diff options
403 files changed, 28886 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..cd89955 --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +BasedOnStyle: llvm diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82848fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +*.a +*.o +*.txt +*.log +*.bin +*.iso +*.img +*.tar.xz +*.tar.xz.sig +.cache/ +toolchain/bin/ +toolchain/binutils-*/ +toolchain/gcc-*/ +toolchain/build-* +userland/* +userland/terminal/term +!userland/libc/* +!userland/minibox/* +!userland/windowserver/* +!userland/terminal/* +!userland/libgui/* +!userland/snake/* +!userland/ante/* +!userland/ante/* +ext2.img +mount @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state 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) <year> <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 3 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, see <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU 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 Lesser General +Public License instead of this License. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. @@ -0,0 +1,14 @@ +Copyright (C) 2022 - 2023 Anton Kling <anton@kling.gg> + +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 3 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, see <https://www.gnu.org/licenses/>. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..74f52b4 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +CC="./sysroot/bin/i686-sb-gcc" +AS="./sysroot/bin/i686-sb-as" +OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o +CFLAGS = -O2 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I. +INCLUDE=-I./includes/ -I./libc/include/ + +all: myos.iso + +%.o: %.c + $(CC) $(INCLUDE) -c -o $@ $< $(CFLAGS) + +%.o: %.s + $(AS) $< -o $@ + +myos.bin: $(OBJ) + $(CC) $(INCLUDE) -shared -T linker.ld -o myos.bin -ffreestanding -nostdlib $(CFLAGS) $^ -lgcc + +debug: + qemu-system-i386 -no-reboot -no-shutdown -serial file:./serial.log -hda ext2.img -m 1G -cdrom myos.iso -s -S & + gdb -x .gdbinit + +nk: + qemu-system-i386 -d int -no-reboot -no-shutdown -serial file:./serial.log -hda ext2.img -m 1G -cdrom myos.iso -s + +run: + qemu-system-i386 -enable-kvm -d int -no-reboot -no-shutdown -chardev stdio,id=char0,logfile=serial.log,signal=off -serial chardev:char0 -hda ext2.img -m 1G -cdrom myos.iso -s + +myos.iso: myos.bin + cp myos.bin isodir/boot + grub-mkrescue -o myos.iso isodir + +clean: + rm myos.bin myos.iso $(OBJ) diff --git a/README.md b/README.md new file mode 100644 index 0000000..836a31d --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# sbOS + +A mostly from scratch, UNIX like x86 hobbyist operaing system. Kernel, +libc and the rest of the userland are written from scratch. It only +requires a bootloader that supports the first version of multiboot(such +as GRUB). + +## Features + +* Paging +* Interrupts +* Process scheduling +* VBE graphics +* PS2 Mouse/Keyboard +* VFS +* ext2 filesystem +* DevFS +* UNIX sockets +* libc +* Window Manager +* Terminal Emulator +* Very basic shell +* Shell utilities(cat, yes, echo etc) + +and some other stuff. + +## How do I run it? + +You shouldn't, it is very incomplete and does not have much intreasting +sutff in the userland yet. Setup is currently also sligthly painful if +you don't know what you are doing. + +## Why? + +fun diff --git a/arch/i386/boot.s b/arch/i386/boot.s new file mode 100644 index 0000000..61bbfbb --- /dev/null +++ b/arch/i386/boot.s @@ -0,0 +1,128 @@ +.set ALIGN, 1<<0 +.set MEMINFO, 1<<1 +.set VIDEO_MODE, 1<<2 +.set FLAGS, VIDEO_MODE|ALIGN | MEMINFO +.set MAGIC, 0x1BADB002 +.set CHECKSUM, -(MAGIC + FLAGS) + +#.section .multiboot +.align 16, 0 +.section .multiboot.data, "aw" + .align 4 + .long MAGIC + .long FLAGS + .long CHECKSUM + # unused(padding) + .long 0,0,0,0,0 + # Video mode + .long 0 # Linear graphics + .long 0 # Preferred width + .long 0 # Preferred height + .long 32 # Preferred pixel depth + +# Allocate the initial stack. +.section .bootstrap_stack, "aw", @nobits +stack_bottom: +.skip 16384 # 16 KiB +stack_top: + +.global boot_page_directory +.global boot_page_table1 +.section .bss, "aw", @nobits + .align 4096 +boot_page_directory: + .skip 4096 +boot_page_table1: + .skip 4096 + +.section .multiboot.text, "a" +.global _start +.extern _kernel_end +.type _start, @function +# Kernel entry +_start: + # edi contains the buffer we wish to modify + movl $(boot_page_table1 - 0xC0000000), %edi + + # for loop + movl $0, %esi + movl $1024, %ecx +1: + # esi = address + # If we are in kernel range jump to "label 2" + cmpl $_kernel_start, %esi + jl 2f + + # If we are past the kernel jump to the final stage + # "label 3" + cmpl $(_kernel_end - 0xC0000000), %esi + jge 3f + +2: + # Add permission to the pages + movl %esi, %edx + orl $0x003, %edx + movl %edx, (%edi) + + # Size of page is 4096 bytes. + addl $4096, %esi + # Size of entries in boot_page_table1 is 4 bytes. + addl $4, %edi + # Loop to the next entry if we haven't finished. + loop 1b + +3: + # Map the page table to both virtual addresses 0x00000000 and 0xC0000000. + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4 + + # Set cr3 to the address of the boot_page_directory. + movl $(boot_page_directory - 0xC0000000), %ecx + movl %ecx, %cr3 + + # Enable paging + movl %cr0, %ecx + orl $0x80000000, %ecx + movl %ecx, %cr0 + + # Jump to higher half with an absolute jump. + lea 4f, %ecx + jmp *%ecx + +.size _start, . - _start + +.section .text + +4: + # At this point, paging is fully set up and enabled. + + # Unmap the identity mapping as it is now unnecessary. + movl $0, boot_page_directory + 0 + + # Reload crc3 to force a TLB flush so the changes to take effect. + movl %cr3, %ecx + movl %ecx, %cr3 + + # Set up the stack. + mov $stack_top, %esp + + # Reset EFLAGS. + pushl $0 + popf + + pushl %esp + + /* Push the pointer to the Multiboot information structure. */ + pushl %ebx + /* Push the magic value. */ + pushl %eax + + mov $_kernel_end, %eax + pushl %eax + # Enter the high-level kernel. + call kernel_main + + # Infinite loop if the system has nothing more to do. + cli +1: hlt + jmp 1b diff --git a/arch/i386/mmu.c b/arch/i386/mmu.c new file mode 100644 index 0000000..6fff8f2 --- /dev/null +++ b/arch/i386/mmu.c @@ -0,0 +1,565 @@ +#include <assert.h> +#include <ksbrk.h> +#include <log.h> +#include <mmu.h> + +#define INDEX_FROM_BIT(a) (a / (32)) +#define OFFSET_FROM_BIT(a) (a % (32)) +#define PAGE_SIZE ((uintptr_t)0x1000) + +#define PAGE_ALLOCATE 1 +#define PAGE_NO_ALLOCATE 0 + +PageDirectory *kernel_directory; +PageDirectory real_kernel_directory; +PageDirectory *active_directory = 0; + +#define END_OF_MEMORY 0x8000000 * 15 +const uint32_t num_of_frames = END_OF_MEMORY / PAGE_SIZE; +uint32_t frames[END_OF_MEMORY / PAGE_SIZE] = {0}; +uint32_t num_allocated_frames = 0; + +#define KERNEL_START 0xc0000000 +extern uintptr_t data_end; + +void write_to_frame(uint32_t frame_address, uint8_t on); + +void *ksbrk(size_t s) { + uintptr_t rc = (uintptr_t)align_page((void *)data_end); + data_end += s; + data_end = (uintptr_t)align_page((void *)data_end); + + if (!get_active_pagedirectory()) { + // If there is no active pagedirectory we + // just assume that the memory is + // already mapped. + return (void *)rc; + } + // Determine whether we are approaching a unallocated table + int table_index = 1 + (rc / (1024 * 0x1000)); + if (!active_directory->tables[table_index]) { + uint32_t physical; + active_directory->tables[table_index] = (PageTable *)0xDEADBEEF; + active_directory->tables[table_index] = + (PageTable *)ksbrk_physical(sizeof(PageTable), (void **)&physical); + memset(active_directory->tables[table_index], 0, sizeof(PageTable)); + active_directory->physical_tables[table_index] = (uint32_t)physical | 0x3; + + kernel_directory->tables[table_index] = + active_directory->tables[table_index]; + kernel_directory->physical_tables[table_index] = + active_directory->physical_tables[table_index]; + return ksbrk(s); + } + mmu_allocate_shared_kernel_region((void *)rc, (data_end - (uintptr_t)rc)); + assert(((uintptr_t)rc % PAGE_SIZE) == 0); + memset((void *)rc, 0x00, s); + + return (void *)rc; +} + +void *ksbrk_physical(size_t s, void **physical) { + void *r = ksbrk(s); + if (physical) { + *physical = (void *)virtual_to_physical(r, 0); + } + return r; +} + +uint32_t mmu_get_number_of_allocated_frames(void) { + return num_allocated_frames; +} + +Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, + int set_user) { + uintptr_t address = (uintptr_t)ptr; + if (!directory) + directory = get_active_pagedirectory(); + address /= 0x1000; + + uint32_t table_index = address / 1024; + if (!directory->tables[table_index]) { + if (!create_new_page) + return 0; + + uint32_t physical; + directory->tables[table_index] = + (PageTable *)ksbrk_physical(sizeof(PageTable), (void **)&physical); + memset(directory->tables[table_index], 0, sizeof(PageTable)); + directory->physical_tables[table_index] = + (uint32_t)physical | ((set_user) ? 0x7 : 0x3); + + if (!set_user) { + kernel_directory->tables[table_index] = directory->tables[table_index]; + kernel_directory->physical_tables[table_index] = + directory->physical_tables[table_index]; + } + } + Page *p = &directory->tables[table_index]->pages[address % 1024]; + if (create_new_page) { + p->present = 0; + } + return &directory->tables[table_index]->pages[address % 1024]; +} + +void mmu_free_pages(void *a, uint32_t n) { + for (; n > 0; n--) { + Page *p = get_page(a, NULL, PAGE_NO_ALLOCATE, 0); + p->present = 0; + write_to_frame(p->frame * 0x1000, 0); + a += 0x1000; + } +} + +void *next_page(void *ptr) { + uintptr_t a = (uintptr_t)ptr; + return (void *)(a + (PAGE_SIZE - ((uint32_t)a & (PAGE_SIZE - 1)))); +} + +void *align_page(void *a) { + if ((uintptr_t)a & (PAGE_SIZE - 1)) + return next_page(a); + + return a; +} + +void flush_tlb(void) { + asm volatile("\ + mov %cr3, %eax;\ + mov %eax, %cr3"); +} + +uint32_t first_free_frame(void) { + asm("cli"); + for (uint32_t i = 1; i < INDEX_FROM_BIT(num_of_frames); i++) { + if (frames[i] == 0xFFFFFFFF) + continue; + + for (uint32_t c = 0; c < 32; c++) + if (!(frames[i] & ((uint32_t)1 << c))) + return i * 32 + c; + } + + kprintf("ERROR Num frames: %x\n", mmu_get_number_of_allocated_frames()); + klog("No free frames, uh oh.", LOG_ERROR); + assert(0); + return 0; +} + +void write_to_frame(uint32_t frame_address, uint8_t on) { + uint32_t frame = frame_address / 0x1000; + assert(INDEX_FROM_BIT(frame) < sizeof(frames) / sizeof(frames[0])); + if (on) { + num_allocated_frames++; + frames[INDEX_FROM_BIT(frame)] |= ((uint32_t)0x1 << OFFSET_FROM_BIT(frame)); + return; + } + num_allocated_frames--; + frames[INDEX_FROM_BIT(frame)] &= ~((uint32_t)0x1 << OFFSET_FROM_BIT(frame)); +} + +PageDirectory *get_active_pagedirectory(void) { return active_directory; } + +PageTable *clone_table(uint32_t src_index, PageDirectory *src_directory, + uint32_t *physical_address) { + PageTable *new_table = + ksbrk_physical(sizeof(PageTable), (void **)physical_address); + PageTable *src = src_directory->tables[src_index]; + + // Copy all the pages + for (uint16_t i = 0; i < 1024; i++) { + if (!src->pages[i].present) { + new_table->pages[i].present = 0; + continue; + } + uint32_t frame_address = first_free_frame(); + write_to_frame(frame_address * 0x1000, 1); + new_table->pages[i].frame = frame_address; + + new_table->pages[i].present |= src->pages[i].present; + new_table->pages[i].rw |= src->pages[i].rw; + new_table->pages[i].user |= src->pages[i].user; + new_table->pages[i].accessed |= src->pages[i].accessed; + new_table->pages[i].dirty |= src->pages[i].dirty; + } + + // Now copy all of the data to the new table. This is done by creating a + // virutal pointer to this newly created tables physical frame so we can + // copy data to it. + for (uint32_t i = 0; i < 1024; i++) { + // Find a unused table + if (src_directory->tables[i]) + continue; + + // Link the table to the new table temporarily + src_directory->tables[i] = new_table; + src_directory->physical_tables[i] = *physical_address | 0x7; + PageDirectory *tmp = get_active_pagedirectory(); + switch_page_directory(src_directory); + + // For each page in the table copy all the data over. + for (uint32_t c = 0; c < 1024; c++) { + // Only copy pages that are used. + if (!src->pages[c].frame || !src->pages[c].present) + continue; + + uint32_t table_data_pointer = i << 22 | c << 12; + uint32_t src_data_pointer = src_index << 22 | c << 12; + memcpy((void *)table_data_pointer, (void *)src_data_pointer, 0x1000); + } + src_directory->tables[i] = 0; + src_directory->physical_tables[i] = 0; + switch_page_directory(tmp); + return new_table; + } + ASSERT_NOT_REACHED; + return 0; +} + +PageTable *copy_table(PageTable *src, uint32_t *physical_address) { + PageTable *new_table = + ksbrk_physical(sizeof(PageTable), (void **)physical_address); + + // copy all the pages + for (uint16_t i = 0; i < 1024; i++) { + if (!src->pages[i].present) { + new_table->pages[i].present = 0; + continue; + } + new_table->pages[i].frame = src->pages[i].frame; + new_table->pages[i].present = src->pages[i].present; + new_table->pages[i].rw = src->pages[i].rw; + new_table->pages[i].user = src->pages[i].user; + new_table->pages[i].accessed = src->pages[i].accessed; + new_table->pages[i].dirty = src->pages[i].dirty; + } + return new_table; +} + +PageDirectory *clone_directory(PageDirectory *original) { + if (!original) + original = get_active_pagedirectory(); + + uint32_t physical_address; + PageDirectory *new_directory = + ksbrk_physical(sizeof(PageDirectory), (void **)&physical_address); + uint32_t offset = + (uint32_t)new_directory->physical_tables - (uint32_t)new_directory; + new_directory->physical_address = physical_address + offset; + + for (int i = 0; i < 1024; i++) { + if (!original->tables[i]) { + new_directory->tables[i] = NULL; + new_directory->physical_tables[i] = (uint32_t)NULL; + continue; + } + + // Make sure to copy instead of cloning the stack. + if (i >= 635 && i <= 641) { + uint32_t physical; + new_directory->tables[i] = clone_table(i, original, &physical); + new_directory->physical_tables[i] = + physical | (original->physical_tables[i] & 0xFFF); + continue; + } + + // if (original->tables[i] == kernel_directory->tables[i]) { + if (i > 641) { + new_directory->tables[i] = kernel_directory->tables[i]; + new_directory->physical_tables[i] = kernel_directory->physical_tables[i]; + continue; + } + + uint32_t physical; + new_directory->tables[i] = clone_table(i, original, &physical); + new_directory->physical_tables[i] = + physical | (original->physical_tables[i] & 0xFFF); + } + + return new_directory; +} + +void mmu_allocate_shared_kernel_region(void *rc, size_t n) { + size_t num_pages = n / PAGE_SIZE; + for (size_t i = 0; i <= num_pages; i++) { + Page *p = get_page((void *)(rc + i * 0x1000), NULL, PAGE_NO_ALLOCATE, 0); + if (!p) { + kprintf("don't have: %x\n", rc + i * 0x1000); + p = get_page((void *)(rc + i * 0x1000), NULL, PAGE_ALLOCATE, 0); + } + if (!p->present || !p->frame) + allocate_frame(p, 0, 1); + } +} + +void mmu_remove_virtual_physical_address_mapping(void *ptr, size_t length) { + size_t num_pages = (uintptr_t)align_page((void *)length) / PAGE_SIZE; + for (size_t i = 0; i < num_pages; i++) { + Page *p = get_page(ptr + (i * PAGE_SIZE), NULL, PAGE_NO_ALLOCATE, 0); + if (!p) + return; + p->frame = 0; + p->present = 0; + } +} + +void *mmu_find_unallocated_virtual_range(void *addr, size_t length) { + addr = align_page(addr); + // Check if the pages already exist + for (size_t i = 0; i < length; i += 0x1000) { + if (get_page(addr + i, NULL, PAGE_NO_ALLOCATE, 0)) { + // Page already exists + return mmu_find_unallocated_virtual_range(addr + 0x1000, length); + } + } + return addr; +} + +int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags) { + size_t num_pages = n / 0x1000; + for (size_t i = 0; i <= num_pages; i++) { + Page *p = get_page((void *)(ptr + i * 0x1000), get_active_pagedirectory(), + PAGE_ALLOCATE, 1); + assert(p); + int rw = (flags & MMU_FLAG_RW); + int kernel = (flags & MMU_FLAG_KERNEL); + if (!allocate_frame(p, rw, kernel)) { + klog("MMU: Frame allocation failed", LOG_WARN); + return 0; + } + } + return 1; +} + +void *mmu_map_frames(void *const ptr, size_t s) { + void *const r = mmu_find_unallocated_virtual_range((void *)0xEF000000, s); + kprintf("r: %x\n", r); + size_t num_pages = s / 0x1000; + for (size_t i = 0; i <= num_pages; i++) { + Page *p = get_page((void *)(r + i * 0x1000), NULL, PAGE_ALLOCATE, 1); + assert(p); + int rw = 1; + int is_kernel = 1; + p->present = 1; + p->rw = rw; + p->user = !is_kernel; + p->frame = (uintptr_t)(ptr + i * 0x1000) / 0x1000; + write_to_frame((uintptr_t)ptr + i * 0x1000, 1); + } + flush_tlb(); + return r; +} + +void *allocate_frame(Page *page, int rw, int is_kernel) { + if (page->present) { + dump_backtrace(5); + klog("Page is already set", 1); + for (;;) + ; + return 0; + } + uint32_t frame_address = first_free_frame(); + assert(frame_address < sizeof(frames) / sizeof(frames[0])); + write_to_frame(frame_address * 0x1000, 1); + + page->present = 1; + page->rw = rw; + page->user = !is_kernel; + page->frame = frame_address; + return (void *)(frame_address * 0x1000); +} + +void mmu_free_address_range(void *ptr, size_t length) { + size_t num_pages = (size_t)align_page((void *)length) / PAGE_SIZE; + for (size_t i = 0; i < num_pages; i++, ptr += PAGE_SIZE) { + Page *page = get_page(ptr, NULL, PAGE_NO_ALLOCATE, 0); + if (!page) + continue; + if (!page->present) + continue; + if (!page->frame) + continue; + // Sanity check that none of the frames are invalid + assert(page->frame < sizeof(frames) / sizeof(frames[0])); + write_to_frame(((uint32_t)page->frame) * 0x1000, 0); + page->present = 0; + page->rw = 0; + page->user = 0; + page->frame = 0; + } +} + +void mmu_map_directories(void *dst, PageDirectory *d, void *src, + PageDirectory *s, size_t length) { + d = (!d) ? get_active_pagedirectory() : d; + s = (!s) ? get_active_pagedirectory() : s; + size_t num_pages = (uint32_t)align_page((void *)length) / 0x1000; + for (size_t i = 0; i < num_pages; i++, dst += 0x1000, src += 0x1000) { + Page *p = get_page(dst, d, PAGE_ALLOCATE, 1); + p->present = 1; + p->rw = 1; + p->user = 1; + void *physical = virtual_to_physical(src, s); + p->frame = (uint32_t)physical / PAGE_SIZE; + } + flush_tlb(); +} + +void mmu_map_physical(void *dst, PageDirectory *d, void *physical, + size_t length) { + d = (!d) ? get_active_pagedirectory() : d; + size_t num_pages = (uint32_t)align_page((void *)length) / 0x1000; + for (size_t i = 0; i < num_pages; i++, dst += 0x1000, physical += 0x1000) { + Page *p = get_page(dst, d, PAGE_ALLOCATE, 1); + p->present = 1; + p->rw = 1; + p->user = 1; + p->frame = (uintptr_t)physical / PAGE_SIZE; + write_to_frame((uintptr_t)physical, 1); + } + flush_tlb(); +} + +void *virtual_to_physical(void *address, PageDirectory *directory) { + if (0 == directory) + directory = get_active_pagedirectory(); + return (void *)((get_page((void *)address, directory, PAGE_NO_ALLOCATE, 0) + ->frame * + 0x1000) + + (((uintptr_t)address) & 0xFFF)); +} + +extern uint32_t inital_esp; +void __attribute__((optimize("O0"))) +move_stack(uint32_t new_stack_address, uint32_t size) { + mmu_allocate_region((void *)(new_stack_address - size), size, + MMU_FLAG_KERNEL); + + uint32_t old_stack_pointer, old_base_pointer; + + register uint32_t eax asm("eax"); + asm volatile("mov %esp, %eax"); + old_stack_pointer = eax; + asm volatile("mov %ebp, %eax"); + old_base_pointer = eax; + + uint32_t new_stack_pointer = + old_stack_pointer + ((uint32_t)new_stack_address - inital_esp); + uint32_t new_base_pointer = + old_base_pointer + ((uint32_t)new_stack_address - inital_esp); + + // Copy the stack + memcpy((void *)new_stack_pointer, (void *)old_stack_pointer, + inital_esp - old_stack_pointer); + for (uint32_t i = (uint32_t)new_stack_address; i > new_stack_address - size; + i -= 4) { + uint32_t tmp = *(uint32_t *)i; + if (old_stack_pointer < tmp && tmp < inital_esp) { + tmp = tmp + (new_stack_address - inital_esp); + uint32_t *tmp2 = (uint32_t *)i; + *tmp2 = tmp; + } + } + + inital_esp = new_stack_pointer; + // Actually change the stack + eax = new_stack_pointer; + asm volatile("mov %eax, %esp"); + eax = new_base_pointer; + asm volatile("mov %eax, %ebp"); +} + +// C strings have a unknown length so it does not makes sense to check +// for a size on the pointer. Instead we check whether the page it +// resides in is accessible to the user. +void *is_valid_user_c_string(const char *ptr, size_t *size) { + void *r = (void *)ptr; + size_t s = 0; + for (;;) { + void *page = (void *)((uintptr_t)ptr & (uintptr_t)(~(PAGE_SIZE - 1))); + if (!is_valid_userpointer(page, PAGE_SIZE)) + return NULL; + for (; (uintptr_t)ptr & (PAGE_SIZE - 1); ptr++, s++) + if (!*ptr) { + if (size) + *size = s; + return r; + } + } +} + +void *is_valid_userpointer(const void *ptr, size_t s) { + uintptr_t t = (uintptr_t)ptr; + size_t num_pages = (uintptr_t)align_page((void *)s) / 0x1000; + for (size_t i = 0; i < num_pages; i++, t += 0x1000) { + Page *page = get_page((void *)t, NULL, PAGE_NO_ALLOCATE, 0); + if (!page) + return NULL; + if (!page->present) + return NULL; + if (!page->user) + return NULL; + } + return (void *)ptr; +} + +void switch_page_directory(PageDirectory *directory) { + active_directory = directory; + asm("mov %0, %%cr3" ::"r"(directory->physical_address)); +} + +void enable_paging(void) { + asm("mov %cr0, %eax\n" + "or 0b10000000000000000000000000000000, %eax\n" + "mov %eax, %cr0\n"); +} + +extern uint32_t boot_page_directory; +extern uint32_t boot_page_table1; + +void paging_init(void) { + uint32_t *cr3; + asm volatile("mov %%cr3, %0" : "=r"(cr3)); + uint32_t *virtual = (uint32_t *)((uint32_t)cr3 + 0xC0000000); + + kernel_directory = &real_kernel_directory; + kernel_directory->physical_address = (uint32_t)cr3; + for (uint32_t i = 0; i < 1024; i++) { + kernel_directory->physical_tables[i] = virtual[i]; + + if (!kernel_directory->physical_tables[i]) { + kernel_directory->tables[i] = NULL; + continue; + } + + kernel_directory->tables[i] = + (PageTable *)(0xC0000000 + (virtual[i] & ~(0xFFF))); + + // Loop through the pages in the table + PageTable *table = kernel_directory->tables[i]; + for (size_t j = 0; j < 1024; j++) { + if (!table->pages[j].present) + continue; + // Add the frame to our bitmap to ensure it does not get used by + // another newly created page. + write_to_frame(table->pages[j].frame * 0x1000, 1); + } + } + + switch_page_directory(kernel_directory); + kernel_directory = clone_directory(kernel_directory); + + // Make null dereferences crash. + switch_page_directory(kernel_directory); + get_page(NULL, kernel_directory, PAGE_ALLOCATE, 0)->present = 0; + switch_page_directory(clone_directory(kernel_directory)); + // FIXME: Really hacky solution. Since page table creation needs to + // allocate memory but memory allocation requires page table creation + // they depend on eachother. The bad/current solution is just to + // allocate a bunch of tables so the memory allocator has enough. + for (uintptr_t i = 0; i < 140; i++) + allocate_frame( + get_page((void *)((0x302 + i) * 0x1000 * 1024), NULL, PAGE_ALLOCATE, 0), + 1, 1); + move_stack(0xA0000000, 0xC00000); +} diff --git a/cpu/gdt.c b/cpu/gdt.c new file mode 100644 index 0000000..28853cf --- /dev/null +++ b/cpu/gdt.c @@ -0,0 +1,72 @@ +#include "gdt.h" + +extern void flush_tss(void); +extern void load_gdt(void *); + +typedef struct tss_entry_struct tss_entry_t; + +tss_entry_t tss_entry; + +typedef union { + struct GDT_Entry s; + uint64_t raw; +} GDT_Entry; + +GDT_Entry gdt_entries[6] = {0}; +GDT_Pointer gdtr; + +extern uint32_t inital_esp; +void write_tss(struct GDT_Entry *gdt_entry) { + uint32_t base = (uint32_t)&tss_entry; + uint32_t limit = sizeof(tss_entry); + + gdt_entry->limit_low = limit; + gdt_entry->base_low = base; + gdt_entry->accessed = 1; + gdt_entry->read_write = 0; + gdt_entry->conforming_expand_down = 0; + gdt_entry->code = 1; + gdt_entry->code_data_segment = 0; + gdt_entry->DPL = 0; + gdt_entry->present = 1; + gdt_entry->limit_high = limit >> 16; + gdt_entry->available = 0; + gdt_entry->long_mode = 0; + gdt_entry->big = 0; + gdt_entry->gran = 0; + gdt_entry->base_high = (base & ((uint32_t)0xff << 24)) >> 24; + + memset(&tss_entry, 0, sizeof tss_entry); + tss_entry.ss0 = GDT_KERNEL_DATA_SEGMENT * GDT_ENTRY_SIZE; + register uint32_t esp asm("esp"); + tss_entry.esp0 = esp; +} + +void gdt_init() { + gdt_entries[GDT_NULL_SEGMENT].raw = 0x0; + gdt_entries[GDT_KERNEL_CODE_SEGMENT].raw = + 0xCF9A000000FFFF; // Kernel code segment + gdt_entries[GDT_KERNEL_DATA_SEGMENT].raw = + 0xCF92000000FFFF; // Kernel data segment + + // Usermode code segment + memcpy(&gdt_entries[GDT_USERMODE_CODE_SEGMENT], + &gdt_entries[GDT_KERNEL_CODE_SEGMENT], GDT_ENTRY_SIZE); + + // Usermode data segment + memcpy(&gdt_entries[GDT_USERMODE_DATA_SEGMENT], + &gdt_entries[GDT_KERNEL_DATA_SEGMENT], GDT_ENTRY_SIZE); + + // Set DPL to 3 to indicate that the segment is in ring 3 + gdt_entries[GDT_USERMODE_CODE_SEGMENT].s.DPL = 3; + gdt_entries[GDT_USERMODE_DATA_SEGMENT].s.DPL = 3; + + write_tss((struct GDT_Entry *)&gdt_entries[GDT_TSS_SEGMENT]); + + gdtr.offset = (uint32_t)&gdt_entries; + gdtr.size = sizeof(gdt_entries) - 1; + + asm("cli"); + load_gdt(&gdtr); + flush_tss(); +} diff --git a/cpu/gdt.h b/cpu/gdt.h new file mode 100644 index 0000000..a490dea --- /dev/null +++ b/cpu/gdt.h @@ -0,0 +1,76 @@ +#ifndef GDT_H +#define GDT_H +#include <stdint.h> +#include <string.h> + +#define GDT_ENTRY_SIZE 0x8 +#define GDT_NULL_SEGMENT 0x0 +#define GDT_KERNEL_CODE_SEGMENT 0x1 +#define GDT_KERNEL_DATA_SEGMENT 0x2 +#define GDT_USERMODE_CODE_SEGMENT 0x3 +#define GDT_USERMODE_DATA_SEGMENT 0x4 +#define GDT_TSS_SEGMENT 0x5 + +struct GDT_Entry +{ + uint16_t limit_low; + uint32_t base_low : 24; + uint32_t accessed : 1; + uint32_t read_write : 1; // readable for code, writable for data + uint32_t conforming_expand_down : 1; // conforming for code, expand down for data + uint32_t code : 1; // 1 for code, 0 for data + uint32_t code_data_segment : 1; // should be 1 for everything but TSS and LDT + uint32_t DPL : 2; // privilege level + uint32_t present : 1; + uint32_t limit_high : 4; + uint32_t available : 1; // only used in software; has no effect on hardware + uint32_t long_mode : 1; + uint32_t big : 1; // 32-bit opcodes for code, uint32_t stack for data + uint32_t gran : 1; // 1 to use 4k page addressing, 0 for byte addressing + uint8_t base_high; +}__attribute__((packed)); + +typedef struct GDT_Pointer +{ + uint16_t size; + uint32_t offset; +}__attribute__((packed)) GDT_Pointer; + +struct tss_entry_struct +{ + uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list. + uint32_t esp0; // The stack pointer to load when changing to kernel mode. + uint32_t ss0; // The stack segment to load when changing to kernel mode. + // Everything below here is unused. + uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2. + uint32_t ss1; + uint32_t esp2; + uint32_t ss2; + uint32_t cr3; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t es; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t fs; + uint32_t gs; + uint32_t ldt; + uint16_t trap; + uint16_t iomap_base; +} __attribute__((packed)); + +void gdt_init(); + +uint8_t gen_access_byte(uint8_t priv, uint8_t s, uint8_t ex, uint8_t dc, uint8_t rw); +uint64_t gen_gdt_entry(uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flag); +uint8_t gen_flag(uint8_t gr, uint8_t sz); +#endif diff --git a/cpu/idt.c b/cpu/idt.c new file mode 100644 index 0000000..832162c --- /dev/null +++ b/cpu/idt.c @@ -0,0 +1,265 @@ +#include <cpu/idt.h> +#include <sched/scheduler.h> +#include <stdio.h> + +#define MASTER_PIC_COMMAND_PORT 0x20 +#define MASTER_PIC_DATA_PORT 0x21 +#define SLAVE_PIC_COMMAND_PORT 0xA0 +#define SLAVE_PIC_DATA_PORT 0xA1 +#define KEYBOARD_DATA_PORT 0x60 +#define KEYBOARD_STATUS_PORT 0x64 +#define KERNEL_CODE_SEGMENT_OFFSET GDT_ENTRY_SIZE *GDT_KERNEL_CODE_SEGMENT + +#define IDT_MAX_ENTRY 256 + +struct IDT_Descriptor { + uint16_t low_offset; + uint16_t code_segment_selector; + uint8_t zero; // Always should be zero + uint8_t type_attribute; + uint16_t high_offset; +} __attribute__((packed)) __attribute__((aligned(4))); + +struct IDT_Pointer { + uint16_t size; + struct IDT_Descriptor **interrupt_table; +} __attribute__((packed)); + +struct IDT_Descriptor IDT_Entry[IDT_MAX_ENTRY]; +struct IDT_Pointer idtr; + +extern void load_idtr(void *idtr); + +void format_descriptor(uint32_t offset, uint16_t code_segment, + uint8_t type_attribute, + struct IDT_Descriptor *descriptor) { + descriptor->low_offset = offset & 0xFFFF; + descriptor->high_offset = offset >> 16; + descriptor->type_attribute = type_attribute; + descriptor->code_segment_selector = code_segment; + descriptor->zero = 0; +} + +void install_handler(void (*handler_function)(), uint16_t type_attribute, + uint8_t entry) { + format_descriptor((uint32_t)handler_function, KERNEL_CODE_SEGMENT_OFFSET, + type_attribute, &IDT_Entry[entry]); +} + +__attribute__((no_caller_saved_registers)) void EOI(uint8_t irq) { + if (irq > 7) + outb(SLAVE_PIC_COMMAND_PORT, 0x20); + + outb(MASTER_PIC_COMMAND_PORT, 0x20); +} + +__attribute__((interrupt)) void +kernel_general_protection_fault(kernel_registers_t *regs) { + asm("cli"); + klog("General Protetion Fault", 0x1); + kprintf(" Error Code: %x\n", regs->error_code); + kprintf("Instruction Pointer: %x\n", regs->eip); + dump_backtrace(12); + for (;;) + ; + EOI(0xD - 8); +} + +__attribute__((interrupt)) void general_protection_fault(registers_t *regs) { + kprintf("\n"); + klog("KERNEL General Protetion Fault", 0x1); + kprintf(" Error Code: %x\n", regs->error_code); +#define EXTERNAL_TO_PROCESSOR (1 << 0) + +#define WAS(_b) if (regs->error_code & (_b)) + if (0 == regs->error_code) { + kprintf("This exception is not segment related."); + } else { + WAS(EXTERNAL_TO_PROCESSOR) { + kprintf("Exception originated externally to the processor."); + } + kprintf("Index references: "); + switch ((regs->error_code >> 1) & 0x3) { + case 0: + kprintf("GDT"); + break; + case 3: + case 1: + kprintf("IDT"); + break; + case 2: + kprintf("LDT"); + break; + } + kprintf("\n"); + kprintf("Segmenet index: %x\n", regs->error_code >> 15); + } + /* kprintf(" Page protection violation: %x\n", regs->error_code & 0x1); + kprintf(" Write access: %x\n", (regs->error_code & (0x1<<1)) >> 1); + kprintf(" No privilege violation: %x\n", (regs->error_code & (0x1<<2)) + >> 2); kprintf(" Instruction fetch: %x\n", (regs->error_code & (0x1<<4)) >> + 4); kprintf(" Shadow stack access: %x\n", (regs->error_code & (0x1<<6)) >> + 6);*/ + kprintf("Instruction Pointer: %x\n", regs->eip); + asm("hlt"); + EOI(0xD - 8); +} + +__attribute__((interrupt)) void double_fault(registers_t *regs) { + (void)regs; + klog("DOUBLE FAULT, THIS IS REALLY BAD", LOG_ERROR); + asm("hlt"); + for (;;) + ; +} +__attribute__((interrupt)) void page_fault(registers_t *regs) { + asm("cli"); + klog("Page Fault", LOG_ERROR); + if (get_current_task()) { + kprintf(" PID: %x\n", get_current_task()->pid); + kprintf(" Name: %s\n", get_current_task()->program_name); + } + kprintf(" Error Code: %x\n", regs->error_code); + kprintf(" Interrupt Number: %x\n", regs->interrupt_number); + kprintf(" Instruction Pointer: %x\n", regs->eip); + dump_backtrace(14); + asm("hlt"); + for (;;) + ; +} + +/* +__attribute__((interrupt)) void page_fault(registers_t *regs) { + asm("cli"); + klog("Page Fault", LOG_ERROR); + if (get_current_task()) { + kprintf(" PID: %x\n", get_current_task()->pid); + kprintf(" Name: %s\n", get_current_task()->program_name); + } + kprintf(" Error Code: %x\n", regs->error_code); + kprintf(" Interrupt Number: %x\n", regs->interrupt_number); +#define PAGE_PRESENT (1 << 0) +#define WRITE_ATTEMPT (1 << 1) +#define USER_LEVEL (1 << 2) +#define RESERVED_WRITE (1 << 3) +#define INSTRUCTION_FETCH (1 << 4) +#define PROTECTION_KEY_VIOLATION (1 << 5) +#define SHADOW_STACK_ACCESS (1 << 6) + +#define WAS(_b) if (regs->error_code & (_b)) + + WAS(PAGE_PRESENT) { kprintf(" Page was present.\n"); } + else { + kprintf(" Page is not present.\n"); + } + + WAS(WRITE_ATTEMPT) { kprintf(" Write attempt.\n"); } + else { + kprintf(" Read attempt.\n"); + } + + WAS(USER_LEVEL) { + get_current_task()->dead = 1; + kprintf(" Page fault in ring 3.\n"); + } + else { + kprintf(" Page fault in ring 0-2.\n"); + } + + WAS(INSTRUCTION_FETCH) { kprintf(" Attempted instruction fetch.\n"); } + + WAS(SHADOW_STACK_ACCESS) { kprintf(" Attempted shadow stack access.\n"); } + + kprintf(" Instruction Pointer: %x\n", regs->eip); + dump_backtrace(12); + asm("hlt"); + for (;;) + ; + EOI(0xE - 8); +}*/ + +static inline void io_wait(void) { outb(0x80, 0); } + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +void PIC_remap(int offset) { + unsigned char a1, a2; + a1 = inb(MASTER_PIC_DATA_PORT); + a2 = inb(SLAVE_PIC_DATA_PORT); + + // Send ICW1 and tell the PIC that we will issue a ICW4 + // Since there is no ICW1_SINGLE sent to indicate it is cascaded + // it means we will issue a ICW3. + outb(MASTER_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(SLAVE_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4); + io_wait(); + + // As a part of ICW2 this sends the offsets(the position to put IRQ0) of the + // vector tables. + outb(MASTER_PIC_DATA_PORT, offset); + io_wait(); + outb(SLAVE_PIC_DATA_PORT, offset + 0x8); + io_wait(); + + // This tells the master on which lines it is having slaves + outb(MASTER_PIC_DATA_PORT, 4); + io_wait(); + // This tells the slave the cascading identity. + outb(SLAVE_PIC_DATA_PORT, 2); + io_wait(); + + outb(MASTER_PIC_DATA_PORT, ICW4_8086); + io_wait(); + outb(SLAVE_PIC_DATA_PORT, ICW4_8086); + io_wait(); + + outb(MASTER_PIC_DATA_PORT, a1); + outb(SLAVE_PIC_DATA_PORT, a2); +} + +void IRQ_set_mask(unsigned char IRQline) { + uint16_t port; + uint8_t value; + port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT; + if (IRQline >= 8) + IRQline -= 8; + value = inb(port) | (1 << IRQline); + outb(port, value); +} + +void IRQ_clear_mask(unsigned char IRQline) { + uint16_t port; + uint8_t value; + port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT; + if (IRQline >= 8) { + IRQline -= 8; + } + value = inb(port) & ~(1 << IRQline); + outb(port, value); +} + +void idt_init(void) { + install_handler(page_fault, INT_32_TRAP_GATE(0x3), 0xE); + install_handler(double_fault, INT_32_TRAP_GATE(0x0), 0x8); + install_handler(kernel_general_protection_fault, INT_32_TRAP_GATE(0x0), 0xD); + + PIC_remap(0x20); + // IRQ_set_mask(0xc); + IRQ_set_mask(0xe); + IRQ_clear_mask(2); + + idtr.interrupt_table = (struct IDT_Descriptor **)&IDT_Entry; + idtr.size = (sizeof(struct IDT_Descriptor) * IDT_MAX_ENTRY) - 1; + load_idtr(&idtr); +} diff --git a/cpu/idt.h b/cpu/idt.h new file mode 100644 index 0000000..853b1e0 --- /dev/null +++ b/cpu/idt.h @@ -0,0 +1,76 @@ +typedef struct kernel_registers kernel_registers_t; +typedef struct registers registers_t; +#ifndef IDT_H +#define IDT_H +#include <cpu/gdt.h> +#include <cpu/io.h> +#include <log.h> +#include <stdint.h> +#include <stdio.h> + +/* + * the type_attribute in the IDT_Entry struct + * is divded like this + * 7 0 + * +---+---+---+---+---+---+---+---+ + * | P | DPL | S | GateType | + * +---+---+---+---+---+---+---+---+ + * It is 8 bits(1 byte) long + * + * P + * Present bit. Should be zero for unused + * interrupts. + * + * DPL + * Specifices the maximum ring(0 to 3) the + * interrupt can be called from. + * + * S + * Storage segment. This should be set to + * zero for all interrupt and trap gates. + * + * GateType + * Possible IDT gate types: + * 0b0101 0x5 5 80386 32 bit task gate + * 0b0110 0x6 6 80286 16-bit interrupt gate + * 0b0111 0x7 7 80286 16-bit trap gate + * 0b1110 0xE 14 80386 32-bit interrupt gate + * 0b1111 0xF 15 80386 32-bit trap gate + */ + +// This enables the present bit. +#define INT_PRESENT 0x80 /* 0b10000000 */ + +#define INT_32_TASK_GATE(min_privlege) \ + (INT_PRESENT | 0x05 | (min_privlege << 5)) +#define INT_16_INTERRUPT_GATE(min_privlege) \ + (INT_PRESENT | 0x06 | (min_privlege << 5)) +#define INT_16_TRAP_GATE(min_privlege) \ + (INT_PRESENT | 0x07 | (min_privlege << 5)) +#define INT_32_INTERRUPT_GATE(min_privlege) \ + (INT_PRESENT | 0x0E | (min_privlege << 5)) +#define INT_32_TRAP_GATE(min_privlege) \ + (INT_PRESENT | 0x0F | (min_privlege << 5)) + +struct interrupt_frame; + +struct kernel_registers { + // uint32_t ds; + // uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + // uint32_t interrupt_number, error_code; + uint32_t error_code; + uint32_t eip, cs, eflags; +}; + +struct registers { + uint32_t ds; + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; + uint32_t interrupt_number, error_code; + uint32_t eip, cs, eflags, useresp, ss; +}; + +void idt_init(void); +__attribute__((no_caller_saved_registers)) void EOI(unsigned char irq); +void install_handler(void (*handler_function)(), uint16_t type_attribute, + uint8_t entry); +#endif diff --git a/cpu/int_syscall.s b/cpu/int_syscall.s new file mode 100644 index 0000000..8c3c25f --- /dev/null +++ b/cpu/int_syscall.s @@ -0,0 +1,20 @@ +.intel_syntax noprefix +.global int_syscall +.extern syscall_function_handler +int_syscall: + push ebp + push edi + push esi + push edx + push ecx + push ebx + push eax + call syscall_function_handler + add esp, 4 + pop ebx + pop ecx + pop edx + pop esi + pop edi + pop ebp + iretd diff --git a/cpu/io.h b/cpu/io.h new file mode 100644 index 0000000..9c33b66 --- /dev/null +++ b/cpu/io.h @@ -0,0 +1,11 @@ +#include <stdint.h> + +__attribute__((no_caller_saved_registers)) extern void outsw(uint16_t, + uint32_t); +__attribute__((no_caller_saved_registers)) extern void outb(uint16_t, uint16_t); +__attribute__((no_caller_saved_registers)) extern uint16_t inb(uint16_t); +__attribute__((no_caller_saved_registers)) extern void +rep_outsw(uint16_t count, uint16_t port, volatile void *addy); +__attribute__((no_caller_saved_registers)) extern void +rep_insw(uint16_t count, uint16_t port, volatile void *addy); +extern void jump_usermode(void (*address)(), uint32_t stack_pointer); diff --git a/cpu/io.s b/cpu/io.s new file mode 100644 index 0000000..fe370a5 --- /dev/null +++ b/cpu/io.s @@ -0,0 +1,121 @@ +.intel_syntax noprefix +.global outsw +.global outb +.global inb +.global rep_outsw +.global rep_insw +.global flush_tss +.global load_idtr + +# ebx, esi, edi, ebp, and esp; +outsw: + push ebp + mov ebp, esp + push esi + mov dx, [ebp + 4+4] + mov esi, [ebp + 8+4] + outsw + pop esi + mov esp, ebp + pop ebp + ret + +outb: + mov al, [esp + 8] + mov dx, [esp + 4] + out dx, al + ret + +inb: + mov dx, [esp + 4] + in al, dx + ret + +rep_outsw: + push ebp + mov ebp, esp + push edi + mov ecx, [ebp + 4+4] #ECX is counter for OUTSW + mov edx, [ebp + 8+4] #Data port, in and out + mov edi, [ebp + 12+4] #Memory area + rep outsw #in to [RDI] + pop edi + mov esp, ebp + pop ebp + ret + +rep_insw: + push ebp + mov ebp, esp + push edi + mov ecx, [ebp + 4+4] #ECX is counter for INSW + mov edx, [ebp + 8+4] #Data port, in and out + mov edi, [ebp + 12+4] #Memory area + rep insw #in to [RDI] + pop edi + mov esp, ebp + pop ebp + ret + +flush_tss: + mov ax, 40 + ltr ax + ret + +load_idtr: + mov edx, [esp + 4] + lidt [edx] + ret + +test_user_function: + mov eax, 0x00 + int 0x80 + mov ecx, 0x03 + mov ebx, 0x04 + mov eax, 0x02 + int 0x80 + mov ebx, eax + mov eax, 0x01 + int 0x80 +loop: + jmp loop + ret + +.global spin_lock +.global spin_unlock +.extern locked + +spin_lock: + mov eax, 1 + xchg eax, ebx + test eax, eax + jnz spin_lock + ret + +spin_unlock: + xor eax, eax + xchg eax, ebx + ret + + +.global jump_usermode +jump_usermode: + mov ax, (4 * 8) | 3 # user data segment with RPL 3 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax # sysexit sets SS + + # setup wrmsr inputs + xor edx, edx # not necessary; set to 0 + mov eax, 0x100008 # SS=0x10+0x10=0x20, CS=0x8+0x10=0x18 + mov ecx, 0x174 # MSR specifier: IA32_SYSENTER_CS + wrmsr # set sysexit segments + + # setup sysexit inputs + mov edx, [esp + 4] # to be loaded into EIP + mov ecx, [esp + 8] # to be loaded into ESP + mov esp, ecx + mov ebp, ecx + sti + sysexit diff --git a/cpu/reload_gdt.s b/cpu/reload_gdt.s new file mode 100644 index 0000000..3a0119b --- /dev/null +++ b/cpu/reload_gdt.s @@ -0,0 +1,17 @@ +.section .text +.global load_gdt + +load_gdt: + mov 4(%esp), %eax + lgdt (%eax) + + mov $0x10, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + mov %eax, %ss + jmp $0x8, $.long_jump +.long_jump: + ret + diff --git a/cpu/spinlock.c b/cpu/spinlock.c new file mode 100644 index 0000000..3f87423 --- /dev/null +++ b/cpu/spinlock.c @@ -0,0 +1,2 @@ +#include <stdint.h> +uint8_t locked; diff --git a/cpu/spinlock.h b/cpu/spinlock.h new file mode 100644 index 0000000..93290c4 --- /dev/null +++ b/cpu/spinlock.h @@ -0,0 +1,5 @@ +#ifndef SPINLOCK_H +#define SPINLOCK_H +void spin_lock(int *l); +void spin_unlock(int *l); +#endif diff --git a/cpu/syscall.c b/cpu/syscall.c new file mode 100644 index 0000000..19c195f --- /dev/null +++ b/cpu/syscall.c @@ -0,0 +1,174 @@ +// FIXME: Make sure that the args variabel actually points to something +// valid. +#include <assert.h> +#include <cpu/syscall.h> +#include <drivers/pst.h> +#include <errno.h> +#include <fs/tmpfs.h> +#include <fs/vfs.h> +#include <kmalloc.h> +#include <scalls/accept.h> +#include <scalls/bind.h> +#include <scalls/mmap.h> +#include <scalls/msleep.h> +#include <scalls/ppoll.h> +#include <scalls/shm.h> +#include <scalls/socket.h> +#include <scalls/stat.h> +#include <scalls/uptime.h> +#include <stdint.h> +#include <string.h> + +#pragma GCC diagnostic ignored "-Wpedantic" + +int syscall_open(SYS_OPEN_PARAMS *args) { + char file[256]; + strcpy(file, args->file); + // const char *file = copy_and_allocate_user_string(args->file); + int flags = args->flags; + int mode = args->mode; + int rc = vfs_open(file, flags, mode); + // kfree((void *)file); + return rc; +} + +int syscall_exec(SYS_EXEC_PARAMS *args) { + const char *filename = copy_and_allocate_user_string(args->path); + + int argc = 0; + for (; args->argv[argc];) { + argc++; + } + + char **new_argv = kallocarray(argc + 1, sizeof(char *)); + for (int i = 0; i < argc; i++) + new_argv[i] = copy_and_allocate_user_string(args->argv[i]); + + new_argv[argc] = NULL; + + exec(filename, new_argv); + kfree((void *)filename); + for (int i = 0; i < argc; i++) + kfree(new_argv[i]); + kfree(new_argv); + return -1; +} + +int syscall_pipe(int fd[2]) { + pipe(fd); // FIXME: Error checking + return 0; +} + +int syscall_pread(SYS_PREAD_PARAMS *args) { + return vfs_pread(args->fd, args->buf, args->count, args->offset); +} + +int syscall_read(SYS_READ_PARAMS *args) { + if (!get_vfs_fd(args->fd)) + return -EBADF; + int rc = vfs_pread(args->fd, args->buf, args->count, + get_current_task()->file_descriptors[args->fd]->offset); + get_current_task()->file_descriptors[args->fd]->offset += rc; + return rc; +} + +int syscall_pwrite(SYS_PWRITE_PARAMS *args) { + return vfs_pwrite(args->fd, args->buf, args->count, args->offset); +} + +int syscall_write(int fd, const char *buf, size_t count) { + if (!get_vfs_fd(fd)) + return -EBADF; + int rc = vfs_pwrite(fd, (char *)buf, count, + get_current_task()->file_descriptors[fd]->offset); + get_current_task()->file_descriptors[fd]->offset += rc; + return rc; +} + +int syscall_dup2(SYS_DUP2_PARAMS *args) { + return vfs_dup2(args->org_fd, args->new_fd); +} + +void syscall_exit(int status) { + exit(status); + assert(0); +} + +void syscall_wait(int *status) { + asm("cli"); + if (!get_current_task()->child) { + if (status) + *status = -1; + return; + } + if (get_current_task()->child->dead) { + if (status) + *status = get_current_task()->child_rc; + return; + } + get_current_task()->halts[WAIT_CHILD_HALT] = 1; + switch_task(); + if (status) + *status = get_current_task()->child_rc; +} + +int syscall_fork(void) { return fork(); } + +int syscall_getpid(void) { return get_current_task()->pid; } + +void *align_page(void *a); + +int syscall_brk(void *addr) { + void *end = get_current_task()->data_segment_end; + if (!mmu_allocate_region(end, addr - end, MMU_FLAG_RW)) + return -ENOMEM; + get_current_task()->data_segment_end = align_page(addr); + return 0; +} + +void *syscall_sbrk(uintptr_t increment) { + asm("cli"); + void *rc = get_current_task()->data_segment_end; + void *n = + (void *)((uintptr_t)(get_current_task()->data_segment_end) + increment); + int rc2; + if (0 > (rc2 = syscall_brk(n))) + return (void *)rc2; + return rc; +} + +int syscall_close(int fd) { return vfs_close(fd); } + +int syscall_openpty(SYS_OPENPTY_PARAMS *args) { + assert(is_valid_userpointer(args, sizeof(SYS_OPENPTY_PARAMS))); + return openpty(args->amaster, args->aslave, args->name, args->termp, + args->winp); +} + +void (*syscall_functions[])() = { + (void(*))syscall_open, (void(*))syscall_read, + (void(*))syscall_write, (void(*))syscall_pread, + (void(*))syscall_pwrite, (void(*))syscall_fork, + (void(*))syscall_exec, (void(*))syscall_getpid, + (void(*))syscall_exit, (void(*))syscall_wait, + (void(*))syscall_brk, (void(*))syscall_sbrk, + (void(*))syscall_pipe, (void(*))syscall_dup2, + (void(*))syscall_close, (void(*))syscall_openpty, + (void(*))syscall_poll, (void(*))syscall_mmap, + (void(*))syscall_accept, (void(*))syscall_bind, + (void(*))syscall_socket, (void(*))syscall_shm_open, + (void(*))syscall_ftruncate, (void(*))syscall_stat, + (void(*))syscall_msleep, (void(*))syscall_uptime, +}; + +void syscall_function_handler(uint32_t eax, uint32_t arg1, uint32_t arg2, + uint32_t arg3, uint32_t arg4, uint32_t arg5) { + assert(eax < sizeof(syscall_functions) / sizeof(syscall_functions[0])); + syscall_functions[eax](arg1, arg2, arg3, arg4, arg5); +} + +extern void int_syscall(void); + +void syscalls_init(void) { + install_handler(int_syscall, INT_32_INTERRUPT_GATE(0x3), 0x80); +} diff --git a/cpu/syscall.h b/cpu/syscall.h new file mode 100644 index 0000000..51d50f2 --- /dev/null +++ b/cpu/syscall.h @@ -0,0 +1,59 @@ +#include "idt.h" +#include <stddef.h> +#include <stdint.h> + +void syscalls_init(void); + +typedef struct SYS_OPEN_PARAMS { + char *file; + int flags; + int mode; +} __attribute__((packed)) SYS_OPEN_PARAMS; + +typedef struct SYS_PREAD_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PREAD_PARAMS; + +typedef struct SYS_READ_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_READ_PARAMS; + +typedef struct SYS_PWRITE_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PWRITE_PARAMS; + +typedef struct SYS_WRITE_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_WRITE_PARAMS; + +typedef struct SYS_EXEC_PARAMS { + char *path; + char **argv; +} __attribute__((packed)) SYS_EXEC_PARAMS; + +typedef struct SYS_WAIT_PARAMS { + int *status; +} __attribute__((packed)) SYS_WAIT_PARAMS; + +typedef struct SYS_DUP2_PARAMS { + int org_fd; + int new_fd; +} __attribute__((packed)) SYS_DUP2_PARAMS; + +typedef struct SYS_OPENPTY_PARAMS { + int *amaster; + int *aslave; + char *name; + /*const struct termios*/ void *termp; + /*const struct winsize*/ void *winp; +} __attribute__((packed)) SYS_OPENPTY_PARAMS; diff --git a/crypto/ChaCha20/chacha20.c b/crypto/ChaCha20/chacha20.c new file mode 100644 index 0000000..5bf7aa2 --- /dev/null +++ b/crypto/ChaCha20/chacha20.c @@ -0,0 +1,29 @@ +#include "chacha20.h" + +#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define QR(a, b, c, d) \ + (a += b, d ^= a, d = ROTL(d, 16), c += d, b ^= c, b = ROTL(b, 12), \ + a += b, d ^= a, d = ROTL(d, 8), c += d, b ^= c, b = ROTL(b, 7)) +#define ROUNDS 20 + +void chacha_block(uint32_t out[16], uint32_t const in[16]) +{ + int i; + uint32_t x[16]; + + for (i = 0; i < 16; ++i) + x[i] = in[i]; + for (i = 0; i < ROUNDS; i += 2) { + QR(x[0], x[4], x[8], x[12]); + QR(x[1], x[5], x[9], x[13]); + QR(x[2], x[6], x[10], x[14]); + QR(x[3], x[7], x[11], x[15]); + + QR(x[0], x[5], x[10], x[15]); + QR(x[1], x[6], x[11], x[12]); + QR(x[2], x[7], x[8], x[13]); + QR(x[3], x[4], x[9], x[14]); + } + for (i = 0; i < 16; ++i) + out[i] = x[i] + in[i]; +} diff --git a/crypto/ChaCha20/chacha20.h b/crypto/ChaCha20/chacha20.h new file mode 100644 index 0000000..17532f3 --- /dev/null +++ b/crypto/ChaCha20/chacha20.h @@ -0,0 +1,15 @@ +#ifndef CHACHA20_H +#define CHACHA20_H +#include <stdint.h> + +#define KEY 4 +#define KEY_SIZE 8*sizeof(uint32_t) +#define COUNT 12 +#define COUNT_SIZE sizeof(uint32_t) +#define COUNT_MAX (0x100000000-1) // 2^32 - 1 +#define NONCE 13 +#define NONCE_SIZE 2*sizeof(uint32_t) +#define BLOCK_SIZE 16*sizeof(uint32_t) + +void chacha_block(uint32_t out[16], uint32_t const in[16]); +#endif diff --git a/crypto/SHA1 b/crypto/SHA1 new file mode 160000 +Subproject 237ea7023cad8402932dfbde337d69e5f4d515f diff --git a/drivers/ata.c b/drivers/ata.c new file mode 100644 index 0000000..fd9b504 --- /dev/null +++ b/drivers/ata.c @@ -0,0 +1,253 @@ +#include <assert.h> +#include <cpu/io.h> +#include <drivers/ata.h> +#include <drivers/pit.h> + +#define PRIMARY_BUS_BASEPORT 0x1F0 +#define SECONDAY_BUS_BASEPORT 0x170 + +#define PRIMARY_BUS_IRQ 14 +#define SECONDAY_BUS_IRQ 15 + +#define STATUS_PORT 7 +#define COMMAND_PORT 7 +#define DRIVE_SELECT 6 +#define LBAhi 5 +#define LBAmid 4 +#define LBAlo 3 +#define SECTOR_COUNT 2 +#define DATA_PORT 0 + +#define IDENTIFY 0xEC +#define READ_SECTORS 0x20 +#define WRITE_SECTORS 0x30 +#define CACHE_FLUSH 0xE7 + +#define STATUS_BSY ((1 << 7)) +#define STATUS_DF ((1 << 5)) +#define STATUS_DRQ ((1 << 3)) +#define STATUS_ERR ((1 << 0)) + +uint32_t io_base; + +unsigned char read_buffer[SECTOR_SIZE]; + +void select_drive(uint8_t master_slave) { + outb(io_base + DRIVE_SELECT, (master_slave) ? 0xA0 : 0xB0); +} + +int identify(int master_slave) { + select_drive(master_slave); + outb(io_base + SECTOR_COUNT, 0); + outb(io_base + LBAlo, 0); + outb(io_base + LBAmid, 0); + outb(io_base + LBAhi, 0); + outb(io_base + COMMAND_PORT, IDENTIFY); + if (0 == inb(io_base + STATUS_PORT)) + return 0; // Drive does not exist + + for (; 0 != (inb(io_base + STATUS_PORT) & STATUS_BSY);) + ; + + // Because of some ATAPI drives that do not + // follow spec, at this point we need to check + // the LBAmid and LBAhi ports to see if they are + // non-zero. If so, the drive is not ATA, and we + // should stop polling. + if (0 != inb(io_base + LBAmid) || 0 != inb(io_base + LBAhi)) { + klog("Drive is not ATA.", LOG_ERROR); + return -1; + } + + for (uint16_t status;;) { + status = inb(io_base + STATUS_PORT); + + if (1 == (status & STATUS_ERR)) { + klog("Drive ERR set.", LOG_ERROR); + return -2; + } + + if ((status & STATUS_DRQ)) + break; + } + + // The data is ready to read from the Data + // port (0x1F0). Read 256 16-bit values, + // and store them. + // TODO: This returns some intreasting information. + // https://wiki.osdev.org/ATA_PIO_Mode#Interesting_information_returned_by_IDENTIFY + uint16_t array[256]; + rep_insw(1 * SECTOR_SIZE / 16, io_base + DATA_PORT, array); + return 1; +} + +int poll_status(void) { + for (uint16_t status;;) { + // Read the Regular Status port until... + // We read this 15 times to give some + // time for the drive to catch up. + for (int n = 0; n < 15; n++) + status = inb(io_base + STATUS_PORT); + + // ERR or + // DF sets + if ((status & STATUS_ERR) || (status & STATUS_DF)) { + klog("Drive error set.", LOG_ERROR); + return 0; + } + + // BSY clears + // DRQ sets + if (0 == (status & STATUS_BSY) && 0 != (status & STATUS_DRQ)) + break; + } + return 1; +} + +// Instructions from: https://wiki.osdev.org/ATA_PIO_Mode#28_bit_PIO +void __attribute__((optimize("O0"))) +setup_drive_for_command(uint32_t lba, uint32_t sector_count) { + // 1. Send 0xE0 for the "master" or 0xF0 for + // the "slave", ORed with the highest 4 bits + // of the LBA to port 0x1F6 + outb(io_base + DRIVE_SELECT, 0xE0 | (0 << 4) | ((lba >> 24) & 0x0F)); + + // 2. Send a NULL byte to port 0x1F1, if you + // like (it is ignored and wastes + // lots of CPU time) + + // NOP + + // 3. Send the sectorcount to port 0x1F2 + outb(io_base + SECTOR_COUNT, sector_count); + + // 4. Send the low 8 bits of the LBA to port 0x1F3 + outb(io_base + LBAlo, (lba >> 0) & 0xFF); + + // 5. Send the next 8 bits of the LBA to port 0x1F4 + outb(io_base + LBAmid, (lba >> 8) & 0xFF); + + // 6. Send the next 8 bits of the LBA to port 0x1F5 + outb(io_base + LBAhi, (lba >> 16) & 0xFF); +} + +void delayed_rep_outsw(size_t n, uint16_t port, volatile uint8_t *buffer) { + for (volatile size_t i = 0; i < n; i++) { + outsw(port, (uint32_t)buffer); + buffer += 2; + // outsw(port, buffer); + } +} + +void __attribute__((optimize("O0"))) +ata_write_lba28(uint32_t lba, uint32_t sector_count, + volatile const uint8_t *buffer) { + setup_drive_for_command(lba, sector_count); + + outb(io_base + COMMAND_PORT, WRITE_SECTORS); + + for (volatile uint32_t i = 0; i < sector_count; i++) { + if (!poll_status()) { + // FIXME: Fail properly + for (;;) + ; + } + + delayed_rep_outsw(256, io_base + DATA_PORT, + (void *)((uint32_t)buffer + i * 256)); + } + + // Cache flush + outb(io_base + COMMAND_PORT, CACHE_FLUSH); + + // Wait for BSY to clear + for (;;) { + uint16_t status = inb(io_base + STATUS_PORT); + if (!(status & STATUS_BSY)) + break; + } +} + +// Instructions from: https://wiki.osdev.org/ATA_PIO_Mode#28_bit_PIO +void __attribute__((optimize("O0"))) +ata_read_lba28(uint32_t lba, uint32_t sector_count, volatile void *address) { + // Step 1-6 is done in this function. + setup_drive_for_command(lba, sector_count); + + // 7. Send the "READ SECTORS" command to port 0x17F + outb(io_base + COMMAND_PORT, READ_SECTORS); + + // 8. Wait for an IRQ or poll. + + // This step can be found in the for loop + + // 9. Transfer 256 16-bit values, a uint16_t at a time, + // into your buffer from I/O port 0x1F0 + for (volatile uint32_t i = 0; i < sector_count; i++) { + // 10. Then loop back to waiting for the next IRQ + // or poll again for each successive sector. + // 8. Wait for an IRQ or poll. + if (!poll_status()) { + // FIXME: Fail properly + for (;;) + ; + } + rep_insw(256, io_base + DATA_PORT, (void *)((uint32_t)address + i * 256)); + } +} + +void ata_init(void) { + io_base = PRIMARY_BUS_BASEPORT; + + // Before sending any data to the IO ports, + // read the Regular Status byte. The value + // 0xFF is an illegal status value, and + // indicates that the bus has no drives + if (0xFF == inb(io_base + STATUS_PORT)) { + klog("Bus has no drives", LOG_ERROR); + } + + // Issue IDENTIFY command + select_drive(1); +} + +void __attribute__((optimize("O0"))) +read_lba(uint32_t lba, void *address, size_t size, size_t offset) { + uintptr_t ptr = (uintptr_t)address; + lba += offset / SECTOR_SIZE; + offset = offset % SECTOR_SIZE; + asm("cli"); + size_t total_read = 0; + for (int i = 0; size > 0; i++) { + uint32_t read_len = + (SECTOR_SIZE < (size + offset)) ? (SECTOR_SIZE - offset) : size; + ata_read_lba28(lba + i, 1, read_buffer); + memcpy((void *)ptr, read_buffer + offset, read_len); + size -= read_len; + total_read += read_len; + ptr += read_len; + offset = 0; + } +} + +void write_lba(uint32_t lba, volatile void *address, size_t size, + size_t offset) { + uintptr_t ptr = (uintptr_t)address; + lba += offset / SECTOR_SIZE; + offset = offset % SECTOR_SIZE; + size_t total_write = 0; + uint8_t sector_buffer[512]; + for (int i = 0; size > 0; i++) { + ata_read_lba28(lba + i, 1, sector_buffer); + uint32_t write_len = + (SECTOR_SIZE < (size + offset)) ? (SECTOR_SIZE - offset) : size; + + memcpy(sector_buffer + offset, (void *)ptr, write_len); + ata_write_lba28(lba + i, 1, sector_buffer); + + size -= write_len; + total_write += write_len; + ptr += write_len; + offset = 0; + } +} diff --git a/drivers/ata.h b/drivers/ata.h new file mode 100644 index 0000000..3e88d7f --- /dev/null +++ b/drivers/ata.h @@ -0,0 +1,16 @@ +#include "../cpu/idt.h" +#include <stddef.h> + +#define SECTOR_SIZE 512 + +void ata_init(void); + +void read_drive_chs(uint8_t head_index, uint8_t sector_count, + uint8_t sector_index, uint8_t cylinder_low_value, + uint8_t cylinder_high_value, void *address); +void read_drive_lba(uint32_t lba, uint8_t sector_count, void *address); +void read_lba(uint32_t lba, void *address, size_t size, size_t offset); +void write_lba(uint32_t lba, volatile void *address, size_t size, + size_t offset); +void ata_write_lba28(uint32_t lba, uint32_t sector_count, + volatile const uint8_t *buffer); diff --git a/drivers/keyboard.c b/drivers/keyboard.c new file mode 100644 index 0000000..8c96606 --- /dev/null +++ b/drivers/keyboard.c @@ -0,0 +1,188 @@ +#include <assert.h> +#include <drivers/keyboard.h> +#include <errno.h> +#include <fs/devfs.h> +#include <fs/fifo.h> +#include <fs/vfs.h> +#include <sched/scheduler.h> +#include <stdint.h> + +#define PS2_REG_DATA 0x60 +#define PS2_REG_STATUS 0x64 +#define PS2_REG_COMMAND 0x64 + +#define PS2_CMD_ENABLE_FIRST_PORT 0xAE // no rsp + +#define PS2_CMD_TEST_CONTROLLER 0xAA // has rsp + +#define PS2_RSP_TEST_PASSED 0x55 +#define PS2_RSP_TEST_FAILED 0xFC + +#define PS2_CMD_SET_SCANCODE 0xF0 // has rsp +#define PS2_KB_ACK 0xFA +#define PS2_KB_RESEND 0xFE + +#define PS2_CMD_SET_MAKE_RELEASE 0xF8 // has rsp + +uint8_t kb_scancodes[3] = {0x43, 0x41, 0x3f}; + +FIFO_FILE *keyboard_fifo; + +uint8_t ascii_table[] = { + 'e', '\x1B', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, + '\t', + + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', + // 0, // [ + // 0, // ] + // 0, + // 0, // ? + '[', ']', + '\n', // ENTER + 'C', + + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', + ';', // ; + '\'', // ; + '`', // ; + 'D', // LEFT SHIFT + '\\', // ; + 'z', 'x', 'c', 'v', 'b', 'n', 'm', + ',', // ; + '.', // ; + '/', // ; + 'U', // ; + 'U', // ; + 'U', // ; + ' ', // ; +}; + +uint8_t capital_ascii_table[] = { + 'e', '\x1B', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, + '\t', + + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', + // 0, // [ + // 0, // ] + // 0, + // 0, // ? + '{', '}', + '\n', // ENTER + 'C', + + 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', + ':', // ; + '\"', // ; + '~', // ; + 'D', // LEFT SHIFT + '\\', // ; + 'Z', 'X', 'C', 'V', 'B', 'N', 'M', + '<', // ; + '>', // ; + '?', // ; + 'U', // ; + 'U', // ; + 'U', // ; + ' ', // ; +}; + +vfs_inode_t *kb_inode; + +uint8_t keyboard_to_ascii(uint16_t key, uint8_t capital) { + if ((key & 0xFF) > sizeof(ascii_table)) + return 'U'; + if (capital) + return capital_ascii_table[key & 0xFF]; + else + return ascii_table[key & 0xFF]; +} + +uint8_t is_shift_down = 0; +uint8_t is_alt_down = 0; + +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +extern process_t *ready_queue; +__attribute__((interrupt)) void +int_keyboard(__attribute__((unused)) struct interrupt_frame *frame) { + outb(0x20, 0x20); + uint16_t c; + c = inb(PS2_REG_DATA); + int released = 0; + if (c & 0x80) { + switch ((c & ~(0x80)) & 0xFF) { + case 0x2A: // Left shift + case 0x36: // Right shift + is_shift_down = 0; + return; + case 0x38: + is_alt_down = 0; + return; + } + released = 1; + } else { + switch (c & 0xFF) { + case 0x2A: // Left shift + case 0x36: // Right shift + is_shift_down = 1; + return; + case 0x38: + is_alt_down = 1; + return; + } + released = 0; + } + unsigned char a = keyboard_to_ascii((c & ~(0x80)) & 0xFF, is_shift_down); + struct KEY_EVENT ev; + ev.c = a; + ev.release = released; + ev.mode = 0; + ev.mode |= is_shift_down << 0; + ev.mode |= is_alt_down << 1; + fifo_object_write((uint8_t *)&ev, 0, sizeof(ev), keyboard_fifo); + kb_inode->has_data = keyboard_fifo->has_data; +} + +#define PS2_WAIT_RECV \ + { \ + for (;;) { \ + uint8_t status = inb(PS2_REG_STATUS); \ + if (status & 0x1) \ + break; \ + } \ + } + +#define PS2_WAIT_SEND \ + { \ + for (;;) { \ + uint8_t status = inb(PS2_REG_STATUS); \ + if (!(status & (0x1 << 1))) \ + break; \ + } \ + } + +void install_keyboard(void) { + keyboard_fifo = create_fifo_object(); + install_handler(int_keyboard, INT_32_INTERRUPT_GATE(0x3), 0x21); +} + +int keyboard_read(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd) { + (void)offset; + + if (0 == fd->inode->has_data) { + return -EAGAIN; + } + int rc = fifo_object_read(buffer, 0, len, keyboard_fifo); + fd->inode->has_data = keyboard_fifo->has_data; + return rc; +} + +void add_keyboard(void) { + kb_inode = devfs_add_file("/keyboard", keyboard_read, NULL, NULL, 0, 0, + FS_TYPE_CHAR_DEVICE); +} diff --git a/drivers/keyboard.h b/drivers/keyboard.h new file mode 100644 index 0000000..4b76f22 --- /dev/null +++ b/drivers/keyboard.h @@ -0,0 +1,11 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include <stdint.h> +#include <cpu/io.h> +#include <cpu/idt.h> + +void install_keyboard(void); +void add_keyboard(void); + +#endif diff --git a/drivers/mouse.c b/drivers/mouse.c new file mode 100644 index 0000000..23619a0 --- /dev/null +++ b/drivers/mouse.c @@ -0,0 +1,144 @@ +#include <cpu/idt.h> +#include <drivers/mouse.h> +#include <fs/devfs.h> +#include <fs/fifo.h> +#include <fs/vfs.h> +#include <stdint.h> + +uint8_t mouse_cycle = 0; // unsigned char +uint8_t mouse_uint8_t[3]; // signed char +uint8_t mouse_x = 0; // signed char +uint8_t mouse_y = 0; // signed char +vfs_inode_t *mouse_inode; +vfs_fd_t *mouse_fd; + +struct mouse_event { + uint8_t buttons; + uint8_t x; + uint8_t y; +}; + +int fs_mouse_write(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd) { + int rc = fifo_object_write(buffer, offset, len, fd->inode->internal_object); + FIFO_FILE *f = fd->inode->internal_object; + mouse_inode->has_data = f->has_data; + return rc; +} + +int fs_mouse_read(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd) { + FIFO_FILE *f = fd->inode->internal_object; + if (!mouse_inode->has_data) + return 0; + int rc = fifo_object_read(buffer, offset, len, f); + mouse_inode->has_data = f->has_data; + return rc; +} + +void add_mouse(void) { + mouse_inode = devfs_add_file("/mouse", fs_mouse_read, fs_mouse_write, NULL, 0, + 0, FS_TYPE_CHAR_DEVICE); + mouse_inode->internal_object = create_fifo_object(); + // Don't look at this + int fd = vfs_open("/dev/mouse", O_RDWR, 0); + mouse_fd = get_vfs_fd(fd); + get_current_task()->file_descriptors[fd] = NULL; +} + +__attribute__((interrupt)) void what(registers_t *r) { EOI(0xe); } + +__attribute__((interrupt)) void int_mouse(registers_t *r) { + (void)r; + EOI(12); + switch (mouse_cycle) { + case 0: + mouse_uint8_t[0] = inb(0x60); + if(!(mouse_uint8_t[0] & (1 << 3))) { + mouse_cycle = 0; + return; + } + mouse_cycle++; + break; + case 1: + mouse_uint8_t[1] = inb(0x60); + mouse_cycle++; + break; + case 2: + mouse_uint8_t[2] = inb(0x60); + mouse_x = mouse_uint8_t[1]; + mouse_y = mouse_uint8_t[2]; + mouse_cycle = 0; + struct mouse_event e; + e.buttons = mouse_uint8_t[0]; + e.x = mouse_x; + e.y = mouse_y; + raw_vfs_pwrite(mouse_fd, &e, sizeof(e), 0); + break; + } +} + +void mouse_wait(uint8_t a_type) { + uint32_t _time_out = 100000; + if (a_type == 0) { + while (_time_out--) { + if ((inb(0x64) & 1) == 1) { + return; + } + } + return; + } else { + while (_time_out--) { + if ((inb(0x64) & 2) == 0) { + return; + } + } + return; + } +} + +void mouse_write(uint8_t a_write) { + // Wait to be able to send a command + mouse_wait(1); + // Tell the mouse we are sending a command + outb(0x64, 0xD4); + // Wait for the final part + mouse_wait(1); + // Finally write + outb(0x60, a_write); +} + +uint8_t mouse_read() { + // Get's response from mouse + mouse_wait(0); + return inb(0x60); +} + +void install_mouse(void) { + uint8_t _status; // unsigned char + asm("cli"); + // Enable the auxiliary mouse device + mouse_wait(1); + outb(0x64, 0xA8); + + // Enable the interrupts + mouse_wait(1); + outb(0x64, 0x20); + mouse_wait(0); + _status = (inb(0x60) | 2); + mouse_wait(1); + outb(0x64, 0x60); + mouse_wait(1); + outb(0x60, _status); + + // Tell the mouse to use default settings + mouse_write(0xF6); + mouse_read(); // Acknowledge + + // Enable the mouse + mouse_write(0xF4); + mouse_read(); // Acknowledge + + install_handler(int_mouse, INT_32_INTERRUPT_GATE(0x3), 12 + 0x20); + install_handler(what, INT_32_INTERRUPT_GATE(0x3), 0xe + 0x20); +} diff --git a/drivers/mouse.h b/drivers/mouse.h new file mode 100644 index 0000000..5248143 --- /dev/null +++ b/drivers/mouse.h @@ -0,0 +1,5 @@ +#ifndef MOUSE_H +#define MOUSE_H +void install_mouse(void); +void add_mouse(void); +#endif diff --git a/drivers/pit.c b/drivers/pit.c new file mode 100644 index 0000000..711883c --- /dev/null +++ b/drivers/pit.c @@ -0,0 +1,55 @@ +#include "pit.h" + +#define PIT_IO_CHANNEL_0 0x40 +#define PIT_IO_MODE_COMMAND 0x43 + +uint64_t clock_num_ms_ticks = 0; +uint64_t pit_counter = 0; +uint16_t hertz; + +uint64_t pit_num_ms(void) { return clock_num_ms_ticks; } + +uint16_t read_pit_count(void) { + uint16_t count = 0; + + outb(PIT_IO_MODE_COMMAND, 0x0 /*0b00000000*/); + + count = inb(PIT_IO_CHANNEL_0); + count |= inb(PIT_IO_CHANNEL_0) << 8; + + return count; +} + +void set_pit_count(uint16_t hertz) { + uint16_t divisor = 1193180 / hertz; + + /* + * 0b00110110 + * ^^ + * channel - 0 + * ^^ + * r/w mode - LSB then MSB + * ^^^ + * mode - 3 Square Wave Mode + * ^ + * BCD - no + */ + outb(PIT_IO_MODE_COMMAND, 0x36 /*0b00110110*/); + outb(PIT_IO_CHANNEL_0, divisor & 0xFF); + outb(PIT_IO_CHANNEL_0, (divisor & 0xFF00) >> 8); +} + +__attribute__((interrupt)) void +int_clock(__attribute__((unused)) struct interrupt_frame *frame) { + outb(0x20, 0x20); + pit_counter++; + if (pit_counter >= hertz / 1000) { + pit_counter = 0; + clock_num_ms_ticks++; + } + switch_task(); +} + +void pit_install(void) { + install_handler(int_clock, INT_32_INTERRUPT_GATE(0x0), 0x20); +} diff --git a/drivers/pit.h b/drivers/pit.h new file mode 100644 index 0000000..8d9ce98 --- /dev/null +++ b/drivers/pit.h @@ -0,0 +1,12 @@ +#ifndef PIT_H +#define PIT_H +#include <cpu/idt.h> +#include <cpu/io.h> +#include <sched/scheduler.h> +#include <stdint.h> +#include <stdio.h> + +void pit_install(void); +void set_pit_count(uint16_t hertz); +uint64_t pit_num_ms(void); +#endif diff --git a/drivers/pst.c b/drivers/pst.c new file mode 100644 index 0000000..d063ec9 --- /dev/null +++ b/drivers/pst.c @@ -0,0 +1,17 @@ +#include <drivers/pst.h> +#include <fs/tmpfs.h> + +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp) { + (void)name; + (void)termp; + (void) winp; + int fd[2]; + pipe(fd); // This depends upon that pipe will support read and write + // through the same fd. In reality this should not be the + // case. + *amaster = fd[0]; + *aslave = fd[1]; + return 0; +} diff --git a/drivers/pst.h b/drivers/pst.h new file mode 100644 index 0000000..e8fdfaa --- /dev/null +++ b/drivers/pst.h @@ -0,0 +1,7 @@ +#ifndef PST_H +#define PST_H +#include "../fs/vfs.h" + +int openpty(int *amaster, int *aslave, char *name, /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp); +#endif diff --git a/drivers/serial.c b/drivers/serial.c new file mode 100644 index 0000000..549d852 --- /dev/null +++ b/drivers/serial.c @@ -0,0 +1,35 @@ +#include "cpu/io.h" + +#define PORT 0x3f8 // COM1 + +int serial_init(void) { + outb(PORT + 1, 0x00); // Disable all interrupts + outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(PORT + 1, 0x00); // (hi byte) + outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip + outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial + // returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if (inb(PORT + 0) != 0xAE) { + return 1; + } + + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + outb(PORT + 4, 0x0F); + return 0; +} + +int is_transmit_empty() { return inb(PORT + 5) & 0x20; } + +void write_serial(char a) { + while (is_transmit_empty() == 0) + ; + + outb(PORT, a); +} diff --git a/drivers/serial.h b/drivers/serial.h new file mode 100644 index 0000000..327765b --- /dev/null +++ b/drivers/serial.h @@ -0,0 +1,2 @@ +int serial_init(void); +void write_serial(char a); diff --git a/drivers/vbe.c b/drivers/vbe.c new file mode 100644 index 0000000..97f5507 --- /dev/null +++ b/drivers/vbe.c @@ -0,0 +1,50 @@ +#include <assert.h> +#include <drivers/vbe.h> +#include <fs/devfs.h> +#include <fs/vfs.h> +#include <mmu.h> +#include <stdio.h> + +uint8_t *framebuffer; +uint32_t framebuffer_physical; +uint32_t framebuffer_width; +uint32_t framebuffer_height; +uint64_t framebuffer_size; + +vfs_vm_object_t vbe_vm_object; + +#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit))) + +void display_driver_init(multiboot_info_t *mbi) { + assert(CHECK_FLAG(mbi->flags, 12)); + framebuffer_width = mbi->framebuffer_width; + framebuffer_height = mbi->framebuffer_height; + + uint32_t bits_pp = mbi->framebuffer_bpp; + uint32_t bytes_pp = (bits_pp / 8) + (8 - (bits_pp % 8)); + + framebuffer_size = bytes_pp * framebuffer_width * framebuffer_height; + + framebuffer_physical = mbi->framebuffer_addr; + framebuffer = + mmu_map_frames((void *)(uint32_t)mbi->framebuffer_addr, framebuffer_size); +} + +vfs_vm_object_t *vbe_get_vm_object(uint64_t length, uint64_t offset, + vfs_fd_t *fd) { + (void)fd; + (void)length; + (void)offset; + vbe_vm_object.size = framebuffer_size; + int n = (uintptr_t)align_page((void *)(uint32_t)framebuffer_size) / 0x1000; + vbe_vm_object.object = kmalloc(sizeof(void *) * n); + for (int i = 0; i < n; i++) { + vbe_vm_object.object[i] = (void *)framebuffer_physical + (i * 0x1000); + } + return &vbe_vm_object; +} + +void add_vbe_device(void) { + devfs_add_file("/vbe", NULL, NULL, vbe_get_vm_object, 1, 1, + FS_TYPE_BLOCK_DEVICE); +} diff --git a/drivers/vbe.h b/drivers/vbe.h new file mode 100644 index 0000000..4df2221 --- /dev/null +++ b/drivers/vbe.h @@ -0,0 +1,7 @@ +#ifndef VBE_H +#define VBE_H +#include <multiboot.h> +void display_driver_init(multiboot_info_t *mb); +void display_driver_cross(multiboot_info_t *mbi); +void add_vbe_device(void); +#endif // VBE_H @@ -0,0 +1,73 @@ +#include <assert.h> +#include <crypto/SHA1/sha1.h> +#include <elf.h> +#include <sched/scheduler.h> +#include <stddef.h> +#include <stdint.h> + +void *load_elf_file(const char *f, uint32_t *ds) { + // ELFHeader *header = kmalloc(sizeof(ELFHeader)); + ELFHeader header; + int fd = vfs_open(f, O_RDONLY, 0); + if (fd < 0) { + return NULL; + } + + if (sizeof(header) != vfs_pread(fd, &header, sizeof(header), 0)) { + return NULL; + } + + if (0 != memcmp(header.e_ident, "\x7F\x45\x4C\x46" /* "\x7FELF" */, 4)) { + klog("Incorrect ELF signature", LOG_ERROR); + return NULL; + } + + if (0 > fd) { + return NULL; + } + Elf32_Phdr program_header; + assert(sizeof(program_header) == header.e_phentsize); + uint32_t header_offset = header.e_phoff; + uintptr_t end_of_code = 0; + for (int i = 0; i < header.e_phnum; + i++, header_offset += header.e_phentsize) { + if (0 >= + vfs_pread(fd, &program_header, sizeof(program_header), header_offset)) { + return NULL; + } + + // FIXME: Only one type is supported, which is 1(load). More should be + // added. + assert(1 == program_header.p_type); + + // 1. Clear p_memsz bytes at p_vaddr to 0.(We also allocate frames for + // that range) + uint32_t p_memsz = program_header.p_memsz; + uint32_t p_vaddr = program_header.p_vaddr; + + uint32_t pages_to_allocate = + (uint32_t)align_page((void *)(p_vaddr + p_memsz)); + pages_to_allocate -= p_vaddr - (p_vaddr % 0x1000); + pages_to_allocate /= 0x1000; + + mmu_allocate_region((void *)p_vaddr, pages_to_allocate * 0x1000, + MMU_FLAG_RW); + + flush_tlb(); + + uintptr_t e = program_header.p_vaddr + program_header.p_memsz; + if (e > end_of_code) + end_of_code = e; + + memset((void *)program_header.p_vaddr, 0, program_header.p_memsz); + + // 2. Copy p_filesz bytes from p_offset to p_vaddr + int rc = vfs_pread(fd, (void *)program_header.p_vaddr, + program_header.p_filesz, program_header.p_offset); + + assert(rc == (int)program_header.p_filesz); + } + *ds = end_of_code; + vfs_close(fd); + return (void *)header.e_entry; +} @@ -0,0 +1,99 @@ +#ifndef ELF_H +#define ELF_H +#include <stdint.h> +#include <mmu.h> +#include <fs/vfs.h> +#include <assert.h> + +#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_LOPROC 0xff00 // Processor-specific +#define ET_HIPROC 0xffff // Processor-specific + +#define EM_NONE 0 // No machine +#define EM_M32 1 // AT&T WE 32100 +#define EM_SPARC 2 // SPARC +#define EM_386 3 // Intel 80386 +#define EM_68K 4 // Motorola 68000 +#define EM_88K 5 // Motorola 88000 +#define EM_860 7 // Intel 80860 +#define EM_MIPS 8 // MIPS RS3000 + +#define EV_NONE 0 // Invalid version +#define EV_CURRENT 1 // Current version + +#define ELF_EXECUTABLE (1 << 0) +#define ELF_WRITABLE (1 << 1) +#define ELF_READABLE (1 << 2) + +#define Elf32_Addr uint32_t // Unsigned program address +#define Elf32_Half uint16_t // Unsigned medium integer +#define Elf32_Off uint32_t // Unsigned file offset +#define Elf32_Sword uint32_t // Signed large integer +#define Elf32_Word uint32_t // Unsigned large integer + +#define ELF_EXEC (1 << 0) +#define ELF_WRITE (1 << 1) +#define ELF_READ (1 << 2) + +// ELF header +typedef struct { + unsigned char e_ident[16]; + Elf32_Half e_type; // Object file type (ET_*) + Elf32_Half e_machine; // Required architecture (EM_*) + Elf32_Word e_version; // Object file version (EV_*) + Elf32_Addr e_entry; // File entry point + Elf32_Off e_phoff; // Program header table's offset(bytes) + Elf32_Off e_shoff; // Section header table's offset(bytes) + Elf32_Word e_flags; + Elf32_Half e_ehsize; // ELF Header size + Elf32_Half + e_phentsize; // Size of program's header tables(all are the same size) + Elf32_Half e_phnum; // Amount of program headers + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} __attribute__((packed)) ELFHeader; + +// Section header +typedef struct { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +enum ShT_Types { + SHT_NULL = 0, // Null section + SHT_PROGBITS = 1, // Program information + SHT_SYMTAB = 2, // Symbol table + SHT_STRTAB = 3, // String table + SHT_RELA = 4, // Relocation (w/ addend) + SHT_NOBITS = 8, // Not present in file + SHT_REL = 9, // Relocation (no addend) +}; + +// Program header +typedef struct { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} __attribute__((packed)) Elf32_Phdr; + + +void *load_elf_file(const char *f, uint32_t *ds); +#endif diff --git a/fs/devfs.c b/fs/devfs.c new file mode 100644 index 0000000..14748a7 --- /dev/null +++ b/fs/devfs.c @@ -0,0 +1,91 @@ +#include <drivers/keyboard.h> +#include <drivers/serial.h> +#include <fs/devfs.h> +#include <fs/vfs.h> +#include <random.h> + +devfs_file files[20]; +int num_files = 0; + +vfs_inode_t *devfs_add_file( + char *path, + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + vfs_vm_object_t *(get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd), + uint8_t has_data, uint8_t can_write, int type) { + files[num_files].name = copy_and_allocate_string(path); + + vfs_inode_t *i = kmalloc(sizeof(vfs_inode_t)); + files[num_files].inode = i; + i->type = type; + i->read = read; + i->write = write; + i->close = NULL; + i->get_vm_object = get_vm_object; + i->has_data = has_data; + i->is_open = 1; + i->can_write = can_write; + num_files++; + return i; +} + +vfs_inode_t *devfs_open(const char *file) { + for (int i = 0; i < num_files; i++) + if (isequal_n(files[i].name, file, strlen(files[i].name))) + return files[i].inode; + + return 0; +} + +int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + return fd->inode->read(buffer, offset, len, fd); +} + +int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + return fd->inode->write(buffer, offset, len, fd); +} + +vfs_vm_object_t *devfs_get_vm_object(uint64_t length, uint64_t offset, + vfs_fd_t *fd) { + return fd->inode->get_vm_object(length, offset, fd); +} + +int stdout_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + + int rc = len; + for (; len--;) + putc(*buffer++); + return rc; +} + +int serial_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + + int rc = len; + for (; len--;) + write_serial(*buffer++); + return rc; +} + +void add_serial(void) { + devfs_add_file("/serial", NULL, serial_write, NULL, 0, 1, + FS_TYPE_CHAR_DEVICE); +} + +void add_stdout(void) { + devfs_add_file("/stdout", NULL, stdout_write, NULL, 0, 1, + FS_TYPE_CHAR_DEVICE); +} + +vfs_inode_t *devfs_mount(void) { + vfs_inode_t *root = kmalloc_eternal(sizeof(vfs_inode_t)); + root->open = devfs_open; + root->read = devfs_read; + root->write = devfs_write; + root->close = NULL; + return root; +} diff --git a/fs/devfs.h b/fs/devfs.h new file mode 100644 index 0000000..23a499e --- /dev/null +++ b/fs/devfs.h @@ -0,0 +1,26 @@ +#ifndef DEVFS_H +#define DEVFS_H +#include <defs.h> +#include <fs/vfs.h> +#include <stdint.h> + +typedef struct devfs_file { + char *name; + vfs_inode_t *inode; +} devfs_file; + +vfs_inode_t *devfs_mount(void); +vfs_inode_t *devfs_open(const char *file); +int devfs_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); +int devfs_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); +void add_stdout(void); +void add_serial(void); +vfs_inode_t *devfs_add_file( + char *path, + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd), + uint8_t has_data, uint8_t can_write, int type); + +#endif diff --git a/fs/ext2.c b/fs/ext2.c new file mode 100644 index 0000000..3b4dba8 --- /dev/null +++ b/fs/ext2.c @@ -0,0 +1,633 @@ +#include <assert.h> +#include <fs/ext2.h> +#include <fs/vfs.h> +#include <stdint.h> +#include <string.h> + +#define EXT2_SUPERBLOCK_SECTOR 2 +#define EXT2_ROOT_INODE 2 + +#define BLOCKS_REQUIRED(_a, _b) ((_a) / (_b) + (((_a) % (_b)) != 0)) + +superblock_t *superblock; +uint32_t block_byte_size; +uint32_t inode_size; +uint32_t inodes_per_block; + +#define BLOCK_SIZE (block_byte_size) + +void ext2_close(vfs_fd_t *fd) { + return; // There is nothing to clear +} + +int read_inode(int inode_num, unsigned char *data, uint64_t size, + uint64_t offset, uint64_t *file_size); + +void ext2_read_block(uint32_t block, void *address, size_t size, + size_t offset) { + read_lba(block * block_byte_size / 512, address, size, offset); +} + +void ext2_write_block(uint32_t block, void *address, size_t size, + size_t offset) { + write_lba(block * block_byte_size / 512, address, size, offset); +} + +void write_group_descriptor(uint32_t group_index, bgdt_t *block_group) { + int starting_block = (1024 == block_byte_size) ? 2 : 1; + ext2_write_block(starting_block, block_group, sizeof(bgdt_t), + group_index * sizeof(bgdt_t)); +} + +void get_group_descriptor(uint32_t group_index, bgdt_t *block_group) { + int starting_block = (1024 == block_byte_size) ? 2 : 1; + ext2_read_block(starting_block, block_group, sizeof(bgdt_t), + group_index * sizeof(bgdt_t)); +} + +uint32_t num_block_groups(void) { + // Determining the Number of Block Groups + + // From the Superblock, extract the size of each block, the total + // number of inodes, the total number of blocks, the number of blocks + // per block group, and the number of inodes in each block group. From + // this information we can infer the number of block groups there are + // by: + + // Rounding up the total number of blocks divided by the number of + // blocks per block group + uint32_t num_blocks = superblock->num_blocks; + uint32_t num_blocks_in_group = superblock->num_blocks_in_group; + uint32_t b = num_blocks / num_blocks_in_group; + if (num_blocks % num_blocks_in_group != 0) + b++; + + // Rounding up the total number of inodes divided by the number of + // inodes per block group + uint32_t num_inodes = superblock->num_inodes; + uint32_t num_inodes_in_group = superblock->num_inodes_in_group; + uint32_t i = num_inodes / num_inodes_in_group; + if (num_inodes % num_inodes_in_group != 0) + i++; + // Both (and check them against each other) + assert(i == b); + return i; +} + +void ext2_block_containing_inode(uint32_t inode_index, uint32_t *block_index, + uint32_t *offset) { + assert(0 != inode_index); + bgdt_t block_group; + get_group_descriptor((inode_index - 1) / superblock->num_inodes_in_group, + &block_group); + + uint64_t full_offset = + ((inode_index - 1) % superblock->num_inodes_in_group) * inode_size; + *block_index = block_group.starting_inode_table + + (full_offset >> (superblock->block_size + 10)); + *offset = full_offset & (block_byte_size - 1); +} + +void ext2_get_inode_header(int inode_index, inode_t *data) { + uint32_t block_index; + uint32_t block_offset; + ext2_block_containing_inode(inode_index, &block_index, &block_offset); + + uint8_t mem_block[inode_size]; + ext2_read_block(block_index, mem_block, inode_size, block_offset); + + memcpy(data, mem_block, inode_size); +} + +void ext2_write_inode(int inode_index, inode_t *data) { + uint32_t block_index; + uint32_t block_offset; + ext2_block_containing_inode(inode_index, &block_index, &block_offset); + + uint8_t mem_block[inode_size]; + memcpy(mem_block, data, inode_size); + ext2_write_block(block_index, mem_block, inode_size, block_offset); +} + +int ext2_get_inode_in_directory(int dir_inode, char *file, + direntry_header_t *entry) { + // FIXME: Allocate sufficent size each time + unsigned char *data = kmalloc(block_byte_size * 5); + ASSERT_BUT_FIXME_PROPOGATE( + -1 != read_inode(dir_inode, data, block_byte_size * 5, 0, 0)); + + direntry_header_t *dir; + unsigned char *data_p = data; + for (; (dir = (direntry_header_t *)data_p)->inode; data_p += dir->size) { + if (0 == dir->size) + break; + if (0 == dir->name_length) + continue; + if (0 == + memcmp(data_p + sizeof(direntry_header_t), file, dir->name_length)) { + if (strlen(file) > dir->name_length) + continue; + if (entry) + memcpy(entry, data_p, sizeof(direntry_header_t)); + return dir->inode; + } + } + return 0; +} + +int ext2_read_dir(int dir_inode, unsigned char *buffer, size_t len, + size_t offset) { + unsigned char data[block_byte_size]; + read_inode(dir_inode, data, block_byte_size, 0, 0); + + direntry_header_t *dir; + struct dirent tmp_entry; + size_t n_dir = 0; + int rc = 0; + unsigned char *data_p = data; + for (; (dir = (direntry_header_t *)data_p)->inode && len > 0; + data_p += dir->size, n_dir++) { + if (0 == dir->size) + break; + if (0 == dir->name_length) + continue; + if (n_dir < (offset / sizeof(struct dirent))) + continue; + + memcpy(tmp_entry.d_name, data_p + sizeof(direntry_header_t), + dir->name_length); + tmp_entry.d_name[dir->name_length] = '\0'; + uint8_t *p = (uint8_t *)&tmp_entry; + size_t l = sizeof(struct dirent); + + l = (len < l) ? len : l; + memcpy(buffer, p, l); + len -= l; + rc += l; + } + return rc; +} + +uint32_t ext2_find_inode(const char *file) { + int cur_path_inode = EXT2_ROOT_INODE; + + if (*file == '/' && *(file + 1) == '\0') + return cur_path_inode; + + char *str = copy_and_allocate_string(file); + char *orig_str = str; + + char *start; + for (;;) { + int final = 0; + start = str + 1; + str++; + + for (; '/' != *str && '\0' != *str; str++) + ; + if ('\0' == *str) + final = 1; + + *str = '\0'; + + direntry_header_t a; + if (0 == (cur_path_inode = + ext2_get_inode_in_directory(cur_path_inode, start, &a))) { + kfree(orig_str); + return 0; + } + + if (final) + break; + + // The expected returned entry is a directory + if (TYPE_INDICATOR_DIRECTORY != a.type_indicator) { + kfree(orig_str); + kprintf("FAILED\n"); + return 0; + } + } + kfree(orig_str); + return cur_path_inode; +} + +uint32_t get_singly_block_index(uint32_t singly_block_ptr, uint32_t i) { + uint8_t block[block_byte_size]; + ext2_read_block(singly_block_ptr, block, block_byte_size, 0); + uint32_t index = *(uint32_t *)(block + (i * (32 / 8))); + return index; +} + +int get_block(inode_t *inode, uint32_t i) { + if (i < 12) + return inode->block_pointers[i]; + + i -= 12; + uint32_t singly_block_size = block_byte_size / (32 / 8); + uint32_t double_block_size = (singly_block_size * singly_block_size); + if (i < singly_block_size) { + return get_singly_block_index(inode->single_indirect_block_pointer, i); + } else if (i < double_block_size) { + i -= singly_block_size; + uint32_t singly_entry = get_singly_block_index( + inode->double_indirect_block_pointer, i / singly_block_size); + uint32_t offset_in_entry = i % singly_block_size; + int block = get_singly_block_index(singly_entry, offset_in_entry); + return block; + } + assert(0); + return 0; +} + +int get_free_block(int allocate) { + bgdt_t block_group; + uint8_t bitmap[BLOCK_SIZE]; + assert(0 < superblock->num_blocks_unallocated); + for (uint32_t g = 0; g < num_block_groups(); g++) { + get_group_descriptor(g, &block_group); + + if (block_group.num_unallocated_blocks_in_group == 0) { + kprintf("skip\n"); + continue; + } + + ext2_read_block(block_group.block_usage_bitmap, bitmap, BLOCK_SIZE, 0); + for (uint32_t i = 0; i < superblock->num_blocks_in_group; i++) { + if (!(bitmap[i >> 3] & (1 << (i % 8)))) { + if (allocate) { + bitmap[i >> 3] |= (1 << (i % 8)); + ext2_write_block(block_group.block_usage_bitmap, bitmap, BLOCK_SIZE, + 0); + block_group.num_unallocated_blocks_in_group--; + write_group_descriptor(g, &block_group); + superblock->num_blocks_unallocated--; + write_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, + 0); + } + return i + g * superblock->num_blocks_in_group + 1; + } + } + } + return -1; +} + +int get_free_inode(int allocate) { + bgdt_t block_group; + assert(0 < superblock->num_inodes_unallocated); + for (uint32_t g = 0; g < num_block_groups(); g++) { + get_group_descriptor(g, &block_group); + + if (0 == block_group.num_unallocated_inodes_in_group) + continue; + + uint8_t bitmap[BLOCK_SIZE]; + ext2_read_block(block_group.inode_usage_bitmap, bitmap, BLOCK_SIZE, 0); + for (uint32_t i = 0; i < superblock->num_inodes_in_group; i++) { + if (!(bitmap[i / 8] & (1 << (i % 8)))) { + if (allocate) { + bitmap[i / 8] |= (1 << (i % 8)); + ext2_write_block(block_group.inode_usage_bitmap, bitmap, BLOCK_SIZE, + 0); + block_group.num_unallocated_inodes_in_group--; + write_group_descriptor(g, &block_group); + superblock->num_inodes_unallocated--; + write_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, + 0); + } + return i + g * superblock->num_inodes_in_group + 1; + } + } + } + return -1; +} + +int write_inode(int inode_num, unsigned char *data, uint64_t size, + uint64_t offset, uint64_t *file_size, int append) { + (void)file_size; + uint8_t inode_buffer[inode_size]; + ext2_get_inode_header(inode_num, (inode_t *)inode_buffer); + inode_t *inode = (inode_t *)inode_buffer; + + uint64_t fsize = (uint64_t)(((uint64_t)inode->_upper_32size << 32) | + (uint64_t)inode->low_32size); + if (append) + offset = fsize; + + uint32_t block_start = offset / block_byte_size; + uint32_t block_offset = offset % block_byte_size; + + int num_blocks_used = inode->num_disk_sectors / (BLOCK_SIZE / SECTOR_SIZE); + + if (size + offset > fsize) + fsize = size + offset; + + int num_blocks_required = BLOCKS_REQUIRED(fsize, BLOCK_SIZE); + + for (int i = num_blocks_used; i < num_blocks_required; i++) { + if (i > 12) + assert(0); + int b = get_free_block(1 /*true*/); + assert(-1 != b); + inode->block_pointers[i] = b; + } + + inode->num_disk_sectors = num_blocks_required * (BLOCK_SIZE / SECTOR_SIZE); + + int bytes_written = 0; + for (int i = block_start; size; i++) { + uint32_t block = get_block(inode, i); + if (0 == block) { + kprintf("block_not_found\n"); + break; + } + + int write_len = ((size + block_offset) > block_byte_size) + ? (block_byte_size - block_offset) + : size; + ext2_write_block(block, data + bytes_written, write_len, block_offset); + block_offset = 0; + bytes_written += write_len; + size -= write_len; + } + inode->low_32size = fsize; + inode->_upper_32size = (fsize >> 32); + ext2_write_inode(inode_num, inode); + return bytes_written; +} + +int read_inode(int inode_num, unsigned char *data, uint64_t size, + uint64_t offset, uint64_t *file_size) { + // TODO: Fail if size is lower than the size of the file being read, and + // return the size of the file the callers is trying to read. + uint8_t inode_buffer[inode_size]; + ext2_get_inode_header(inode_num, (inode_t *)inode_buffer); + inode_t *inode = (inode_t *)inode_buffer; + + uint64_t fsize = (uint64_t)(((uint64_t)inode->_upper_32size << 32) | + (uint64_t)inode->low_32size); + + if (file_size) + *file_size = fsize; + + if (size > fsize - offset) + size -= ((size + offset) - fsize); + + if (size == 0) + return 0; + + if (offset > fsize) + return 0; + + uint32_t block_start = offset / block_byte_size; + uint32_t block_offset = offset % block_byte_size; + + int bytes_read = 0; + for (int i = block_start; size; i++) { + uint32_t block = get_block(inode, i); + if (0 == block) { + klog("Filesystem EXT2: Unable to find block", LOG_WARN); + return -1; + } + + int read_len = ((size + block_offset) > block_byte_size) + ? (block_byte_size - block_offset) + : size; + ext2_read_block(block, data + bytes_read, read_len, block_offset); + block_offset = 0; + bytes_read += read_len; + size -= read_len; + } + return bytes_read; +} + +size_t ext2_read_file_offset(const char *file, unsigned char *data, + uint64_t size, uint64_t offset, + uint64_t *file_size) { + // TODO: Fail if the file does not exist. + uint32_t inode = ext2_find_inode(file); + return read_inode(inode, data, size, offset, file_size); +} + +size_t ext2_read_file(const char *file, unsigned char *data, size_t size, + uint64_t *file_size) { + return ext2_read_file_offset(file, data, size, 0, file_size); +} + +int resolve_link(int inode_num) { + uint8_t tmp[inode_size]; + inode_t *inode = (inode_t *)tmp; + uint64_t inode_size = + (((uint64_t)inode->_upper_32size) << 32) & inode->low_32size; + assert(inode_size <= 60); + ext2_get_inode_header(inode_num, inode); + char *path = (char *)(tmp + (10 * 4)); + path--; + *path = '/'; + return ext2_find_inode(path); +} + +int ext2_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + uint64_t file_size; + int rc; + int inode_num = fd->inode->inode_num; + assert(fd->inode->type != FS_TYPE_DIRECTORY); + if (fd->inode->type == FS_TYPE_LINK) { + inode_num = resolve_link(inode_num); + } + rc = write_inode(inode_num, buffer, len, offset, &file_size, 0); + return rc; +} + +int ext2_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + uint64_t file_size; + int rc; + int inode_num = fd->inode->inode_num; + if (fd->inode->type == FS_TYPE_DIRECTORY) { + rc = ext2_read_dir(inode_num, buffer, len, offset); + return rc; + } + if (fd->inode->type == FS_TYPE_LINK) { + inode_num = resolve_link(inode_num); + } + rc = read_inode(inode_num, buffer, len, offset, &file_size); + return rc; +} + +vfs_inode_t *ext2_open(const char *path) { + uint32_t inode_num = ext2_find_inode(path); + if (0 == inode_num) + return NULL; + + inode_t ext2_inode[inode_size]; + ext2_get_inode_header(inode_num, ext2_inode); + uint64_t file_size = + ((uint64_t)(ext2_inode->_upper_32size) << 32) | ext2_inode->low_32size; + + uint8_t type; + switch ((ext2_inode->types_permissions / 0x1000)) { + case 0xA: + type = FS_TYPE_LINK; + break; + case 0x4: + type = FS_TYPE_DIRECTORY; + break; + default: + type = FS_TYPE_FILE; + break; + } + + return vfs_create_inode(inode_num, type, 1 /*has_data*/, 1 /*can_write*/, + 1 /*is_open*/, NULL /*internal_object*/, file_size, + ext2_open, ext2_create_file, ext2_read, ext2_write, + ext2_close, NULL /*get_vm_object*/); +} + +uint64_t end_of_last_entry_position(int dir_inode, uint64_t *entry_offset, + direntry_header_t *meta) { + // FIXME: Allocate sufficent size each time + unsigned char data[block_byte_size * 5]; + uint64_t file_size = 0; + read_inode(dir_inode, data, block_byte_size * 5, 0, &file_size); + assert(block_byte_size * 5 > file_size); + + direntry_header_t *dir; + unsigned char *data_p = data; + uint64_t pos = 0; + uint64_t prev = pos; + for (; pos < file_size && (dir = (direntry_header_t *)data_p)->size; + data_p += dir->size, prev = pos, pos += dir->size) + ; + if (entry_offset) + *entry_offset = prev; + if (meta) + memcpy(meta, ((char *)data) + prev, sizeof(direntry_header_t)); + return pos; +} + +int ext2_create_entry(const char *path, int mode, int *error) { + (void)mode; + *error = 0; + // Check if the file already exists + { + uint32_t inode_num = ext2_find_inode(path); + if (0 != inode_num) { + klog("ext2_create_file: File already exists", LOG_WARN); + *error = 1; + return inode_num; + } + } + + uint32_t parent_inode; + // Get the parent directory + char path_buffer[strlen(path) + 1]; + strcpy(path_buffer, path); + char *e = path_buffer; + for (; *e; e++) + ; + for (; *e != '/'; e--) + ; + *e = '\0'; + if (*path_buffer == '\0') { + parent_inode = EXT2_ROOT_INODE; + } else { + parent_inode = ext2_find_inode(path_buffer); + } + if (0 == parent_inode) { // Parent does not exist + klog("ext2_create_file: Parent does not exist", LOG_WARN); + *error = 1; + return -1; + } + + const char *filename = e + 1; + + int new_file_inode = get_free_inode(1); + if (-1 == new_file_inode) { + klog("ext2_create_file: Unable to find free inode", LOG_WARN); + *error = 1; + return -1; + } + assert(0 != new_file_inode); + + uint64_t entry_offset = 0; + direntry_header_t meta; + end_of_last_entry_position(parent_inode, &entry_offset, &meta); + + uint32_t padding_in_use = block_byte_size - entry_offset; + + kprintf("meta.size: %x\n", meta.size); + kprintf("padding_in_use: %x\n", padding_in_use); + // assert(padding_in_use == meta.size); + assert(padding_in_use >= (sizeof(direntry_header_t) + strlen(filename))); + + // Modify the entry to have its real size + meta.size = sizeof(direntry_header_t) + meta.name_length; + meta.size += (4 - (meta.size % 4)); + write_inode(parent_inode, (unsigned char *)&meta, sizeof(direntry_header_t), + entry_offset, NULL, 0); + + // Create new entry + uint32_t new_entry_offset = entry_offset + meta.size; + direntry_header_t entry; + entry.inode = new_file_inode; + entry.type_indicator = TYPE_INDICATOR_REGULAR; + entry.name_length = strlen(filename); + entry.size = (sizeof(direntry_header_t) + entry.name_length); + entry.size += (4 - (entry.size % 4)); + + uint32_t length_till_next_block = 1024 - (new_entry_offset % 1024); + if (0 == length_till_next_block) + length_till_next_block = 1024; + assert(entry.size < length_till_next_block); + entry.size = length_till_next_block; + + uint8_t buffer[entry.size]; + memset(buffer, 0, entry.size); + memcpy(buffer, &entry, sizeof(entry)); + memcpy(buffer + sizeof(entry), filename, entry.name_length); + write_inode(parent_inode, (unsigned char *)buffer, entry.size, + new_entry_offset, NULL, 0); + return new_file_inode; +} + +int ext2_create_file(const char *path, int mode) { + int err; + int new_file_inode = ext2_create_entry(path, mode, &err); + if (err) + return 0; + // Create the inode header + uint8_t inode_buffer[inode_size]; + inode_t *new_inode = (inode_t *)inode_buffer; + memset(inode_buffer, 0, inode_size); + new_inode->types_permissions = 0x8000; + new_inode->num_hard_links = 1; + ext2_write_inode(new_file_inode, new_inode); + return new_file_inode; +} + +vfs_inode_t *ext2_mount(void) { + vfs_inode_t *root = kmalloc_eternal(sizeof(vfs_inode_t)); + root->open = ext2_open; + root->read = ext2_read; + root->write = ext2_write; + root->close = ext2_close; + root->create_file = ext2_create_file; + parse_superblock(); + return root; +} + +void parse_superblock(void) { + superblock = ksbrk(2 * SECTOR_SIZE); + read_lba(EXT2_SUPERBLOCK_SECTOR, (void *)superblock, 2 * SECTOR_SIZE, 0); + block_byte_size = 1024 << superblock->block_size; + + if (0xEF53 != superblock->ext2_signature) { + klog("Incorrect ext2 signature in superblock.", LOG_ERROR); + for (;;) + ; // TODO: Fail properly + } + + if (1 <= superblock->major_version) + inode_size = ((ext_superblock_t *)superblock)->inode_size; + + inodes_per_block = block_byte_size / inode_size; +} diff --git a/fs/ext2.h b/fs/ext2.h new file mode 100644 index 0000000..63684da --- /dev/null +++ b/fs/ext2.h @@ -0,0 +1,139 @@ +#ifndef EXT2_H +#define EXT2_H +#include <drivers/ata.h> +#include <fs/vfs.h> +#include <kmalloc.h> +#include <stdint.h> + +typedef struct Superblock { + uint32_t num_inodes; + uint32_t num_blocks; + uint32_t num_blocks_reserved; + uint32_t num_blocks_unallocated; + uint32_t num_inodes_unallocated; + uint32_t superblock_block_num; + uint32_t block_size; + uint32_t fragment_size; + uint32_t num_blocks_in_group; + uint32_t num_fragments_in_group; + uint32_t num_inodes_in_group; + uint32_t last_mount; + uint32_t last_write; + uint16_t num_mounts_since_fsck; + uint16_t num_mounts_allowed; + uint16_t ext2_signature; // 0xEF53 + uint16_t fs_state; + uint16_t when_error; + uint16_t minor_version; + uint32_t last_fsck; + uint32_t interval_fsck; + uint32_t os_id; + uint32_t major_version; + uint16_t userid_reserved_blocks; + uint16_t groupid_reserved_blocks; +} __attribute__((packed)) superblock_t; + +typedef struct ExtendedSuperblock { + uint32_t num_inodes; + uint32_t num_blocks; + uint32_t num_blocks_reserved; + uint32_t num_blocks_unallocated; + uint32_t num_inodes_unallocated; + uint32_t superblock_block_num; + uint32_t block_size; + uint32_t fragment_size; + uint32_t num_blocks_group; + uint32_t num_fragments_group; + uint32_t num_inodes_group; + uint32_t last_mount; + uint32_t last_write; + uint16_t num_mounts_since_fsck; + uint16_t num_mounts_allowed; + uint16_t ext2_signature; // 0xEF53 + uint16_t fs_state; + uint16_t when_error; + uint16_t minor_version; + uint32_t last_fsck; + uint32_t interval_fsck; + uint32_t os_id; + uint32_t major_version; + uint16_t userid_reserved_blocks; + uint16_t groupid_reserved_blocks; + uint32_t pad; + uint16_t inode_size; +} __attribute__((packed)) ext_superblock_t; + +typedef struct BlockGroupDescriptorTable { + uint32_t block_usage_bitmap; + uint32_t inode_usage_bitmap; + uint32_t starting_inode_table; + uint16_t num_unallocated_blocks_in_group; + uint16_t num_unallocated_inodes_in_group; + uint16_t num_directories_group; +} __attribute__((packed)) bgdt_t; + +typedef struct INode { + uint16_t types_permissions; + uint16_t user_id; + uint32_t low_32size; + uint32_t last_access_time; + uint32_t creation_time; + uint32_t last_modification_time; + uint32_t deletion_time; + uint16_t group_id; + uint16_t num_hard_links; + uint32_t num_disk_sectors; + uint32_t flags; + uint32_t os_specific; + uint32_t block_pointers[12]; + uint32_t single_indirect_block_pointer; + uint32_t double_indirect_block_pointer; + uint32_t triple_indirect_block_pointer; + uint32_t gen_number; + uint32_t _extended_attribute_block; + uint32_t _upper_32size; + uint32_t address_fragment; + uint32_t os_specific2; +} __attribute__((packed)) inode_t; + +// 0 Unknown type +// 1 Regular file +// 2 Directory +// 3 Character device +// 4 Block device +// 5 FIFO +// 6 Socket +// 7 Symbolic link (soft link) +#define TYPE_INDICATOR_UNKOWN 0 +#define TYPE_INDICATOR_REGULAR 1 +#define TYPE_INDICATOR_DIRECTORY 2 +#define TYPE_INDICATOR_CHARACTER_DEVICE 3 +#define TYPE_INDICATOR_BLOCK_DEVICE 4 +#define TYPE_INDICATOR_FIFO 5 +#define TYPE_INDICATOR_SOCKET 6 +#define TYPE_INDICATOR_SOFT_LINK 7 + +#define FIFO 0x1000 +#define CHARACTER_DEVICE 0x2000 +#define DIRECTORY 0x4000 +#define BLOCK_DEVICE 0x6000 +#define REGULAR_FILE 0x8000 +#define SYMBOLIC_LINK 0xA000 +#define UNIX_SOCKET 0xC000 + +typedef struct DirectoryEntryHeader { + uint32_t inode; + uint16_t size; + uint8_t name_length; + uint8_t type_indicator; +} __attribute__((packed)) direntry_header_t; + +int ext2_create_file(const char *path, int mode); +vfs_inode_t *ext2_mount(void); +void parse_superblock(void); +size_t ext2_read_file_offset(const char *file, unsigned char *data, + uint64_t size, uint64_t offset, + uint64_t *file_size); +size_t ext2_read_file(const char *file, unsigned char *data, size_t size, + uint64_t *file_size); +#endif diff --git a/fs/fifo.c b/fs/fifo.c new file mode 100644 index 0000000..d515ed7 --- /dev/null +++ b/fs/fifo.c @@ -0,0 +1,97 @@ +#include "fifo.h" +#include <errno.h> + +#define STARTING_SIZE 4096 + +void fifo_close(vfs_fd_t *fd) { + // TODO: Implement + (void)fd; + return; +} + +int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file) { + (void)offset; + file->has_data = 1; + if (file->write_len + len >= file->buffer_len) { + file->can_write = 0; + return -EAGAIN; + } + memcpy(file->buffer + file->write_len, buffer, len); + file->write_len += len; + return len; +} + +int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file) { + (void)offset; + if (file->write_len == 0) { + file->has_data = 0; + return -EAGAIN; + } + + if (len == 0) + return 0; + + file->can_write = 1; + if (len > file->write_len) + len = file->write_len; + + memcpy(buffer, file->buffer, len); + // Shift bufffer to the left + memcpy(file->buffer, file->buffer + len, file->buffer_len - len); + + file->write_len -= len; + if (file->write_len == 0) { + file->has_data = 0; + } + return len; +} + +FIFO_FILE *create_fifo_object(void) { + FIFO_FILE *n = kmalloc(sizeof(FIFO_FILE)); + n->buffer = kmalloc(STARTING_SIZE); + n->buffer_len = STARTING_SIZE; + n->write_len = 0; + return n; +} + +int create_fifo(void) { + + int fd_n = 0; + for (; get_current_task()->file_descriptors[fd_n]; fd_n++) + ; + + vfs_fd_t *fd = kmalloc(sizeof(vfs_fd_t)); + fd->flags = O_RDWR | O_NONBLOCK; + get_current_task()->file_descriptors[fd_n] = fd; + fd->inode = kmalloc(sizeof(vfs_inode_t)); + + fd->inode->internal_object = (void *)create_fifo_object(); + fd->inode->open = NULL; + fd->inode->read = fifo_read; + fd->inode->write = fifo_write; + fd->inode->close = fifo_close; + fd->inode->get_vm_object = NULL; + fd->inode->is_open = 1; + + return fd_n; +} + +int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; + int rc = fifo_object_write(buffer, offset, len, file); + fd->inode->has_data = file->has_data; + fd->inode->can_write = file->can_write; + return rc; +} + +int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + FIFO_FILE *file = (FIFO_FILE *)fd->inode->internal_object; + file->is_blocking = !(fd->flags & O_NONBLOCK); + int rc = fifo_object_read(buffer, offset, len, file); + fd->inode->has_data = file->has_data; + fd->inode->can_write = file->can_write; + return rc; +} diff --git a/fs/fifo.h b/fs/fifo.h new file mode 100644 index 0000000..ee91ba1 --- /dev/null +++ b/fs/fifo.h @@ -0,0 +1,26 @@ +#ifndef FIFO_H +#define FIFO_H +#include "vfs.h" +#include <stddef.h> +#include <stdint.h> + +typedef struct { + char *buffer; + uint64_t buffer_len; + uint64_t write_len; + uint8_t is_blocking; + uint8_t has_data; + uint8_t can_write; +} FIFO_FILE; + +int create_fifo(void); +FIFO_FILE *create_fifo_object(void); +int fifo_object_write(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file); +int fifo_object_read(uint8_t *buffer, uint64_t offset, uint64_t len, + FIFO_FILE *file); +int fifo_write(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd); +int fifo_read(uint8_t *buffer, uint64_t offset, uint64_t len, + vfs_fd_t *fd); +#endif diff --git a/fs/shm.c b/fs/shm.c new file mode 100644 index 0000000..00f8dfb --- /dev/null +++ b/fs/shm.c @@ -0,0 +1,98 @@ +#include <assert.h> +#include <errno.h> +#include <fs/shm.h> +#include <fs/vfs.h> +#include <hashmap/hashmap.h> +#include <mmu.h> +#include <sched/scheduler.h> +#include <stddef.h> + +HashMap *shared_memory_objects; + +void shm_init(void) { shared_memory_objects = hashmap_create(10); } + +int shm_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + vfs_vm_object_t *p = fd->inode->internal_object; + + if (offset > p->size) + return -EFBIG; + + if (offset + len > p->size) + len = p->size - offset; + + memcpy((void *)((uintptr_t)((uintptr_t)p->virtual_object + offset)), buffer, + len); + return len; +} + +int shm_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + vfs_vm_object_t *p = fd->inode->internal_object; + + if (offset > p->size) + return -EFBIG; + + if (offset + len > p->size) + len = p->size - offset; + + memcpy((void *)buffer, + (void *)((uintptr_t)((uintptr_t)p->virtual_object + offset)), len); + return len; +} + +vfs_vm_object_t *shm_get_vm_object(uint64_t length, uint64_t offset, + vfs_fd_t *fd) { + (void)length; + (void)offset; + vfs_vm_object_t *p = fd->inode->internal_object; + return p; +} + +int shm_open(const char *name, int oflag, mode_t mode) { + // Try to find or create a new shared memory object. + vfs_vm_object_t *internal_object = + hashmap_get_entry(shared_memory_objects, name); + if (!internal_object) { + // if (!(oflag & O_CREAT)) + // return -EMFILE; + internal_object = kmalloc(sizeof(vfs_vm_object_t)); + internal_object->object = NULL; + internal_object->size = 0; + hashmap_add_entry(shared_memory_objects, name, internal_object, NULL, 0); + } + + vfs_inode_t *inode = + vfs_create_inode(0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/, + 1 /*can_write*/, 1 /*is_open*/, internal_object, + 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + shm_read, shm_write, NULL /*close*/, shm_get_vm_object); + + vfs_fd_t *fd_ptr; + int fd = vfs_create_fd(oflag, mode, inode, &fd_ptr); + if (-1 == fd) { + kfree(inode); + return -EMFILE; + } + return fd; +} + +int shm_unlink(const char *name) { + (void)name; + return 0; +} + +int ftruncate(int fildes, uint64_t length) { + kprintf("ftruncate: %d\n", length); + vfs_fd_t *fd = get_current_task()->file_descriptors[fildes]; + if (!fd) + return -EBADF; + vfs_vm_object_t *p = fd->inode->internal_object; + p->size = length; + p->virtual_object = ksbrk(length); + int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000; + p->object = kmalloc(sizeof(void *) * n); + for (int i = 0; i < n; i++) + p->object[i] = + (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame * + 0x1000); + return 0; +} diff --git a/fs/shm.h b/fs/shm.h new file mode 100644 index 0000000..fbbdb5c --- /dev/null +++ b/fs/shm.h @@ -0,0 +1,13 @@ +#ifndef SHM_H +#define SHM_H +#include <stddef.h> +#include <stdint.h> + +typedef int mode_t; + +void shm_init(void); +int shm_open(const char *name, int oflag, mode_t mode); +int shm_unlink(const char *name); +int ftruncate(int fildes, uint64_t length); + +#endif diff --git a/fs/tmpfs.c b/fs/tmpfs.c new file mode 100644 index 0000000..2c5974b --- /dev/null +++ b/fs/tmpfs.c @@ -0,0 +1,94 @@ +#include <assert.h> +#include <errno.h> +#include <fs/fifo.h> +#include <fs/tmpfs.h> +#include <halts.h> +#include <sched/scheduler.h> +#include <stdint.h> + +void tmp_close(vfs_fd_t *fd) { + fd->inode->is_open = 0; + ((tmp_inode *)fd->inode->internal_object)->read_inode->is_open = 0; +} + +int tmp_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + tmp_inode *calling_file = fd->inode->internal_object; + tmp_inode *child_file = calling_file->read_inode->internal_object; + if (child_file->is_closed) + return -EPIPE; + + int rc = fifo_object_write(buffer, offset, len, child_file->fifo); + calling_file->read_inode->has_data = child_file->fifo->has_data; + fd->inode->can_write = child_file->fifo->can_write; + return rc; +} + +int tmp_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + tmp_inode *calling_file = fd->inode->internal_object; + tmp_inode *child_file = calling_file->read_inode->internal_object; + if (calling_file->is_closed) + return -EPIPE; + + int rc = fifo_object_read(buffer, offset, len, calling_file->fifo); + fd->inode->has_data = calling_file->fifo->has_data; + calling_file->read_inode->can_write = child_file->fifo->can_write; + return rc; +} + +void dual_pipe(int fd[2]) { + for (int i = 0; i < 2; i++) { + tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); + pipe->fifo = create_fifo_object(); + + int has_data = 0; + int can_write = 1; + int is_open = 1; + void *internal_object = pipe; + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, + internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + tmp_read, tmp_write, tmp_close, NULL /*get_vm_object*/); + assert(inode); + + vfs_fd_t *fd_ptr; + fd[i] = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd_ptr); + assert(-1 != fd[i]); + } + vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; + vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; + tmp_inode *f_pipe = f_inode->internal_object; + tmp_inode *s_pipe = s_inode->internal_object; + f_pipe->read_inode = s_inode; + s_pipe->read_inode = f_inode; + f_pipe->is_closed = 0; + s_pipe->is_closed = 0; +} + +void pipe(int fd[2]) { + for (int i = 0; i < 2; i++) { + tmp_inode *pipe = kmalloc(sizeof(tmp_inode)); + pipe->fifo = create_fifo_object(); + + int has_data = 0; + int can_write = 1; + int is_open = 1; + void *internal_object = pipe; + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, + internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, + tmp_read, tmp_write, tmp_close, NULL /*get_vm_object*/); + assert(inode); + + vfs_fd_t *fd_ptr; + fd[i] = vfs_create_fd(O_RDWR, 0, inode, &fd_ptr); + assert(-1 != fd[i]); + } + vfs_inode_t *f_inode = get_current_task()->file_descriptors[fd[0]]->inode; + vfs_inode_t *s_inode = get_current_task()->file_descriptors[fd[1]]->inode; + tmp_inode *f_pipe = f_inode->internal_object; + tmp_inode *s_pipe = s_inode->internal_object; + f_pipe->read_inode = s_inode; + s_pipe->read_inode = f_inode; + f_pipe->is_closed = 0; + s_pipe->is_closed = 0; +} diff --git a/fs/tmpfs.h b/fs/tmpfs.h new file mode 100644 index 0000000..4052bd5 --- /dev/null +++ b/fs/tmpfs.h @@ -0,0 +1,16 @@ +#ifndef TMP_H +#define TMP_H +#include <fs/fifo.h> +#include <fs/vfs.h> + +#define TMP_BUFFER_SIZE (1024 * 10) + +typedef struct { + FIFO_FILE *fifo; + uint8_t is_closed; + vfs_inode_t *read_inode; +} tmp_inode; + +void pipe(int fd[2]); +void dual_pipe(int fd[2]); +#endif diff --git a/fs/vfs.c b/fs/vfs.c new file mode 100644 index 0000000..9842e11 --- /dev/null +++ b/fs/vfs.c @@ -0,0 +1,272 @@ +#include <assert.h> +#include <errno.h> +#include <fs/vfs.h> +#include <mmu.h> +#include <poll.h> + +vfs_inode_t *root_dir; +vfs_mounts_t mounts[10]; +int num_mounts = 0; + +vfs_fd_t *get_vfs_fd(int fd) { + if (fd >= 100) { + klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); + dump_backtrace(12); + return NULL; + } + if (fd < 0) { + klog("get_vfs_fd(): Tried to get out of range fd", LOG_WARN); + dump_backtrace(12); + return NULL; + } + return get_current_task()->file_descriptors[fd]; +} + +vfs_inode_t *vfs_create_inode( + int inode_num, int type, uint8_t has_data, uint8_t can_write, + uint8_t is_open, void *internal_object, uint64_t file_size, + vfs_inode_t *(*open)(const char *path), + int (*create_file)(const char *path, int mode), + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + void (*close)(vfs_fd_t *fd), + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd)) { + vfs_inode_t *r = kmalloc(sizeof(inode_t)); + r->inode_num = inode_num; + r->type = type; + r->has_data = has_data; + r->can_write = can_write; + r->is_open = is_open; + r->internal_object = internal_object; + r->file_size = file_size; + r->open = open; + r->create_file = create_file; + r->read = read; + r->write = write; + r->close = close; + r->get_vm_object = get_vm_object; + return r; +} + +int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd) { + process_t *p = (process_t *)get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->file_descriptors[i]) + break; + if (p->file_descriptors[i]) + return -1; + vfs_fd_t *r = kmalloc(sizeof(vfs_fd_t)); + r->flags = flags; + r->mode = mode; + r->inode = inode; + r->reference_count = 1; + p->file_descriptors[i] = r; + if (fd) + *fd = r; + return i; +} + +int vfs_create_file(const char *file) { + vfs_mounts_t *file_mount = 0; + int length = 0; + for (int i = 0; i < num_mounts; i++) { + int path_len = strlen(mounts[i].path); + if (path_len <= length) + continue; + + if (isequal_n(mounts[i].path, file, path_len)) { + length = path_len; + file_mount = &mounts[i]; + } + } + if (1 != length) + file += length; + + if (!file_mount) { + kprintf("vfs_internal_open could not find mounted path for file : %s\n", + file); + return 0; + } + // ext2_create_file("/etc/oscreated", 0); + assert(file_mount->local_root->create_file); + kprintf("Creating a file\n"); + return file_mount->local_root->create_file(file, 0); +} + +vfs_inode_t *vfs_internal_open(const char *file) { + vfs_mounts_t *file_mount = 0; + int length = 0; + for (int i = 0; i < num_mounts; i++) { + int path_len = strlen(mounts[i].path); + if (path_len <= length) + continue; + + if (isequal_n(mounts[i].path, file, path_len)) { + length = path_len; + file_mount = &mounts[i]; + } + } + if (1 != length) + file += length; + + if (!file_mount) { + kprintf("vfs_internal_open could not find mounted path for file : %s\n", + file); + return NULL; + } + + vfs_inode_t *ret = file_mount->local_root->open(file); + return ret; +} + +char *vfs_clean_path(const char *path, char *resolved_path) { + // char *const clean = kmalloc(strlen(path) + 1); + char *clean = resolved_path; + int prev_slash = 0; + char *ptr = clean; + for (; *path; path++) { + if (prev_slash && '/' == *path) { + continue; + } + prev_slash = ('/' == *path); + *ptr = *path; + ptr++; + } + *ptr = '\0'; + return clean; +} + +char *vfs_resolve_path(const char *file, char *resolved_path) { + if ('/' == *file) { + return vfs_clean_path(file, resolved_path); + } + const char *cwd = get_current_task()->current_working_directory; + size_t l = strlen(cwd); + assert(l > 0); + assert('/' == cwd[l - 1]); + // char *r = kmalloc(l + strlen(file) + 1); + char r[256]; + strcpy(r, cwd); + strcat(r, file); + char *final = vfs_clean_path(r, resolved_path); + // kfree(r); + return final; +} + +int vfs_open(const char *file, int flags, int mode) { + char resolved_path[256] = {0}; + vfs_resolve_path(file, resolved_path); + vfs_inode_t *inode = vfs_internal_open(resolved_path); + if (0 == inode) { + if (mode & O_CREAT) { + if (vfs_create_file(resolved_path)) { + klog("VFS: File created", LOG_NOTE); + return vfs_open(file, flags, mode); + } + klog("VFS: Could not create file", LOG_WARN); + } + return -ENOENT; + } + if (inode->type == FS_TYPE_UNIX_SOCKET) { + return uds_open(resolved_path); + } + + return vfs_create_fd(flags, mode, inode, NULL); +} + +int vfs_close(int fd) { + vfs_fd_t *fd_ptr = get_vfs_fd(fd); + if (NULL == fd_ptr) { + return -1; + } + assert(0 < fd_ptr->reference_count); + // Remove process reference + fd_ptr->reference_count--; + get_current_task()->file_descriptors[fd] = 0; + // If no references left then free the contents + if (0 == fd_ptr->reference_count) { + if (fd_ptr->inode->close) + fd_ptr->inode->close(fd_ptr); + + kfree(fd_ptr); + } + return 0; +} + +int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, uint64_t count, + uint64_t offset) { + if (!(vfs_fd->flags & O_READ)) + return -EBADF; + return vfs_fd->inode->read(buf, offset, count, vfs_fd); +} + +int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset) { + if (fd >= 100) { + kprintf("EBADF : %x\n", fd); + return -EBADF; + } + if (fd < 0) { + dump_backtrace(12); + kprintf("EBADF : %x\n", fd); + return -EBADF; + } + vfs_fd_t *vfs_fd = get_current_task()->file_descriptors[fd]; + if (!vfs_fd) + return -EBADF; + int rc = raw_vfs_pread(vfs_fd, buf, count, offset); + if (-EAGAIN == rc && count > 0) { + if (!(vfs_fd->flags & O_NONBLOCK)) { + struct pollfd fds; + fds.fd = fd; + fds.events = POLLIN; + fds.revents = 0; + poll(&fds, 1, 0); + return vfs_pread(fd, buf, count, offset); + } + } + return rc; +} + +int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count, + uint64_t offset) { + assert(vfs_fd); + assert(vfs_fd->inode); + assert(vfs_fd->inode->write); + return vfs_fd->inode->write(buf, offset, count, vfs_fd); +} + +int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset) { + vfs_fd_t *vfs_fd = get_vfs_fd(fd); + if (!vfs_fd) + return -EBADF; + if (!(vfs_fd->flags & O_WRITE)) { + return -EBADF; + } + return raw_vfs_pwrite(vfs_fd, buf, count, offset); +} + +vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset) { + vfs_fd_t *vfs_fd = get_vfs_fd(fd); + if (!vfs_fd) + return NULL; + vfs_vm_object_t *r = vfs_fd->inode->get_vm_object(length, offset, vfs_fd); + return r; +} + +int vfs_dup2(int org_fd, int new_fd) { + get_current_task()->file_descriptors[new_fd] = + get_current_task()->file_descriptors[org_fd]; + get_current_task()->file_descriptors[new_fd]->reference_count++; + return 1; +} + +void vfs_mount(char *path, vfs_inode_t *local_root) { + int len = strlen(path); + mounts[num_mounts].path = kmalloc_eternal(len + 1); + memcpy(mounts[num_mounts].path, path, len); + mounts[num_mounts].path[len] = '\0'; + mounts[num_mounts].local_root = local_root; + num_mounts++; +} diff --git a/fs/vfs.h b/fs/vfs.h new file mode 100644 index 0000000..b3ef3e1 --- /dev/null +++ b/fs/vfs.h @@ -0,0 +1,94 @@ +typedef struct vfs_fd vfs_fd_t; +typedef struct vfs_inode vfs_inode_t; +typedef struct vfs_vm_object vfs_vm_object_t; +typedef struct vfs_mounts vfs_mounts_t; +#ifndef VFS_H +#define VFS_H +#include <limits.h> +#include <sched/scheduler.h> +#include <socket.h> +#include <stddef.h> +#include <stdint.h> + +// FIXME: Is there some standard value for this? +#define O_NONBLOCK (1 << 0) +#define O_READ (1 << 1) +#define O_WRITE (1 << 2) +#define O_CREAT (1 << 3) +#define O_RDONLY O_READ +#define O_WRONLY O_WRITE +#define O_RDWR (O_WRITE | O_READ) + +#define FS_TYPE_FILE 0 +#define FS_TYPE_UNIX_SOCKET 1 +#define FS_TYPE_CHAR_DEVICE 2 +#define FS_TYPE_BLOCK_DEVICE 3 +#define FS_TYPE_DIRECTORY 4 +#define FS_TYPE_LINK 7 + +struct vfs_vm_object { + void *virtual_object; + void **object; + uint64_t size; +}; + +struct vfs_mounts { + char *path; + vfs_inode_t *local_root; +}; + +struct dirent { + unsigned int d_ino; // File serial number. + char d_name[PATH_MAX]; // Filename string of entry. +}; + +struct vfs_fd { + size_t offset; + int flags; + int mode; + int reference_count; // Number of usages of this file descriptor, + // once it reaches zero then the contents can + // be freed. + vfs_inode_t *inode; +}; + +struct vfs_inode { + int inode_num; + int type; + uint8_t has_data; + uint8_t can_write; + uint8_t is_open; + void *internal_object; + uint64_t file_size; + vfs_inode_t *(*open)(const char *path); + int (*create_file)(const char *path, int mode); + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd); + void (*close)(vfs_fd_t *fd); + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd); +}; + +int vfs_close(int fd); +vfs_fd_t *get_vfs_fd(int fd); +int vfs_open(const char *file, int flags, int mode); +void vfs_mount(char *path, vfs_inode_t *local_root); +int vfs_pwrite(int fd, void *buf, uint64_t count, uint64_t offset); +int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, uint64_t count, + uint64_t offset); +int vfs_pread(int fd, void *buf, uint64_t count, uint64_t offset); +vfs_vm_object_t *vfs_get_vm_object(int fd, uint64_t length, uint64_t offset); +int vfs_dup2(int org_fd, int new_fd); +vfs_inode_t *vfs_internal_open(const char *file); +int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd); +vfs_inode_t *vfs_create_inode( + int inode_num, int type, uint8_t has_data, uint8_t can_write, + uint8_t is_open, void *internal_object, uint64_t file_size, + vfs_inode_t *(*open)(const char *path), + int (*create_file)(const char *path, int mode), + int (*read)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + int (*write)(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd), + void (*close)(vfs_fd_t *fd), + vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, + vfs_fd_t *fd)); +#endif @@ -0,0 +1,102 @@ +#include <assert.h> +#include <halts.h> +#include <sched/scheduler.h> + +int create_disconnect_inode_halt(vfs_inode_t *inode) { + volatile process_t *p = get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->disconnect_halt_inode[i]) + break; + + if (p->disconnect_halt_inode[i]) + return -1; + + p->disconnect_halt_inode[i] = inode; + + return i; +} + +int create_disconnect_fdhalt(vfs_fd_t *fd) { + assert(fd); + return create_disconnect_inode_halt(fd->inode); +} + +int create_read_inode_halt(vfs_inode_t *inode) { + volatile process_t *p = get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->read_halt_inode[i]) + break; + + if (p->read_halt_inode[i]) + return -1; + + p->read_halt_inode[i] = inode; + + return i; +} + +int create_read_fdhalt(vfs_fd_t *fd) { + assert(fd); + return create_read_inode_halt(fd->inode); +} + +int create_write_inode_halt(vfs_inode_t *inode) { + volatile process_t *p = get_current_task(); + int i; + for (i = 0; i < 100; i++) + if (!p->write_halt_inode[i]) + break; + + if (p->write_halt_inode[i]) + return -1; + + p->write_halt_inode[i] = inode; + + return i; +} + +int create_write_fdhalt(vfs_fd_t *fd) { + return create_write_inode_halt(fd->inode); +} + +void unset_read_fdhalt(int i) { get_current_task()->read_halt_inode[i] = NULL; } + +void unset_write_fdhalt(int i) { + get_current_task()->write_halt_inode[i] = NULL; +} + +void unset_disconnect_fdhalt(int i) { + get_current_task()->disconnect_halt_inode[i] = NULL; +} + +int isset_fdhalt(vfs_inode_t *read_halts[], vfs_inode_t *write_halts[], + vfs_inode_t *disconnect_halts[]) { + int blocked = 0; + for (int i = 0; i < 100; i++) { + if (!read_halts[i]) + continue; + if (read_halts[i]->has_data) { + return 0; + } + blocked = 1; + } + for (int i = 0; i < 100; i++) { + if (!write_halts[i]) + continue; + if (write_halts[i]->can_write) { + return 0; + } + blocked = 1; + } + for (int i = 0; i < 100; i++) { + if (!disconnect_halts[i]) + continue; + if (!disconnect_halts[i]->is_open) { + return 0; + } + blocked = 1; + } + return blocked; +} @@ -0,0 +1,21 @@ +#ifndef HALTS_H +#define HALTS_H +#include <fs/vfs.h> +#include <stdint.h> + +typedef struct { + uint8_t *ptr; + uint8_t active; +} halt_t; + +int create_read_fdhalt(vfs_fd_t *fd); +int create_read_inode_halt(vfs_inode_t *inode); +void unset_read_fdhalt(int i); +int create_write_fdhalt(vfs_fd_t *fd); +int create_write_inode_halt(vfs_inode_t *inode); +void unset_write_fdhalt(int i); +int create_disconnect_fdhalt(vfs_fd_t *fd); +void unset_disconnect_fdhalt(int i); +int isset_fdhalt(vfs_inode_t *read_halts[], vfs_inode_t *write_halts[], + vfs_inode_t *disconnect_halts[]); +#endif diff --git a/hashmap b/hashmap new file mode 160000 +Subproject 07dfe3b606e0d82b2e181b27344b5e4ce8849f3 diff --git a/includes/defs.h b/includes/defs.h new file mode 100644 index 0000000..3a373b3 --- /dev/null +++ b/includes/defs.h @@ -0,0 +1,5 @@ +#ifndef DEFS_H +#define DEFS_H +#define BYTE unsigned char +#define BYTEPTR BYTE* +#endif diff --git a/includes/mmu.h b/includes/mmu.h new file mode 100644 index 0000000..39c951b --- /dev/null +++ b/includes/mmu.h @@ -0,0 +1,61 @@ +#ifndef PAGING_H +#define PAGING_H +#include "kmalloc.h" +#include <stdint.h> + +typedef uint8_t mmu_flags; + +#define MMU_FLAG_RW (1 << 0) +#define MMU_FLAG_KERNEL (1 << 1) + +void *next_page(void *a); +void *align_page(void *a); + +typedef struct Page { + uint32_t present : 1; + uint32_t rw : 1; + uint32_t user : 1; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t unused : 7; + uint32_t frame : 20; +} __attribute__((packed)) Page; + +typedef struct PageTable { + Page pages[1024]; +} __attribute__((packed)) PageTable; + +typedef struct PageDirectory { + PageTable *tables[1024]; + uint32_t physical_tables[1024]; + uint32_t physical_address; +} PageDirectory; + +int mmu_allocate_region(void *ptr, size_t n, mmu_flags flags); +void mmu_allocate_shared_kernel_region(void *rc, size_t n); +void *mmu_find_unallocated_virtual_range(void *addr, size_t length); +void mmu_remove_virtual_physical_address_mapping(void *ptr, size_t length); +void mmu_free_address_range(void *ptr, size_t length); +void mmu_map_directories(void *dst, PageDirectory *d, void *src, + PageDirectory *s, size_t length); +uint32_t mmu_get_number_of_allocated_frames(void); +void *mmu_map_frames(void *ptr, size_t s); +void mmu_map_physical(void *dst, PageDirectory *d, void *physical, + size_t length); +void mmu_free_pages(void *a, uint32_t n); + +void flush_tlb(void); +void paging_init(void); +PageDirectory *get_active_pagedirectory(void); +void move_stack(uint32_t new_stack_address, uint32_t size); +void switch_page_directory(PageDirectory *directory); +void *allocate_frame(Page *page, int rw, int is_kernel); +PageDirectory *clone_directory(PageDirectory *original); +void *virtual_to_physical(void *address, PageDirectory *directory); +void *is_valid_userpointer(const void *const p, size_t s); +void *is_valid_user_c_string(const char *ptr, size_t *size); +void *ksbrk(size_t s); + +Page *get_page(void *ptr, PageDirectory *directory, int create_new_page, + int set_user); +#endif diff --git a/includes/sys/types.h b/includes/sys/types.h new file mode 100644 index 0000000..1ccbf63 --- /dev/null +++ b/includes/sys/types.h @@ -0,0 +1,2 @@ +typedef int time_t; +typedef int pid_t; diff --git a/init/kernel.c b/init/kernel.c new file mode 100644 index 0000000..9f507e0 --- /dev/null +++ b/init/kernel.c @@ -0,0 +1,101 @@ +#include <assert.h> +#include <cpu/gdt.h> +#include <cpu/idt.h> +#include <cpu/spinlock.h> +#include <cpu/syscall.h> +#include <crypto/SHA1/sha1.h> +#include <drivers/ata.h> +#include <drivers/keyboard.h> +#include <drivers/mouse.h> +#include <drivers/pit.h> +#include <drivers/serial.h> +#include <drivers/vbe.h> +#include <fs/devfs.h> +#include <fs/ext2.h> +#include <fs/shm.h> +#include <fs/vfs.h> +#include <log.h> +#include <mmu.h> +#include <multiboot.h> +#include <random.h> +#include <sched/scheduler.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#if defined(__linux__) +#error "You are not using a cross-compiler." +#endif + +#if !defined(__i386__) +#error "This OS needs to be compiled with a ix86-elf compiler" +#endif + +uint32_t inital_esp; +uintptr_t data_end; + +void kernel_main(uint32_t kernel_end, unsigned long magic, unsigned long addr, + uint32_t inital_stack) { + data_end = kernel_end; + inital_esp = inital_stack; + + asm("cli"); + kprintf("If you see this then the serial driver works :D.\n"); + assert(magic == MULTIBOOT_BOOTLOADER_MAGIC); + + paging_init(); + klog("Paging Initalized", LOG_SUCCESS); + multiboot_info_t *mb = + mmu_map_frames((multiboot_info_t *)addr, sizeof(multiboot_info_t)); + + gdt_init(); + klog("GDT Initalized", LOG_SUCCESS); + + idt_init(); + klog("IDT Initalized", LOG_SUCCESS); + + syscalls_init(); + klog("Syscalls Initalized", LOG_SUCCESS); + + pit_install(); + set_pit_count(2000); + klog("PIT driver installed", LOG_SUCCESS); + + ata_init(); + klog("ATA Initalized", LOG_SUCCESS); + + tasking_init(); + klog("Tasking Initalized", LOG_SUCCESS); + + install_mouse(); + klog("PS2 Mouse driver installed", LOG_SUCCESS); + + install_keyboard(); + klog("PS2 Keyboard driver installed", LOG_SUCCESS); + + vfs_mount("/", ext2_mount()); + vfs_mount("/dev", devfs_mount()); + add_stdout(); + add_serial(); + add_random_devices(); + shm_init(); + + setup_random(); + + add_keyboard(); + add_mouse(); + + display_driver_init(mb); + add_vbe_device(); + int pid; + if (0 == (pid = fork())) { + char *argv[] = {"/init", NULL}; + if (0 == exec("/init", argv)) { + kprintf("exec() failed\n"); + } + } + for (;;) + ; +} diff --git a/isodir/boot/grub/grub.cfg b/isodir/boot/grub/grub.cfg new file mode 100644 index 0000000..b2f8404 --- /dev/null +++ b/isodir/boot/grub/grub.cfg @@ -0,0 +1,3 @@ +menuentry "myos" { + multiboot /boot/myos.bin +} diff --git a/kmalloc.c b/kmalloc.c new file mode 100644 index 0000000..f3c8238 --- /dev/null +++ b/kmalloc.c @@ -0,0 +1,233 @@ +#include <assert.h> +#include <kmalloc.h> +#include <ksbrk.h> +#define NEW_ALLOC_SIZE 0x30000 + +#define IS_FREE (1 << 0) +#define IS_FINAL (1 << 1) + +typedef struct MallocHeader { + uint64_t magic; + uint32_t size; + uint8_t flags; + struct MallocHeader *n; +} MallocHeader; + +size_t max(size_t a, size_t b) { return (a > b) ? a : b; } + +size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +uint64_t delta_page(uint64_t a) { return 0x1000 - (a % 0x1000); } + +MallocHeader *head = NULL; +MallocHeader *final = NULL; +uint32_t total_heap_size = 0; + +int init_heap(void) { + head = (MallocHeader *)ksbrk(NEW_ALLOC_SIZE); + total_heap_size += NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->magic = 0xdde51ab9410268b1; + head->size = NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->flags = IS_FREE | IS_FINAL; + head->n = NULL; + final = head; + return 1; +} + +int add_heap_memory(size_t min_desired) { + min_desired += sizeof(MallocHeader) + 0x1000; + size_t allocation_size = max(min_desired, NEW_ALLOC_SIZE); + allocation_size += delta_page(allocation_size); + void *p; + if ((void *)(-1) == (p = (void *)ksbrk(allocation_size))) { + return 0; + } + total_heap_size += allocation_size - sizeof(MallocHeader); + void *e = final; + e = (void *)((uint32_t)e + final->size); + if (p == e) { + final->size += allocation_size - sizeof(MallocHeader); + return 1; + } + MallocHeader *new_entry = p; + new_entry->size = allocation_size - sizeof(MallocHeader); + new_entry->flags = IS_FREE | IS_FINAL; + new_entry->n = NULL; + new_entry->magic = 0xdde51ab9410268b1; + final->n = new_entry; + final = new_entry; + return 1; +} + +MallocHeader *next_header(MallocHeader *a) { + assert(a->magic == 0xdde51ab9410268b1); + if (a->n) { + assert(a->n->magic == 0xdde51ab9410268b1); + return a->n; + } + return NULL; +} + +MallocHeader *next_close_header(MallocHeader *a) { + if (!a) { + kprintf("next close header fail\n"); + for (;;) + ; + } + if (a->flags & IS_FINAL) + return NULL; + return next_header(a); +} + +MallocHeader *find_free_entry(uint32_t s) { + // A new header is required as well as the newly allocated chunk + s += sizeof(MallocHeader); + if (!head) + init_heap(); + MallocHeader *p = head; + for (; p; p = next_header(p)) { + assert(p->magic == 0xdde51ab9410268b1); + if (!(p->flags & IS_FREE)) + continue; + uint64_t required_size = s; + if (p->size < required_size) + continue; + return p; + } + return NULL; +} + +void merge_headers(MallocHeader *b) { + if (!(b->flags & IS_FREE)) + return; + + MallocHeader *n = next_close_header(b); + if (!n) + return; + + if (!(n->flags & IS_FREE)) + return; + + b->size += n->size; + b->flags |= n->flags & IS_FINAL; + b->n = n->n; + if (n == final) + final = b; +} + +void *kmalloc(size_t s) { + size_t n = s; + MallocHeader *free_entry = find_free_entry(s); + if (!free_entry) { + if (!add_heap_memory(s)) { + klog("Ran out of memory.", LOG_ERROR); + assert(0); + return NULL; + } + return kmalloc(s); + } + + void *rc = (void *)(free_entry + 1); + + // Create a new header + MallocHeader *new_entry = (MallocHeader *)((uintptr_t)rc + n); + new_entry->flags = free_entry->flags; + new_entry->n = free_entry->n; + new_entry->size = free_entry->size - n - sizeof(MallocHeader); + new_entry->magic = 0xdde51ab9410268b1; + + if (free_entry == final) + final = new_entry; + merge_headers(new_entry); + + // Modify the free entry + free_entry->size = n; + free_entry->flags = 0; + free_entry->n = new_entry; + free_entry->magic = 0xdde51ab9410268b1; + return rc; +} + +#define HEAP 0x00E00000 +#define PHYS 0x403000 + +void *latest = NULL; +uint64_t left = 0; + +void *kmalloc_eternal_physical_align(size_t s, void **physical) { + void *return_address = ksbrk(s); + if (physical) { + if (0 == get_active_pagedirectory()) + *physical = + (void *)((uintptr_t)return_address - (0xC0000000 + PHYS) + HEAP); + else + *physical = (void *)virtual_to_physical(return_address, 0); + } + memset(return_address, 0, 0x1000); + return return_address; +} + +void *kmalloc_eternal_align(size_t s) { + return kmalloc_eternal_physical_align(s, NULL); +} + +void *kmalloc_eternal(size_t s) { return kmalloc_eternal_align(s); } + +size_t get_mem_size(void *ptr) { + if (!ptr) + return 0; + return ((MallocHeader *)((uintptr_t)ptr - sizeof(MallocHeader)))->size; +} + +void *krealloc(void *ptr, size_t size) { + void *rc = kmalloc(size); + if (!rc) + return NULL; + if (!ptr) + return rc; + size_t l = get_mem_size(ptr); + size_t to_copy = min(l, size); + memcpy(rc, ptr, to_copy); + // kfree(ptr); + return rc; +} + +// This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX +// if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void *kreallocarray(void *ptr, size_t nmemb, size_t size) { + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && + SIZE_MAX / nmemb < size) { + return NULL; + } + + return krealloc(ptr, nmemb * size); +} + +void *kallocarray(size_t nmemb, size_t size) { + return kreallocarray(NULL, nmemb, size); +} + +void *kcalloc(size_t nelem, size_t elsize) { + void *rc = kallocarray(nelem, elsize); + if (!rc) + return NULL; + memset(rc, 0, nelem * elsize); + return rc; +} + +void kfree(void *p) { + /* +if (!p) +return; +// FIXME: This assumes that p is at the start of a allocated area. +// Could this be avoided in a simple way? +MallocHeader *h = (MallocHeader *)((uintptr_t)p - sizeof(MallocHeader)); +assert(h->magic == 0xdde51ab9410268b1); +if (h->flags & IS_FREE) +return; + +h->flags |= IS_FREE; +merge_headers(h);*/ +} diff --git a/kmalloc.h b/kmalloc.h new file mode 100644 index 0000000..69e0de3 --- /dev/null +++ b/kmalloc.h @@ -0,0 +1,21 @@ +#include <log.h> +#include <mmu.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +void kmalloc_allocate_heap(void); + +void *kmalloc_eternal(size_t size); +void *kmalloc_eternal_align(size_t size); +void *kmalloc_eternal_physical(size_t size, void **physical); +void *kmalloc_eternal_physical_align(size_t size, void **physical); + +void *kmalloc(size_t s); +void *kmalloc_align(size_t s); +void *krealloc(void *ptr, size_t size); +void *kreallocarray(void *ptr, size_t nmemb, size_t size); +void *kallocarray(size_t nmemb, size_t size); +void *kcalloc(size_t nelem, size_t elsize); +void kfree(void *p); +int init_heap(void); @@ -0,0 +1,40 @@ +#include <assert.h> +#include <ksbrk.h> +#include <mmu.h> +#include <stddef.h> +#include <stdint.h> + +/* +extern uintptr_t data_end; +extern PageDirectory *kernel_directory; + +#define HEAP 0x00E00000 +#define PHYS 0x403000 +#define PAGE_SIZE ((uintptr_t)0x1000) +void *ksbrk(size_t s) { + uintptr_t rc = (uintptr_t)align_page((void *)data_end); + data_end += s; + data_end = (uintptr_t)align_page((void *)data_end); + + if (!get_active_pagedirectory()) { + // If there is no active pagedirectory we + // just assume that the memory is + // already mapped. + return (void *)rc; + } + mmu_allocate_shared_kernel_region((void *)rc, (data_end - (uintptr_t)rc)); + assert(((uintptr_t)rc % PAGE_SIZE) == 0); + memset((void *)rc, 0xFF, s); + return (void *)rc; +} + +void *ksbrk_physical(size_t s, void **physical) { + void *r = ksbrk(s); + if (physical) { + // if (0 == get_active_pagedirectory()) + // *physical = (void *)((uintptr_t)r - (0xC0000000 + PHYS) + HEAP); + // else + *physical = (void *)virtual_to_physical(r, 0); + } + return r; +}*/ @@ -0,0 +1,8 @@ +#ifndef KSBRK_H +#define KSBRK_H +#include <stddef.h> +#include <stdint.h> + +void* ksbrk(size_t s); +void *ksbrk_physical(size_t s, void **physical); +#endif diff --git a/kubsan.c b/kubsan.c new file mode 100644 index 0000000..c81b3fc --- /dev/null +++ b/kubsan.c @@ -0,0 +1,58 @@ +#include <kubsan.h> +#include <log.h> +#include <stdio.h> + +void ubsan_log(const char *cause, struct source_location source) { + kprintf("%s: %s : %d\n", cause, source.file_name, source.line); + dump_backtrace(5); + asm("cli"); + asm volatile("1: jmp 1b"); + asm("hlt"); + for (;;) + ; +} + +void __ubsan_handle_shift_out_of_bounds(struct ShiftOutOfBoundsData *data, + unsigned long lhs, unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_shift_out_of_bounds", data->location); +} + +void __ubsan_handle_add_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_add_overflow", data->location); +} + +void __ubsan_handle_sub_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_sub_overflow", data->location); +} + +void __ubsan_handle_mul_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_mul_overflow", data->location); +} + +void __ubsan_handle_out_of_bounds(struct OutOfBoundsData *data, void *index) { + (void)index; + ubsan_log("handle_out_of_bounds", data->location); +} + +void __ubsan_handle_pointer_overflow(struct OutOfBoundsData *data, + void *index) { + (void)index; + ubsan_log("handle_pointer_overflow", data->location); +} + +void __ubsan_handle_vla_bound_not_positive(struct OutOfBoundsData *data, + void *index) { + (void)index; + ubsan_log("handle_vla_bound_not_positive", data->location); +} diff --git a/kubsan.h b/kubsan.h new file mode 100644 index 0000000..dac5407 --- /dev/null +++ b/kubsan.h @@ -0,0 +1,79 @@ +#include <stdint.h> + +enum { type_kind_int = 0, type_kind_float = 1, type_unknown = 0xffff }; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct source_location { + const char *file_name; + union { + unsigned long reported; + struct { + uint32_t line; + uint32_t column; + }; + }; +}; + +struct OverflowData { + struct source_location location; + struct type_descriptor *type; +}; + +struct type_mismatch_data { + struct source_location location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_v1 { + struct source_location location; + struct type_descriptor *type; + unsigned char log_alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_common { + struct source_location *location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct nonnull_arg_data { + struct source_location location; + struct source_location attr_location; + int arg_index; +}; + +struct OutOfBoundsData { + struct source_location location; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct ShiftOutOfBoundsData { + struct source_location location; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct unreachable_data { + struct source_location location; +}; + +struct invalid_value_data { + struct source_location location; + struct type_descriptor *type; +}; + +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; diff --git a/libc/exit/assert.c b/libc/exit/assert.c new file mode 100644 index 0000000..b48773a --- /dev/null +++ b/libc/exit/assert.c @@ -0,0 +1,12 @@ +#include <assert.h> +#include <log.h> +#include <stdio.h> +#include <log.h> + +void aFailed(char *f, int l) { + kprintf("Assert failed\n"); + kprintf("%s : %d\n", f, l); + dump_backtrace(10); + for (;;) + ; +} diff --git a/libc/include/assert.h b/libc/include/assert.h new file mode 100644 index 0000000..90a0be4 --- /dev/null +++ b/libc/include/assert.h @@ -0,0 +1,19 @@ +#include <log.h> +#include <stdio.h> + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } + +#define ASSERT_BUT_FIXME_PROPOGATE(expr) \ + { \ + if (!(expr)) \ + kprintf("Performing assert that should have been a propogated error."); \ + assert(expr); \ + } + +void aFailed(char *f, int l); +#define ASSERT_NOT_REACHED \ + { assert(0) } diff --git a/libc/include/errno.h b/libc/include/errno.h new file mode 100644 index 0000000..1ad1004 --- /dev/null +++ b/libc/include/errno.h @@ -0,0 +1,85 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. +#endif diff --git a/libc/include/limits.h b/libc/include/limits.h new file mode 100644 index 0000000..05022ec --- /dev/null +++ b/libc/include/limits.h @@ -0,0 +1 @@ +#define PATH_MAX 256 diff --git a/libc/include/stdio.h b/libc/include/stdio.h new file mode 100644 index 0000000..f2bbb32 --- /dev/null +++ b/libc/include/stdio.h @@ -0,0 +1,9 @@ +#ifndef STDIO_H +#define STDIO_H + +void putc(const char c); +int puts(char *str); +void delete_characther(void); +int kprintf(const char *format, ...); + +#endif diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/libc/include/stdlib.h diff --git a/libc/include/string.h b/libc/include/string.h new file mode 100644 index 0000000..7cee4b2 --- /dev/null +++ b/libc/include/string.h @@ -0,0 +1,19 @@ +#ifndef STRING_H +#define STRING_H +#include <stddef.h> +#include <stdint.h> + +unsigned long strlen(const char *s); +void *memcpy(void *dest, const void *src, uint32_t n); +void *memset(void *dst, const unsigned char c, uint32_t n); +int memcmp(const void *s1, const void *s2, uint32_t n); +char *strcpy(char *d, const char *s); +int strcmp(const char *s1, const char *s2); +int isequal(const char *s1, const char *s2); +int isequal_n(const char *s1, const char *s2, uint32_t n); +char *copy_and_allocate_string(const char *s); +char *copy_and_allocate_user_string(const char *s); +char *strncpy(char *dest, const char *src, size_t n); +size_t strlcpy(char *dst, const char *src, size_t dsize); +char *strcat(char *s1, const char *s2); +#endif diff --git a/libc/include/time.h b/libc/include/time.h new file mode 100644 index 0000000..4e356d1 --- /dev/null +++ b/libc/include/time.h @@ -0,0 +1,6 @@ +#include <types.h> + +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; diff --git a/libc/include/types.h b/libc/include/types.h new file mode 100644 index 0000000..ffcf281 --- /dev/null +++ b/libc/include/types.h @@ -0,0 +1,27 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +#endif diff --git a/libc/stdio/print.c b/libc/stdio/print.c new file mode 100644 index 0000000..8174983 --- /dev/null +++ b/libc/stdio/print.c @@ -0,0 +1,97 @@ +#include "../../drivers/serial.h" +#include "../include/assert.h" +#include "../include/stdio.h" +#include <stdarg.h> + +#define TAB_SIZE 8 + +const char HEX_SET[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +inline void putc(const char c) { write_serial(c); } + +int kprint_hex(uint64_t num) { + int c = 2; + + if (num == 0) { + putc('0'); + c++; + return c; + } + + char str[16] = {0}; + int i = 0; + for (; num != 0 && i < 16; i++, num /= 16) + str[i] = HEX_SET[(num % 16)]; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + + return c; +} + +int kprint_int(int num) { + int c = 0; + if (0 == num) { + putc('0'); + c++; + return c; + } + char str[10]; + int i = 0; + for (; num != 0 && i < 10; i++, num /= 10) + str[i] = (num % 10) + '0'; + + c += i; + for (i--; i >= 0; i--) + putc(str[i]); + return c; +} + +int kprintf(const char *format, ...) { + int c = 0; + va_list list; + va_start(list, format); + + const char *s = format; + for (; *s; s++) { + if ('%' != *s) { + putc(*s); + c++; + continue; + } + + char flag = *(s + 1); + if ('\0' == flag) + break; + + switch (flag) { + case 'c': + putc((char)va_arg(list, int)); + c++; + break; + case 'd': + c += kprint_int(va_arg(list, int)); + break; + case 's': + for (char *string = va_arg(list, char *); *string; putc(*string++), c++) + ; + break; + case 'x': + c += kprint_hex(va_arg(list, const uint32_t)); + break; + case '%': + putc('%'); + c++; + break; + default: + ASSERT_NOT_REACHED; + break; + } + s++; + } + return c; +} + +int puts(char *str) { return kprintf("%s\n", str); } diff --git a/libc/string/copy.c b/libc/string/copy.c new file mode 100644 index 0000000..277c808 --- /dev/null +++ b/libc/string/copy.c @@ -0,0 +1,26 @@ +#include <assert.h> +#include <kmalloc.h> +#include <stddef.h> +#include <string.h> + +char *copy_and_allocate_string(const char *s) { + size_t l = strlen(s); + char *r = kmalloc(l + 1); + if (!r) + return NULL; + return strncpy(r, s, l); +} + +char *copy_and_allocate_user_string(const char *s) { + size_t len; + if (!is_valid_user_c_string(s, &len)) + return NULL; + size_t real_len = strlen(s); + assert(real_len == len); + len = real_len; + char *r = kmalloc(len + 1); + if (!r) + return NULL; + strlcpy(r, s, len); + return r; +} diff --git a/libc/string/isequal.c b/libc/string/isequal.c new file mode 100644 index 0000000..cdbd3cc --- /dev/null +++ b/libc/string/isequal.c @@ -0,0 +1,15 @@ +#include "../include/string.h" + +int isequal(const char *s1, const char *s2) { + for(;*s1;s1++,s2++) + if(*s1 != *s2) + return 0; + return 1; +} + +int isequal_n(const char *s1, const char *s2, uint32_t n) { + for(;*s1 && n;s1++,s2++,n--) + if(*s1 != *s2) + return 0; + return 1; +} diff --git a/libc/string/memcmp.c b/libc/string/memcmp.c new file mode 100644 index 0000000..72c680a --- /dev/null +++ b/libc/string/memcmp.c @@ -0,0 +1,12 @@ +#include "../include/string.h" + +int memcmp(const void *s1, const void *s2, uint32_t n) +{ + int return_value = 0; + + for(uint32_t i = 0;i < n;i++) + if(((unsigned char *)(s1))[i] != ((unsigned char *)(s2))[i]) + return_value++; + + return return_value; +} diff --git a/libc/string/memcpy.c b/libc/string/memcpy.c new file mode 100644 index 0000000..70a60c1 --- /dev/null +++ b/libc/string/memcpy.c @@ -0,0 +1,11 @@ +#include "../include/string.h" + +void *__attribute__((optimize("O0"))) +memcpy(void *dest, const void *src, uint32_t n) { + unsigned char *d = dest; + const unsigned char *s = src; + // for(;n--;) *d++ = *s++; + for (; n; n--) + *d++ = *s++; + return dest; +} diff --git a/libc/string/memset.c b/libc/string/memset.c new file mode 100644 index 0000000..a446eb4 --- /dev/null +++ b/libc/string/memset.c @@ -0,0 +1,9 @@ +#include <string.h> + +void *memset(void *dst, const unsigned char c, uint32_t n) { + uintptr_t d = (uintptr_t)dst; + for (uint32_t i = 0; i < n; i++, d++) + *(unsigned char *)d = c; + + return (void *)d; +} diff --git a/libc/string/strcat.c b/libc/string/strcat.c new file mode 100644 index 0000000..78a9ec6 --- /dev/null +++ b/libc/string/strcat.c @@ -0,0 +1,6 @@ +#include <string.h> + +char *strcat(char *s1, const char *s2) { + strcpy(s1 + strlen(s1), s2); + return s1; +} diff --git a/libc/string/strcmp.c b/libc/string/strcmp.c new file mode 100644 index 0000000..d7039e2 --- /dev/null +++ b/libc/string/strcmp.c @@ -0,0 +1,8 @@ +#include "../include/string.h" + +int strcmp(const char *s1, const char *s2) +{ + for(;*s1 == *s2 && *s1; s1++, s2++) + ; + return *s1 - *s2; +} diff --git a/libc/string/strcpy.c b/libc/string/strcpy.c new file mode 100644 index 0000000..fa1e336 --- /dev/null +++ b/libc/string/strcpy.c @@ -0,0 +1,8 @@ +#include <string.h> + +char *strcpy(char *d, const char *s) { + char *s1 = d; + for (; (*d++ = *s++);) + ; + return s1; +} diff --git a/libc/string/strlcpy.c b/libc/string/strlcpy.c new file mode 100644 index 0000000..43d0e58 --- /dev/null +++ b/libc/string/strlcpy.c @@ -0,0 +1,21 @@ +#include <stddef.h> +#include <string.h> + +// Copy string src to buffer dst of size dsize. At most dsize-1 +// chars will be copied. Always NUL terminates (unless dsize == 0). +// Returns strlen(src); if retval >= dsize, truncation occurred. +size_t strlcpy(char *dst, const char *src, size_t dsize) { + size_t n = dsize; + const char *osrc = src; + for (; n; n--) { + if ((*dst++ = *src++) == '\0') + break; + } + if (n == 0) { + if (dsize != 0) + *dst = '\0'; /* NUL-terminate dst */ + while (*src++) + ; + } + return src - osrc - 1; +} diff --git a/libc/string/strlen.c b/libc/string/strlen.c new file mode 100644 index 0000000..4346383 --- /dev/null +++ b/libc/string/strlen.c @@ -0,0 +1,8 @@ +#include "../include/string.h" + +unsigned long strlen(const char *s) +{ + const char * tmp = s; + for(;*tmp++;); + return (tmp - s)-1; +} diff --git a/libc/string/strncpy.c b/libc/string/strncpy.c new file mode 100644 index 0000000..a886895 --- /dev/null +++ b/libc/string/strncpy.c @@ -0,0 +1,11 @@ +#include <stddef.h> +#include <string.h> + +// FIXME: Something is weird with this function +char *strncpy(char *dest, const char *src, size_t n) { + char *r = dest; + for (; n && (*dest = *src); n--, src++, dest++) + ; + *dest = '\0'; + return r; +} diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..59b150d --- /dev/null +++ b/linker.ld @@ -0,0 +1,41 @@ +ENTRY (_start) + +SECTIONS +{ + . = 0x00100000; + /* The kernel will live at 3GB + 1MB in the virtual address space, */ + /* which will be mapped to 1MB in the physical address space. */ + /* Note that we page-align the sections. */ + + _kernel_start = .; + .multiboot.data : { + *(.multiboot.data) + } + + .multiboot.text : { + *(.multiboot.text) + } + + . += 0xC0000000; + /* Add a symbol that indicates the start address of the kernel. */ + .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000) + { + *(.text) + } + .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000) + { + *(.rodata) + } + .data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000) + { + *(.data) + } + .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + /* Add a symbol that indicates the end address of the kernel. */ + _kernel_end = .; +} @@ -0,0 +1,40 @@ +#include "log.h" +#include <sched/scheduler.h> + +struct stackframe { + struct stackframe *ebp; + uint32_t eip; +}; + +void dump_backtrace(uint32_t max_frames) { + struct stackframe *stk; + asm("mov %%ebp,%0" : "=r"(stk)::); + kprintf("Stack trace:\n"); + for (uint32_t frame = 0; stk && frame < max_frames; ++frame) { + kprintf(" 0x%x\n", stk->eip); + stk = stk->ebp; + } + if (get_current_task()) { + kprintf(" PID: %x\n", get_current_task()->pid); + } +} + +void klog(char *str, int code) { + switch (code) { + case LOG_NOTE: + kprintf("[NOTE] "); + break; + case LOG_WARN: + kprintf("[WARN] "); + break; + case LOG_ERROR: + kprintf("[ERROR] "); + break; + default: + case LOG_SUCCESS: + kprintf("[SUCCESS] "); + break; + } + + puts(str); +} @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <stdint.h> + +#define LOG_NOTE 3 +#define LOG_WARN 2 +#define LOG_ERROR 1 +#define LOG_SUCCESS 0 + +void klog(char *str, int code); +void dump_backtrace(uint32_t max_frames); diff --git a/mount/cat b/mount/cat new file mode 120000 index 0000000..a24e907 --- /dev/null +++ b/mount/cat @@ -0,0 +1 @@ +./minibox
\ No newline at end of file diff --git a/mount/init b/mount/init new file mode 120000 index 0000000..a24e907 --- /dev/null +++ b/mount/init @@ -0,0 +1 @@ +./minibox
\ No newline at end of file diff --git a/mount/pid1 b/mount/pid1 Binary files differnew file mode 100755 index 0000000..773d54c --- /dev/null +++ b/mount/pid1 diff --git a/mount/program b/mount/program Binary files differnew file mode 100755 index 0000000..c93d7ba --- /dev/null +++ b/mount/program diff --git a/mount/sh b/mount/sh Binary files differnew file mode 100755 index 0000000..c05684c --- /dev/null +++ b/mount/sh diff --git a/multiboot.h b/multiboot.h new file mode 100644 index 0000000..ecbb6a0 --- /dev/null +++ b/multiboot.h @@ -0,0 +1,243 @@ +#include <stdint.h> +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the ’flags’ member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef uint8_t multiboot_uint8_t; +typedef uint16_t multiboot_uint16_t; +typedef uint32_t multiboot_uint32_t; +typedef uint64_t multiboot_uint64_t; + +struct multiboot_header { + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table { + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table { + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table + multiboot_elf_section_header_table_t; + +struct multiboot_info { + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union { + struct { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color { + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry { + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list { + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info { + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ @@ -0,0 +1,3 @@ +#!/bin/sh +cp new_ext2.img ext2.img +./sync.sh @@ -0,0 +1,54 @@ +#include <fs/vfs.h> +#include <halts.h> +#include <poll.h> +#include <sched/scheduler.h> + +int poll(struct pollfd *fds, size_t nfds, int timeout) { + (void)timeout; + int read_locks[nfds]; + int write_locks[nfds]; + int disconnect_locks[nfds]; + for (size_t i = 0; i < nfds; i++) { + if (fds[i].fd < 0) + continue; + vfs_fd_t *f = get_vfs_fd(fds[i].fd); + if (fds[i].events & POLLIN) + read_locks[i] = create_read_fdhalt(f); + if (fds[i].events & POLLOUT) + write_locks[i] = create_write_fdhalt(f); + if (fds[i].events & POLLHUP) + disconnect_locks[i] = create_disconnect_fdhalt(f); + } + + switch_task(); + + for (size_t i = 0; i < nfds; i++) { + if (fds[i].fd < 0) + continue; + if (fds[i].events & POLLIN) + unset_read_fdhalt(read_locks[i]); + if (fds[i].events & POLLOUT) + unset_write_fdhalt(write_locks[i]); + if (fds[i].events & POLLHUP) + unset_disconnect_fdhalt(disconnect_locks[i]); + } + for (size_t i = 0; i < nfds; i++) { + if (0 > fds[i].fd) { + fds[i].revents = 0; + continue; + } + vfs_fd_t *f = get_vfs_fd(fds[i].fd); + if (!f) { + if (fds[i].events & POLLHUP) + fds[i].revents |= POLLHUP; + } else { + if (f->inode->has_data && fds[i].events & POLLIN) + fds[i].revents |= POLLIN; + if (f->inode->can_write && fds[i].events & POLLOUT) + fds[i].revents |= POLLOUT; + if (!(f->inode->is_open) && fds[i].events & POLLHUP) + fds[i].revents |= POLLHUP; + } + } + return 0; +} @@ -0,0 +1,15 @@ +#include <stdint.h> +#include <stddef.h> + +#define POLLIN (1 << 0) +#define POLLPRI (1 << 1) +#define POLLOUT (1 << 2) +#define POLLHUP (1 << 3) + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll(struct pollfd *fds, size_t nfds, int timeout); diff --git a/process.s b/process.s new file mode 100644 index 0000000..24e1869 --- /dev/null +++ b/process.s @@ -0,0 +1,33 @@ +.intel_syntax noprefix +.global copy_page_physical +.global loop_m +copy_page_physical: + push ebx + pushf + + cli + + mov ebx, [esp+12] + mov ecx, [esp+16] + + mov edx, cr0 + and edx, 0x7fffffff + mov cr0, edx + + mov edx, 1024 + +.loop: + mov eax, [ebx] + mov [ecx], eax + add ebx, 4 + add ecx, 4 + dec edx + jnz .loop + + mov edx, cr0 + or edx, 0x80000000 + mov cr0, edx + + popf + pop ebx + ret diff --git a/random.c b/random.c new file mode 100644 index 0000000..0e1b760 --- /dev/null +++ b/random.c @@ -0,0 +1,142 @@ +// FIXME: This is mostlikely incredibly inefficent and insecure. +#include <crypto/ChaCha20/chacha20.h> +#include <crypto/SHA1/sha1.h> +#include <fs/devfs.h> +#include <fs/vfs.h> +#include <random.h> +#include <stddef.h> +#include <string.h> + +#define HASH_CTX SHA1_CTX +#define HASH_LEN SHA1_LEN + +uint32_t internal_chacha_block[16] = { + // Constant ascii values of "expand 32-byte k" + 0x61707865, + 0x3320646e, + 0x79622d32, + 0x6b206574, + // The unique key + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + // Block counter + 0x00000000, + // Nonce + 0x00000000, + 0x00000000, +}; + +void mix_chacha(void) { + uint8_t rand_data[BLOCK_SIZE]; + get_random((BYTEPTR)rand_data, BLOCK_SIZE); + memcpy(internal_chacha_block + KEY, rand_data, KEY_SIZE); + memcpy(internal_chacha_block + NONCE, rand_data + KEY_SIZE, NONCE_SIZE); + internal_chacha_block[COUNT] = 0; +} + +void get_random(BYTEPTR buffer, uint64_t len) { + uint8_t rand_data[BLOCK_SIZE]; + for (; len > 0;) { + if (COUNT_MAX - 1 == internal_chacha_block[COUNT]) { + // The current block has used up all the 2^32 counts. If the + // key and/or the nonce are not changed and the count + // overflows back to zero then the random values would + // repeate. This is of course not desiered behaviour. The + // solution is to create a new nonce and key using the + // already established chacha block. + internal_chacha_block[COUNT]++; + mix_chacha(); + } + uint32_t read_len = (BLOCK_SIZE < len) ? (BLOCK_SIZE) : len; + chacha_block((uint32_t *)rand_data, internal_chacha_block); + internal_chacha_block[COUNT]++; + memcpy(buffer, rand_data, read_len); + buffer += read_len; + len -= read_len; + } +} + +HASH_CTX hash_pool; +uint32_t hash_pool_size = 0; + +void add_hash_pool(void) { + uint8_t new_chacha_key[KEY_SIZE]; + get_random(new_chacha_key, KEY_SIZE); + + uint8_t hash_buffer[HASH_LEN]; + SHA1_Final(&hash_pool, hash_buffer); + for (size_t i = 0; i < HASH_LEN; i++) + new_chacha_key[i % KEY_SIZE] ^= hash_buffer[i]; + + SHA1_Init(&hash_pool); + SHA1_Update(&hash_pool, hash_buffer, HASH_LEN); + + uint8_t block[BLOCK_SIZE]; + get_random(block, BLOCK_SIZE); + SHA1_Update(&hash_pool, block, BLOCK_SIZE); + + memcpy(internal_chacha_block + KEY, new_chacha_key, KEY_SIZE); + + mix_chacha(); +} + +void add_entropy(uint8_t *buffer, size_t size) { + SHA1_Update(&hash_pool, buffer, size); + hash_pool_size += size; + if (hash_pool_size >= HASH_LEN * 2) + add_hash_pool(); +} + +void setup_random(void) { + SHA1_Init(&hash_pool); + + BYTE seed[1024]; + int rand_fd = vfs_open("/etc/seed", O_RDWR, 0); + if (0 > rand_fd) { + klog("/etc/seed not found", LOG_WARN); + return; + } + + size_t offset = 0; + for (int rc; (rc = vfs_pread(rand_fd, seed, 1024, offset)); offset += rc) { + if (0 > rc) { + klog("/etc/seed read error", LOG_WARN); + break; + } + add_entropy(seed, rc); + } + add_hash_pool(); + + // Update the /etc/seed file to ensure we get a new state upon next + // boot. + get_random(seed, 1024); + vfs_pwrite(rand_fd, seed, 1024, 0); + vfs_close(rand_fd); +} + +int random_write(BYTEPTR buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + add_entropy(buffer, len); + return len; // add_entropy() never fails to recieve (len) amount of data. +} + +int random_read(BYTEPTR buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + get_random(buffer, len); + return len; // get_random() never fails to give "len" amount of data. +} + +void add_random_devices(void) { + devfs_add_file("/random", random_read, random_write, NULL, 1, 1, + FS_TYPE_CHAR_DEVICE); + devfs_add_file("/urandom", random_read, random_write, NULL, 1, 1, + FS_TYPE_CHAR_DEVICE); +} diff --git a/random.h b/random.h new file mode 100644 index 0000000..437927f --- /dev/null +++ b/random.h @@ -0,0 +1,7 @@ +#include <stdint.h> +#include <fs/vfs.h> +#include <defs.h> + +void setup_random(void); +void add_random_devices(void); +void get_random(uint8_t* buffer, uint64_t len); diff --git a/read_eip.s b/read_eip.s new file mode 100644 index 0000000..6041db0 --- /dev/null +++ b/read_eip.s @@ -0,0 +1,5 @@ +.intel_syntax noprefix +.global read_eip +read_eip: + pop eax + jmp eax diff --git a/scalls/accept.c b/scalls/accept.c new file mode 100644 index 0000000..3c3f5ad --- /dev/null +++ b/scalls/accept.c @@ -0,0 +1,5 @@ +#include "accept.h" + +int syscall_accept(SYS_ACCEPT_PARAMS *args) { + return accept(args->socket, args->address, args->address_len); +} diff --git a/scalls/accept.h b/scalls/accept.h new file mode 100644 index 0000000..d022999 --- /dev/null +++ b/scalls/accept.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +int syscall_accept(SYS_ACCEPT_PARAMS *args); diff --git a/scalls/bind.c b/scalls/bind.c new file mode 100644 index 0000000..76e36ab --- /dev/null +++ b/scalls/bind.c @@ -0,0 +1,5 @@ +#include "bind.h" + +int syscall_bind(SYS_BIND_PARAMS *args) { + return bind(args->sockfd, args->addr, args->addrlen); +} diff --git a/scalls/bind.h b/scalls/bind.h new file mode 100644 index 0000000..5661ad0 --- /dev/null +++ b/scalls/bind.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +int syscall_bind(SYS_BIND_PARAMS *args); diff --git a/scalls/clock_gettime.c b/scalls/clock_gettime.c new file mode 100644 index 0000000..632ea08 --- /dev/null +++ b/scalls/clock_gettime.c @@ -0,0 +1,10 @@ +#include <scalls/clock_gettime.h> + +int syscall_clock_gettime(SYS_CLOCK_GETTIME_PARAMS *args) { + // FIXME: Actually implement this + if (args->ts) { + args->ts->tv_sec = 0; + args->ts->tv_nsec = 0; + } + return 0; +} diff --git a/scalls/clock_gettime.h b/scalls/clock_gettime.h new file mode 100644 index 0000000..145aa24 --- /dev/null +++ b/scalls/clock_gettime.h @@ -0,0 +1,8 @@ +#include <time.h> + +typedef struct SYS_CLOCK_GETTIME_PARAMS { + clockid_t clk; + struct timespec *ts; +} __attribute__((packed)) SYS_CLOCK_GETTIME_PARAMS; + +int syscall_clock_gettime(SYS_CLOCK_GETTIME_PARAMS *args); diff --git a/scalls/mmap.c b/scalls/mmap.c new file mode 100644 index 0000000..83fff6a --- /dev/null +++ b/scalls/mmap.c @@ -0,0 +1,7 @@ +#include <scalls/mmap.h> +#include <sched/scheduler.h> + +void *syscall_mmap(SYS_MMAP_PARAMS *args) { + return mmap(args->addr, args->length, args->prot, args->flags, args->fd, + args->offset); +} diff --git a/scalls/mmap.h b/scalls/mmap.h new file mode 100644 index 0000000..f5e121e --- /dev/null +++ b/scalls/mmap.h @@ -0,0 +1,13 @@ +#include <stddef.h> +#include <stdint.h> + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +void *syscall_mmap(SYS_MMAP_PARAMS *args); diff --git a/scalls/msleep.c b/scalls/msleep.c new file mode 100644 index 0000000..0120f08 --- /dev/null +++ b/scalls/msleep.c @@ -0,0 +1,9 @@ +#include <drivers/pit.h> +#include <scalls/msleep.h> +#include <sched/scheduler.h> +#include <stdio.h> + +void syscall_msleep(uint32_t ms) { + get_current_task()->sleep_until = pit_num_ms() + ms; + switch_task(); +} diff --git a/scalls/msleep.h b/scalls/msleep.h new file mode 100644 index 0000000..71bf269 --- /dev/null +++ b/scalls/msleep.h @@ -0,0 +1,5 @@ +#ifndef MSLEEP_H +#define MSLEEP_H +#include <stdint.h> +void syscall_msleep(uint32_t ms); +#endif diff --git a/scalls/ppoll.c b/scalls/ppoll.c new file mode 100644 index 0000000..8feb35c --- /dev/null +++ b/scalls/ppoll.c @@ -0,0 +1,11 @@ +#include <scalls/ppoll.h> +#include <fs/vfs.h> +#include <poll.h> +#include <sched/scheduler.h> + +int syscall_poll(SYS_POLL_PARAMS *args) { + struct pollfd *fds = args->fds; + size_t nfds = args->nfds; + int timeout = args->timeout; + return poll(fds, nfds, timeout); +} diff --git a/scalls/ppoll.h b/scalls/ppoll.h new file mode 100644 index 0000000..13700b5 --- /dev/null +++ b/scalls/ppoll.h @@ -0,0 +1,9 @@ +#include <stddef.h> + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +int syscall_poll(SYS_POLL_PARAMS *args); diff --git a/scalls/shm.c b/scalls/shm.c new file mode 100644 index 0000000..2e8924f --- /dev/null +++ b/scalls/shm.c @@ -0,0 +1,10 @@ +#include "shm.h" +#include "../fs/shm.h" + +int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args) { + return shm_open(args->name, args->oflag, args->mode); +} + +int syscall_ftruncate(SYS_FTRUNCATE_PARAMS *args) { + return ftruncate(args->fildes, args->length); +} diff --git a/scalls/shm.h b/scalls/shm.h new file mode 100644 index 0000000..6d4e13e --- /dev/null +++ b/scalls/shm.h @@ -0,0 +1,20 @@ +#ifndef SYS_SHM_H +#define SYS_SHM_H +#include <stddef.h> +#include <stdint.h> +typedef int mode_t; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +typedef struct SYS_FTRUNCATE_PARAMS { + int fildes; + uint64_t length; +} __attribute__((packed)) SYS_FTRUNCATE_PARAMS; + +int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args); +int syscall_ftruncate(SYS_FTRUNCATE_PARAMS *args); +#endif diff --git a/scalls/socket.c b/scalls/socket.c new file mode 100644 index 0000000..594c745 --- /dev/null +++ b/scalls/socket.c @@ -0,0 +1,5 @@ +#include "socket.h" + +int syscall_socket(SYS_SOCKET_PARAMS *args) { + return socket(args->domain, args->type, args->protocol); +} diff --git a/scalls/socket.h b/scalls/socket.h new file mode 100644 index 0000000..6540b0f --- /dev/null +++ b/scalls/socket.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +int syscall_socket(SYS_SOCKET_PARAMS *args); diff --git a/scalls/stat.c b/scalls/stat.c new file mode 100644 index 0000000..0850151 --- /dev/null +++ b/scalls/stat.c @@ -0,0 +1,13 @@ +#include <errno.h> +#include <fs/vfs.h> +#include <scalls/stat.h> + +int syscall_stat(SYS_STAT_PARAMS *args) { + const char *pathname = copy_and_allocate_user_string(args->pathname); + struct stat *statbuf = args->statbuf; + vfs_inode_t *i = vfs_internal_open(pathname); + if (!i) + return -ENOENT; + statbuf->st_size = i->file_size; + return 0; +} diff --git a/scalls/stat.h b/scalls/stat.h new file mode 100644 index 0000000..78e8c45 --- /dev/null +++ b/scalls/stat.h @@ -0,0 +1,33 @@ +#include <types.h> +#include <time.h> + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atim; // Last data access timestamp. + struct timespec st_mtim; // Last data modification timestamp. + struct timespec st_ctim; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; + +int syscall_stat(SYS_STAT_PARAMS *args); diff --git a/scalls/uptime.c b/scalls/uptime.c new file mode 100644 index 0000000..866c7e5 --- /dev/null +++ b/scalls/uptime.c @@ -0,0 +1,4 @@ +#include <scalls/uptime.h> +#include <drivers/pit.h> + +uint32_t syscall_uptime(void) { return (uint32_t)pit_num_ms(); } diff --git a/scalls/uptime.h b/scalls/uptime.h new file mode 100644 index 0000000..2b5b0c9 --- /dev/null +++ b/scalls/uptime.h @@ -0,0 +1,2 @@ +#include <stdint.h> +uint32_t syscall_uptime(void); diff --git a/sched/scheduler.c b/sched/scheduler.c new file mode 100644 index 0000000..2959693 --- /dev/null +++ b/sched/scheduler.c @@ -0,0 +1,388 @@ +#include <assert.h> +#include <cpu/io.h> +#include <defs.h> +#include <drivers/pit.h> +#include <elf.h> +#include <errno.h> +#include <fs/vfs.h> + +#define STACK_LOCATION ((void *)0x90000000) +#define STACK_SIZE 0x80000 +#define HEAP_SIZE 0x400000 +#define HEAP_LOCATION (STACK_LOCATION - STACK_SIZE - HEAP_SIZE) + +process_t *ready_queue; +process_t *current_task = NULL; +uint32_t next_pid = 0; + +extern uint32_t read_eip(void); + +process_t *get_current_task(void) { return current_task; } + +process_t *create_process(process_t *p) { + process_t *r; + r = ksbrk(sizeof(process_t)); + r->dead = 0; + r->pid = next_pid++; + r->esp = r->ebp = 0; + r->eip = 0; + r->sleep_until = 0; + if (!p) { + assert(1 == next_pid); + strncpy(r->program_name, "[kernel]", sizeof(current_task->program_name)); + } else + strncpy(r->program_name, "[Not yet named]", + sizeof(current_task->program_name)); + + r->cr3 = (p) ? clone_directory(get_active_pagedirectory()) + : get_active_pagedirectory(); + r->next = 0; + r->parent = p; + r->child = NULL; + r->halt_list = NULL; + strcpy(r->current_working_directory, "/"); + r->data_segment_end = (p) ? p->data_segment_end : NULL; + memset((void *)r->halts, 0, 2 * sizeof(uint32_t)); + for (int i = 0; i < 100; i++) { + if (p) { + r->file_descriptors[i] = p->file_descriptors[i]; + if (r->file_descriptors[i]) { + r->file_descriptors[i]->reference_count++; + } + } + r->read_halt_inode[i] = NULL; + r->write_halt_inode[i] = NULL; + r->disconnect_halt_inode[i] = NULL; + r->maps[i] = NULL; + } + return r; +} + +int get_free_fd(process_t *p, int allocate) { + if (!p) + p = (process_t *)current_task; + int i; + for (i = 0; i < 100; i++) + if (!p->file_descriptors[i]) + break; + if (p->file_descriptors[i]) + return -1; + if (allocate) { + vfs_fd_t *fd = p->file_descriptors[i] = kmalloc(sizeof(vfs_fd_t)); + fd->inode = kmalloc(sizeof(vfs_inode_t)); + } + return i; +} + +void tasking_init(void) { current_task = ready_queue = create_process(NULL); } + +int i = 0; +void __attribute__((optimize("O0"))) free_process(void) { + kprintf("Exiting process: %s\n", get_current_task()->program_name); + // free_process() will purge all contents such as allocated frames + // out of the current process. This will be called by exit() and + // exec*(). + + // Do a special free for shared memory which avoids labeling + // underlying frames as "unused". + for (int i = 0; i < 100; i++) { + vfs_close(i); + if (!current_task->maps[i]) + continue; + MemoryMap *m = current_task->maps[i]; + mmu_remove_virtual_physical_address_mapping(m->u_address, 0x1000); + } + + // NOTE: Kernel stuff begins at 0x90000000 + mmu_free_address_range((void *)0x1000, 0x90000000); +} + +void exit(int status) { + assert(current_task->pid != 1); + if (current_task->parent) { + current_task->parent->halts[WAIT_CHILD_HALT] = 0; + current_task->parent->child_rc = status; + } + process_t *new_task = current_task; + for (; new_task == current_task;) { + if (!new_task->next) + new_task = ready_queue; + new_task = new_task->next; + } + + free_process(); + // Remove current_task from list + for (process_t *tmp = ready_queue; tmp;) { + if (tmp == current_task) // current_task is ready_queue(TODO: + // Figure out whether this could even + // happen) + { + ready_queue = current_task->next; + break; + } + if (tmp->next == current_task) { + tmp->next = tmp->next->next; + break; + } + tmp = tmp->next; + } + current_task->dead = 1; + // This function will enable interrupts + switch_task(); +} + +uint32_t setup_stack(uint32_t stack_pointer, int argc, char **argv) { + mmu_allocate_region(STACK_LOCATION - STACK_SIZE, STACK_SIZE, MMU_FLAG_RW); + flush_tlb(); + + uint32_t ptr = stack_pointer; + + char *argv_ptrs[argc + 1]; + for (int i = 0; i < argc; i++) { + char *s = argv[i]; + size_t l = strlen(s); + ptr -= l + 1; + char *b = (char *)ptr; + memcpy(b, s, l); + b[l] = '\0'; + argv_ptrs[i] = b; + } + + char **ptrs[argc + 1]; + for (int i = argc; i >= 0; i--) { + ptr -= sizeof(char *); + ptrs[i] = (char **)ptr; + if (i != argc) { + *(ptrs[i]) = argv_ptrs[i]; + } else { + *(ptrs[i]) = NULL; + } + } + + char *s = (char *)ptr; + ptr -= sizeof(char **); + *(char ***)ptr = (char **)s; + + ptr -= sizeof(int); + *(int *)ptr = argc; + return ptr; +} + +int exec(const char *filename, char **argv) { + // exec() will "takeover" the process by loading the file specified in + // filename into memory, change from ring 0 to ring 3 and jump to the + // files entry point as decided by the ELF header of the file. + int argc = 0; + for (; argv[argc];) { + argc++; + } + + uint32_t end_of_code; + void *entry = load_elf_file(filename, &end_of_code); + if (!entry) { + return 0; + } + + strncpy(current_task->program_name, filename, + sizeof(current_task->program_name)); + + current_task->data_segment_end = align_page((void *)end_of_code); + + uint32_t ptr = setup_stack(0x90000000, argc, argv); + + jump_usermode((void (*)())(entry), ptr); + ASSERT_NOT_REACHED; + return 0; +} + +int __attribute__((optimize("O0"))) fork(void) { + process_t *parent_task = (process_t *)current_task; + + process_t *new_task = create_process(parent_task); + + process_t *tmp_task = (process_t *)ready_queue; + for (; tmp_task->next;) + tmp_task = tmp_task->next; + + tmp_task->next = new_task; + + uint32_t eip = read_eip(); + + if (current_task != parent_task) { + return 0; + } + + new_task->child_rc = -1; + new_task->parent = current_task; + current_task->child = new_task; + + new_task->eip = eip; + asm("\ + mov %%esp, %0;\ + mov %%ebp, %1;" + : "=r"(new_task->esp), "=r"(new_task->ebp)); + asm("sti"); + return new_task->pid; +} + +int is_halted(process_t *process) { + for (int i = 0; i < 2; i++) + if (process->halts[i]) + return 1; + + if (isset_fdhalt(process->read_halt_inode, process->write_halt_inode, + process->disconnect_halt_inode)) { + return 1; + } + return 0; +} + +extern PageDirectory *active_directory; + +process_t *next_task(process_t *c) { + for (;;) { + c = c->next; + if (!c) + c = ready_queue; + if (c->sleep_until > pit_num_ms()) + continue; + if (is_halted(c) || c->dead) + continue; + break; + } + return c; +} + +int task_save_state(void) { + asm("mov %%esp, %0" : "=r"(current_task->esp)); + asm("mov %%ebp, %0" : "=r"(current_task->ebp)); + + uint32_t eip = read_eip(); + + if (0x1 == eip) { + // Should the returned value from read_eip be equal to one it + // means that we have just switched over to this task after we + // saved the state(since the switch_task() function changes the + // eax register to 1). + return 0; + } + + current_task->eip = eip; + return 1; +} + +void switch_task() { + if (!current_task) + return; + + if (0 == task_save_state()) { + return; + } + + current_task = next_task((process_t *)current_task); + + active_directory = current_task->cr3; + + asm(" \ + mov %0, %%esp; \ + mov %1, %%ebp; \ + mov %2, %%ecx; \ + mov %3, %%cr3; \ + mov $0x1, %%eax; \ + jmp *%%ecx" ::"r"(current_task->esp), + "r"(current_task->ebp), "r"(current_task->eip), + "r"(current_task->cr3->physical_address)); +} + +MemoryMap **get_free_map(void) { + for (int i = 0; i < 100; i++) + if (!(current_task->maps[i])) + return &(current_task->maps[i]); + assert(0); + return NULL; +} + +void *get_free_virtual_memory(size_t length) { + void *n = + (void *)((uintptr_t)(get_current_task()->data_segment_end) + length); + + void *rc = get_current_task()->data_segment_end; + get_current_task()->data_segment_end = align_page(n); + return rc; +} + +void *allocate_virtual_user_memory(size_t length, int prot, int flags) { + (void)prot; + (void)flags; + void *rc = get_free_virtual_memory(length); + if ((void *)-1 == rc) + return (void *)-1; + + mmu_allocate_region(rc, length, MMU_FLAG_RW); + return rc; +} + +void *user_kernel_mapping(void *kernel_addr, size_t length) { + void *rc = get_free_virtual_memory(length); + if ((void *)-1 == rc) + return (void *)-1; + + mmu_map_directories(rc, NULL, kernel_addr, NULL, length); + return rc; +} + +void *create_physical_mapping(void **physical_addresses, size_t length) { + void *rc = get_free_virtual_memory(length); + if ((void *)-1 == rc) + return (void *)-1; + int n = (uintptr_t)align_page((void *)length) / 0x1000; + for (int i = 0; i < n; i++) { + mmu_map_physical(rc + (i * 0x1000), NULL, physical_addresses[i], 0x1000); + } + return rc; +} + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset) { + (void)addr; + if (0 == length) { + kprintf("EINVAL\n"); + return (void *)-EINVAL; + } + + vfs_vm_object_t *vmobject = vfs_get_vm_object(fd, length, offset); + if (!vmobject) { + kprintf("ENODEV\n"); + return (void *)-ENODEV; + } + + if (vmobject->size < length) { + kprintf("EOVERFLOW\n"); + return (void *)-EOVERFLOW; // TODO: Check if this is the correct + // code. + } + + MemoryMap **ptr = get_free_map(); + if (!ptr) { + klog("mmap(): No free memory map.", LOG_WARN); + return (void *)-1; + } + *ptr = kmalloc(sizeof(MemoryMap)); + MemoryMap *free_map = *ptr; + + if (fd == -1) { + void *rc = allocate_virtual_user_memory(length, prot, flags); + if ((void *)-1 == rc) { + kprintf("ENOMEM\n"); + return (void *)-ENOMEM; + } + free_map->u_address = rc; + free_map->k_address = NULL; + free_map->fd = -1; + return rc; + } + + if (length > vmobject->size) + length = vmobject->size; + return create_physical_mapping(vmobject->object, length); +} diff --git a/sched/scheduler.h b/sched/scheduler.h new file mode 100644 index 0000000..7ff0734 --- /dev/null +++ b/sched/scheduler.h @@ -0,0 +1,60 @@ +#ifndef SCHEDULER_H +#define SCHEDULER_H +#include <fs/ext2.h> +#include <fs/vfs.h> +#include <halts.h> +#include <mmu.h> + +#define MAX_PATH 256 +#define KEYBOARD_HALT 0 +#define WAIT_CHILD_HALT 1 + +int fork(void); +int exec(const char *filename, char **argv); +void switch_task(); +void tasking_init(void); +void exit(int status); + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset); +int munmap(void *addr, size_t length); +int msync(void *addr, size_t length, int flags); + +typedef struct { + void *u_address; + void *k_address; + int fd; +} MemoryMap; + +typedef struct Process process_t; + +struct Process { + uint32_t pid; + char program_name[100]; + char current_working_directory[MAX_PATH]; + uint32_t eip, esp, ebp; + PageDirectory *cr3; + vfs_fd_t *file_descriptors[100]; + vfs_inode_t *read_halt_inode[100]; + vfs_inode_t *write_halt_inode[100]; + vfs_inode_t *disconnect_halt_inode[100]; + // struct vfs_fd_t ** file_descriptors; + uint32_t halts[2]; + struct Halt *halt_list; + void *data_segment_end; + // uint32_t *halts; + process_t *next; + process_t *parent; + process_t *child; + MemoryMap *maps[100]; + uint32_t sleep_until; + int child_rc; + int dead; + // FIXME: Create a linkedlisti of childs so that the parent process + // can do stuff such as reap zombies and get status. +}; + +process_t *get_current_task(void); +int get_free_fd(process_t *p, int allocate); +void free_process(void); +#endif diff --git a/socket.c b/socket.c new file mode 100644 index 0000000..0e7437c --- /dev/null +++ b/socket.c @@ -0,0 +1,148 @@ +#include <errno.h> +#include <fs/devfs.h> +#include <fs/tmpfs.h> +#include <poll.h> +#include <sched/scheduler.h> +#include <socket.h> + +OPEN_UNIX_SOCKET *un_sockets[100] = {0}; + +int uds_open(const char *path) { + // FIXME: This is super ugly + + // Find the socket that path belongs to + SOCKET *s = NULL; + for (int i = 0; i < 100; i++) { + if (!un_sockets[i]) + continue; + const char *p = path; + const char *e = p; + for (; *e; e++) + ; + for (; e != p && *e != '/'; e--) + ; + if (0 == strcmp(e, un_sockets[i]->path)) { + s = un_sockets[i]->s; + break; + } + } + if (!s) { + return -1; + } + + // Create a pipe + int fd[2]; + dual_pipe(fd); + + char c = 'i'; + raw_vfs_pwrite(s->ptr_fifo_fd, &c, 1, 0); + raw_vfs_pwrite(s->ptr_socket_fd, &c, 1, 0); + + s->incoming_fd = get_current_task()->file_descriptors[fd[1]]; + // vfs_close(fd[1]); + return fd[0]; +} + +int accept(int socket, struct sockaddr *address, socklen_t *address_len) { + (void)address; + (void)address_len; + vfs_inode_t *inode = get_current_task()->file_descriptors[socket]->inode; + SOCKET *s = (SOCKET *)inode->internal_object; + + if (NULL == s->incoming_fd) { + // Wait until we have gotten a connection + struct pollfd fds[1]; + fds[0].fd = s->fifo_fd; + fds[0].events = POLLIN; + fds[0].revents = 0; + poll(fds, 1, 0); + } + + int n = 0; + for (; get_current_task()->file_descriptors[n]; n++) + ; + get_current_task()->file_descriptors[n] = s->incoming_fd; + get_current_task()->file_descriptors[n]->reference_count++; + s->incoming_fd = NULL; + for (char c; 0 < vfs_pread(s->fifo_fd, &c, 1, 0);) + ; + inode->has_data = 0; + // s->ptr_fifo_fd->inode->has_data = 0; + + return n; +} + +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + (void)addrlen; + struct sockaddr_un *un = (struct sockaddr_un *)addr; + + vfs_fd_t *fd = get_vfs_fd(sockfd); + if (!fd) + return -EBADF; + vfs_inode_t *inode = fd->inode; + if (!inode) + return -EBADF; + SOCKET *s = (SOCKET *)inode->internal_object; + + size_t path_len = strlen(un->sun_path); + s->path = kmalloc(path_len + 1); + memcpy(s->path, un->sun_path, path_len); + s->path[path_len] = '\0'; + + OPEN_UNIX_SOCKET *us; + int i = 0; + for (; i < 100; i++) + if (!un_sockets[i]) + break; + + us = un_sockets[i] = kmalloc(sizeof(OPEN_UNIX_SOCKET)); + + us->path = s->path; + us->s = s; + devfs_add_file(us->path, NULL, NULL, NULL, 1, 1, FS_TYPE_UNIX_SOCKET); + return 0; +} + +int socket_write(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)buffer; + (void)offset; + fd->inode->has_data = 1; + return len; +} + +int socket_read(uint8_t *buffer, uint64_t offset, uint64_t len, vfs_fd_t *fd) { + (void)buffer; + (void)offset; + fd->inode->has_data = 0; + return len; +} + +void socket_close(vfs_fd_t *fd) { fd->inode->is_open = 0; } + +int socket(int domain, int type, int protocol) { + if (AF_UNIX != domain) + return -EINVAL; + + SOCKET *new_socket = kmalloc_eternal(sizeof(SOCKET)); + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, 0 /*has_data*/, 1 /*can_write*/, + 1 /*is_open*/, new_socket /*internal_object*/, 0 /*file_size*/, + NULL /*open*/, NULL /*create_file*/, socket_read, socket_write, + socket_close, NULL /*get_vm_object*/); + + vfs_fd_t *fd; + int n = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd); + + new_socket->domain = domain; + new_socket->type = type; + new_socket->protocol = protocol; + new_socket->path = NULL; + new_socket->incoming_fd = NULL; + new_socket->fifo_fd = create_fifo(); + new_socket->ptr_fifo_fd = + get_current_task()->file_descriptors[new_socket->fifo_fd]; + + new_socket->ptr_socket_fd = fd; + + return n; +} diff --git a/socket.h b/socket.h new file mode 100644 index 0000000..debe29d --- /dev/null +++ b/socket.h @@ -0,0 +1,66 @@ +#ifndef SOCKET_H +#define SOCKET_H +#include "fs/vfs.h" +#include <stddef.h> +#include <stdint.h> + +/* +// Create a directory with the proper permissions +mkdir(path, 0700); +// Append the name of the socket +strcat(path, "/socket_name"); + +// Create the socket normally +sockaddr_un address; +address.sun_family = AF_UNIX; +strcpy(address.sun_path, path); +int fd = socket(AF_UNIX, SOCK_STREAM, 0); +bind(fd, (sockaddr*)(&address), sizeof(address)); +listen(fd, 100); +*/ + +#define AF_UNIX 0 +#define AF_LOCAL AF_UNIX + +#define INADDR_ANY 0 + +typedef struct { + int fifo_fd; + vfs_fd_t *ptr_fifo_fd; + + vfs_fd_t *ptr_socket_fd; + + int domain; + int type; + int protocol; + + // UNIX socket + char *path; + vfs_fd_t *incoming_fd; +} SOCKET; + +typedef struct { + char *path; + SOCKET *s; +} OPEN_UNIX_SOCKET; + +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; +typedef unsigned int sa_family_t; +typedef uint32_t socklen_t; + +struct sockaddr { + sa_family_t sa_family; /* Address family */ + char *sa_data; /* Socket address */ +}; + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char *sun_path; /* Socket pathname */ +}; + +int uds_open(const char *path); +int socket(int domain, int type, int protocol); +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#endif @@ -0,0 +1,137 @@ +#!/bin/sh +#pwd +#cd /home/anton/prj/osdev/ +#cd ./userland/json/hashmap +#make clean +#make +#cd ../../.. +# +#cd ./userland/json +#make clean +#make +#cd ../.. +# +cd ./userland/libgui +make clean +make +cd ../.. +# +cd ./userland/libc +#make clean +make +make install +cd ../.. +cd ./userland/nasm-2.16.01 +#make clean +make +#make install +cd ../.. + +cd ./userland/compiler +make +cd ../.. + +#cd ./userland/init +#make clean +#make +#cd ../.. +# +cd ./userland/sh +make clean +make +cd ../.. +cd ./userland/sha1sum +make clean +make +cd ../.. +# +#cd ./userland/cat +#make clean +#make +#cd ../.. +# +cd ./userland/terminal +make clean +make +cd ../.. +# +cd ./userland/snake +make clean +make +cd ../.. +# +cd ./userland/ante +make clean +make +cd ../.. +# +cd ./userland/windowserver +make clean +make +cd ../.. +# +cd ./userland/test +make clean +make +cd ../.. +# +cd ./userland/minibox +make clean +make +cd ../.. + +#cd ./userland/figlet +#cd ./userland/figlet-2.2.5/ +#make clean +#make +#cd ../.. + +pwd +sudo mount ext2.img mount +#sudo cp ./userland/init/init ./mount/init +#sudo cp ./userland/cat/cat ./mount/cat +sudo cp ./userland/sh/sh ./mount/sh +sudo cp ./userland/terminal/term ./mount/term +sudo cp ./userland/snake/snake ./mount/snake +sudo cp ./userland/ante/ante ./mount/ante +sudo cp ./userland/windowserver/ws ./mount/ws +sudo cp ./userland/test/test ./mount/test +sudo cp ./userland/minibox/minibox ./mount/minibox +sudo cp ./userland/nasm-2.16.01/nasm ./mount/nasm + +sudo cp ./userland/figlet-2.2.5/figlet ./mount/ +sudo cp ./userland/figlet-2.2.5/chkfont ./mount/ +sudo cp ./userland/figlet-2.2.5/figlist ./mount/ +sudo cp ./userland/figlet-2.2.5/showfigfonts ./mount/ + +sudo cp ./userland/figlet-2.2.5/fonts/*.flf ./mount/fonts/ +sudo cp ./userland/figlet-2.2.5/fonts/*.flc ./mount/fonts/ + +sudo cp ./DOOM1.WAD ./mount/DOOM1.WAD +sudo cp ./userland/compiler/compiler ./mount/cc +sudo cp ./userland/sha1sum/sha1sum ./mount/sha1sum +sudo cp ./userland/sha1sum/sha1sum ./mount/sa +sudo cp ./userland/fasm/fasm ./mount/fasm +sudo cp ./userland/ed/ed ./mount/ed +sudo cp ./userland/SmallerC/smlrc ./mount/sc +sudo cp ./userland/libc/crt0.o ./mount/crt0.o +sudo cp ./userland/libc/libc.a ./mount/libc.a +sudo cp ./userland/doomgeneric/doomgeneric/doomgeneric ./mount/doomgeneric +echo -e "int main(void) {\nprintf(\"hi\");\nreturn 0;\n}" > /tmp/main.c + +cd ./mount +sudo rm ./init +sudo rm ./cat +sudo rm ./yes +sudo rm ./echo +sudo rm ./wc +sudo rm ./ls +sudo ln -s ./minibox ./init +sudo ln -s ./minibox ./cat +sudo ln -s ./minibox ./yes +sudo ln -s ./minibox ./echo +sudo ln -s ./minibox ./wc +sudo ln -s ./minibox ./ls +sudo cp /tmp/main.c ./main.c +cd .. +sudo umount mount @@ -0,0 +1,10 @@ +#ifndef TIME_H +#define TIME_H +#include <sys/types.h> + +typedef int clockid_t; +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; +#endif diff --git a/toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F b/toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F new file mode 100644 index 0000000..b778c91 --- /dev/null +++ b/toolchain/3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F @@ -0,0 +1,38 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsFNBFm/2cUBEADkvRqMWfAryJ52T4J/640Av5cam9ojdFih9MjcX7QWFxIzJfTF +Yq2z+nb4omdfZosdCJL2zGcn6C0AxpHNvxR9HMDkEyFHKrjDh4xWU+pH4z9azQEq +Jh331X7UzbZldqQo16VkuVavgsTJaHcXm+nGIBTcUbl2oiTtHhmuaYxx6JTMcFjC +7vyO5mLBw78wt52HBYweJ0NjHBvvH/JxbAAULSPRUC61K0exlO49VFbFETQNG1hZ +TKEji95fPbre7PpXQ0ewQShUgttEE/J3UA4jYaF9lOcZgUzbA27xTV//KomP0D30 +yr4e4EJEJYYNKa3hofTEHDXeeNgM25tprhBUMdbVRZpf2Keuk2uDVwc+EiOVri48 +rb1NU+60sOXvoGO6Ks81+mhAGmrBrlgLhAp8K1HPHI4MG4gHnrMqX2rEGUGRPFjC +3qqVVlPm8H05PnosNqDLQ1Pf7C0pVgsCx6hKQB7Y1qBui7aoj9zeFaQgpYef+CEE +RIKEcWwrjaOJwK3pi9HFdxS0NNWYZj8HPzz/AsgTTQdsbulPlVq2SsctmOnL42CZ +OCTppGYwl53CG/EqVY+UQBzFzJBaY8TJRFFYVEy5/HH4H11rMoZwqIkk71EOGU3X +6mWlANRikR3M4GhVITRzuaV69Fed+OeXcCmP94ASLfuhBR2uynmcHpBKpwARAQAB +zsFNBFm/2cUBEAC2iRP97tt607zy5IrWkyRaipMD1cpc5MJinb3dqnhBZNasrNid +7QAkzMmFZ2E0l8uRCR9sycoVHy54S6fIyWReKFOUHoTmiT3DJsyPwmUtQJh/o55u +qbpHWQKME8ycreCCkmqa/u5sXMV9WENl3sDJxWKS5AANnR2goS0lPxByV3t/juA4 +BFEUxTGt0kTfyeBjTAWnCl5zEkmMpSOQ3CDmf79CBmuTAFx6z9R8JtawZpaCHIJs +3sXMwX/iHFoAi04chT337/tqXyytV2kvNjswQu30tNaQf3gzpI0ListerCmV+kbe +e77neNLhOWtJaciLQtj+7u0Fi+Mk+aTBfqEvG5t2FoBJ7Vd/NEcmaaoCRmU2Szat +k+GYH4mrnhFeCczpxtv0ERozlKzUGmMysuVdduwk50YOAWBf7ixJosy3CNzt1Nfp +hM+oePMJAKIztQegGfC5vibsTluaLhnK5ExLiBuehnA8DFkvz8P7zbA8jZjgo8vX +hCliYJjJi2qufR6X03fCDnmmMrgEBwLGLf88ystIIjII4QkLbnPfROJ0BPSmeOAy +rJ6kWmyvbN82BNzyJAhSBGXFIiV0l1ljiHSeN4/mMhR1OYal3xAjOq8yhgXgVBk8 +8lnDl+mMETOC80A1ScGBvHFX7Yfr+PyJnF0eNw+FlccQRAIymoNNm/tcnwARAQAB +wsFfBBgBAgAJBQJZv9nFAhsMAAoJEBP874ndnjxP3akP+gKVMILGc7abNDDnUXXY +z8M+OKVl0uTBuOYqzEFxCxkMsZK2n3PJcB3gAWLLaCvHaaKU3CRhN3WRi9yTc9WF +sUOQFeLsqgZ+TfEbm3APDc0eg0D/jhjyMMzJHrb1Qv3G2yg2an9Lkw8t4z+uThYU +pExCMp2L9TG+CSZd0qvoWlG31iwFeZ26Erh5omROgc9vk43aFZDcBwX6asbujJVp +Gvj/fElHJmPIlYT8vUAtVxThnRQxX9ZGIB1tu5hcHbN+TUITQEYH7QFc/RWV67lu +rRSCH4rI6961Yw/UfFYC+5ebzK/cpThaXqZyOvsHdl9eeuh1uxdWcNQyK2NjRy+5 +C+et+Wx6yWOJ+6P5+xJZPwmvzAKs3SGcc+qK313iJrKmejg5+GOOz06Et0692zDT +fTerZjj0GZCRhwwRMW4QIvyafH6VsTJqVQlJenPOXDgQkeLPLWbLxmDo0dwr6iq1 ++G2/BhJa4TrwCWug3ZmV3OwMqFTGk74aat4CWCpguuKKre88CB8GgsU2z+guqFKf +RDUVe5x51zdwZbyIAqOEBLOh5A85JoGJQhDigYg8lTEpDw2XbLKWviuBpVNksIvw +QyTI7Q8cqPitDPNS118TnkXxCHz7Wd3XcQSj72tbkrLs/qWzfXdSWPCqOU/4derL +rItkXlMjSRCWkp4zuc9d00NV +=n5Jz +-----END PGP PUBLIC KEY BLOCK----- diff --git a/toolchain/binutils-2.40.diff b/toolchain/binutils-2.40.diff new file mode 100644 index 0000000..e8eb8bb --- /dev/null +++ b/toolchain/binutils-2.40.diff @@ -0,0 +1,12573 @@ +diff --git a/bfd/config.bfd b/bfd/config.bfd +index 1b0111fd..369f7299 100644 +--- a/bfd/config.bfd ++++ b/bfd/config.bfd +@@ -237,6 +237,11 @@ esac + + case "${targ}" in + # START OF targmatch.h ++ i[3-7]86-*-sb*) ++ targ_defvec=i386_elf32_vec ++ targ_selvecs= ++ targ64_selvecs=x86_64_elf64_vec ++ ;; + #ifdef BFD64 + aarch64-*-darwin*) + targ_defvec=aarch64_mach_o_vec +diff --git a/config.sub b/config.sub +index dba16e84..b30aad24 100755 +--- a/config.sub ++++ b/config.sub +@@ -1754,7 +1754,7 @@ case $os in + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* ) ++ | fiwix* | sb* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff --git a/gas/configure.tgt b/gas/configure.tgt +index 765ba736..85257e12 100644 +--- a/gas/configure.tgt ++++ b/gas/configure.tgt +@@ -125,6 +125,7 @@ esac + generic_target=${cpu_type}-$vendor-$os + # Note: This table is alpha-sorted, please try to keep it that way. + case ${generic_target} in ++ i386-*-sb*) fmt=elf ;; + aarch64*-*-elf*) fmt=elf;; + aarch64*-*-fuchsia*) fmt=elf;; + aarch64*-*-haiku*) fmt=elf em=haiku ;; +diff --git a/ld/Makefile.am b/ld/Makefile.am +index 12b2c3c4..a9864474 100644 +--- a/ld/Makefile.am ++++ b/ld/Makefile.am +@@ -152,6 +152,7 @@ endif + + # These all start with e so 'make clean' can find them. + ALL_EMULATION_SOURCES = \ ++ eelf_i386_sb.c \ + eaix5ppc.c \ + eaix5rs6.c \ + eaixppc.c \ +@@ -770,6 +771,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS) + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Pc@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sb.Pc@am__quote@ ++#@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sb.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Pc@am__quote@ +diff --git a/ld/Makefile.in b/ld/Makefile.in +index 3d5685d6..b542e0e8 100644 +--- a/ld/Makefile.in ++++ b/ld/Makefile.in +@@ -1,7 +1,7 @@ +-# Makefile.in generated by automake 1.15.1 from Makefile.am. ++# Makefile.in generated by automake 1.16.5 from Makefile.am. + # @configure_input@ + +-# Copyright (C) 1994-2017 Free Software Foundation, Inc. ++# Copyright (C) 1994-2021 Free Software Foundation, Inc. + + # This Makefile.in is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -110,27 +110,8 @@ target_triplet = @target@ + bin_PROGRAMS = ld-new$(EXEEXT) + subdir = . + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \ +- $(top_srcdir)/../bfd/warning.m4 $(top_srcdir)/../config/acx.m4 \ +- $(top_srcdir)/../config/bfd64.m4 \ +- $(top_srcdir)/../config/depstand.m4 \ +- $(top_srcdir)/../config/enable.m4 \ +- $(top_srcdir)/../config/gettext-sister.m4 \ +- $(top_srcdir)/../config/jobserver.m4 \ +- $(top_srcdir)/../config/largefile.m4 \ +- $(top_srcdir)/../config/lcmessage.m4 \ +- $(top_srcdir)/../config/lead-dot.m4 \ +- $(top_srcdir)/../config/nls.m4 \ +- $(top_srcdir)/../config/override.m4 \ +- $(top_srcdir)/../config/pkg.m4 \ +- $(top_srcdir)/../config/plugins.m4 \ +- $(top_srcdir)/../config/po.m4 \ +- $(top_srcdir)/../config/progtest.m4 \ +- $(top_srcdir)/../config/zlib.m4 \ +- $(top_srcdir)/../config/zstd.m4 $(top_srcdir)/../libtool.m4 \ +- $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ +- $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ +- $(top_srcdir)/../bfd/version.m4 $(top_srcdir)/configure.ac ++am__aclocal_m4_deps = $(top_srcdir)/../bfd/version.m4 \ ++ $(top_srcdir)/configure.ac + am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) + DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ +@@ -141,6 +122,9 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs + CONFIG_HEADER = config.h + CONFIG_CLEAN_FILES = po/Makefile.in + CONFIG_CLEAN_VPATH_FILES = ++am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bfdplugindir)" \ ++ "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" ++PROGRAMS = $(bin_PROGRAMS) + am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; + am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ +@@ -168,8 +152,6 @@ am__uninstall_files_from_dir = { \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +-am__installdirs = "$(DESTDIR)$(bfdplugindir)" "$(DESTDIR)$(bindir)" \ +- "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" + LTLIBRARIES = $(bfdplugin_LTLIBRARIES) $(noinst_LTLIBRARIES) + libdep_la_LIBADD = + am_libdep_la_OBJECTS = libdep_plugin.lo +@@ -206,7 +188,6 @@ libldtestplug4_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libldtestplug4_la_CFLAGS) $(CFLAGS) \ + $(libldtestplug4_la_LDFLAGS) $(LDFLAGS) -o $@ +-PROGRAMS = $(bin_PROGRAMS) + am_ld_new_OBJECTS = ldgram.$(OBJEXT) ldlex-wrapper.$(OBJEXT) \ + lexsup.$(OBJEXT) ldlang.$(OBJEXT) mri.$(OBJEXT) \ + ldctor.$(OBJEXT) ldmain.$(OBJEXT) ldwrite.$(OBJEXT) \ +@@ -230,7 +211,188 @@ am__v_at_0 = @ + am__v_at_1 = + DEFAULT_INCLUDES = -I.@am__isrc@ + depcomp = $(SHELL) $(top_srcdir)/../depcomp +-am__depfiles_maybe = depfiles ++am__maybe_remake_depfiles = depfiles ++am__depfiles_remade = ./$(DEPDIR)/deffilep.Po \ ++ ./$(DEPDIR)/eaarch64cloudabi.Po \ ++ ./$(DEPDIR)/eaarch64cloudabib.Po ./$(DEPDIR)/eaarch64elf.Po \ ++ ./$(DEPDIR)/eaarch64elf32.Po ./$(DEPDIR)/eaarch64elf32b.Po \ ++ ./$(DEPDIR)/eaarch64elfb.Po ./$(DEPDIR)/eaarch64fbsd.Po \ ++ ./$(DEPDIR)/eaarch64fbsdb.Po ./$(DEPDIR)/eaarch64haiku.Po \ ++ ./$(DEPDIR)/eaarch64linux.Po ./$(DEPDIR)/eaarch64linux32.Po \ ++ ./$(DEPDIR)/eaarch64linux32b.Po ./$(DEPDIR)/eaarch64linuxb.Po \ ++ ./$(DEPDIR)/eaarch64pe.Po ./$(DEPDIR)/eaix5ppc.Po \ ++ ./$(DEPDIR)/eaix5rs6.Po ./$(DEPDIR)/eaixppc.Po \ ++ ./$(DEPDIR)/eaixrs6.Po ./$(DEPDIR)/ealpha.Po \ ++ ./$(DEPDIR)/ealphavms.Po ./$(DEPDIR)/earcelf.Po \ ++ ./$(DEPDIR)/earclinux.Po ./$(DEPDIR)/earclinux_nps.Po \ ++ ./$(DEPDIR)/earcv2elf.Po ./$(DEPDIR)/earcv2elfx.Po \ ++ ./$(DEPDIR)/earm_wince_pe.Po ./$(DEPDIR)/earmelf.Po \ ++ ./$(DEPDIR)/earmelf_fbsd.Po ./$(DEPDIR)/earmelf_fuchsia.Po \ ++ ./$(DEPDIR)/earmelf_haiku.Po ./$(DEPDIR)/earmelf_linux.Po \ ++ ./$(DEPDIR)/earmelf_linux_eabi.Po \ ++ ./$(DEPDIR)/earmelf_linux_fdpiceabi.Po \ ++ ./$(DEPDIR)/earmelf_nacl.Po ./$(DEPDIR)/earmelf_nbsd.Po \ ++ ./$(DEPDIR)/earmelf_phoenix.Po ./$(DEPDIR)/earmelf_vxworks.Po \ ++ ./$(DEPDIR)/earmelfb.Po ./$(DEPDIR)/earmelfb_fbsd.Po \ ++ ./$(DEPDIR)/earmelfb_fuchsia.Po ./$(DEPDIR)/earmelfb_linux.Po \ ++ ./$(DEPDIR)/earmelfb_linux_eabi.Po \ ++ ./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po \ ++ ./$(DEPDIR)/earmelfb_nacl.Po ./$(DEPDIR)/earmelfb_nbsd.Po \ ++ ./$(DEPDIR)/earmnto.Po ./$(DEPDIR)/earmpe.Po \ ++ ./$(DEPDIR)/eavr1.Po ./$(DEPDIR)/eavr2.Po \ ++ ./$(DEPDIR)/eavr25.Po ./$(DEPDIR)/eavr3.Po \ ++ ./$(DEPDIR)/eavr31.Po ./$(DEPDIR)/eavr35.Po \ ++ ./$(DEPDIR)/eavr4.Po ./$(DEPDIR)/eavr5.Po \ ++ ./$(DEPDIR)/eavr51.Po ./$(DEPDIR)/eavr6.Po \ ++ ./$(DEPDIR)/eavrtiny.Po ./$(DEPDIR)/eavrxmega1.Po \ ++ ./$(DEPDIR)/eavrxmega2.Po ./$(DEPDIR)/eavrxmega3.Po \ ++ ./$(DEPDIR)/eavrxmega4.Po ./$(DEPDIR)/eavrxmega5.Po \ ++ ./$(DEPDIR)/eavrxmega6.Po ./$(DEPDIR)/eavrxmega7.Po \ ++ ./$(DEPDIR)/ecrisaout.Po ./$(DEPDIR)/ecriself.Po \ ++ ./$(DEPDIR)/ecrislinux.Po ./$(DEPDIR)/ecskyelf.Po \ ++ ./$(DEPDIR)/ecskyelf_linux.Po ./$(DEPDIR)/ed10velf.Po \ ++ ./$(DEPDIR)/ed30v_e.Po ./$(DEPDIR)/ed30v_o.Po \ ++ ./$(DEPDIR)/ed30velf.Po ./$(DEPDIR)/eelf32_dlx.Po \ ++ ./$(DEPDIR)/eelf32_sparc.Po ./$(DEPDIR)/eelf32_sparc_sol2.Po \ ++ ./$(DEPDIR)/eelf32_sparc_vxworks.Po ./$(DEPDIR)/eelf32_spu.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_be.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_elf_be.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_elf_le.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_le.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_linux_be.Po \ ++ ./$(DEPDIR)/eelf32_tic6x_linux_le.Po \ ++ ./$(DEPDIR)/eelf32_x86_64.Po ./$(DEPDIR)/eelf32am33lin.Po \ ++ ./$(DEPDIR)/eelf32b4300.Po ./$(DEPDIR)/eelf32bfin.Po \ ++ ./$(DEPDIR)/eelf32bfinfd.Po ./$(DEPDIR)/eelf32bmip.Po \ ++ ./$(DEPDIR)/eelf32bmipn32.Po ./$(DEPDIR)/eelf32briscv.Po \ ++ ./$(DEPDIR)/eelf32briscv_ilp32.Po \ ++ ./$(DEPDIR)/eelf32briscv_ilp32f.Po ./$(DEPDIR)/eelf32bsmip.Po \ ++ ./$(DEPDIR)/eelf32btsmip.Po ./$(DEPDIR)/eelf32btsmip_fbsd.Po \ ++ ./$(DEPDIR)/eelf32btsmipn32.Po \ ++ ./$(DEPDIR)/eelf32btsmipn32_fbsd.Po ./$(DEPDIR)/eelf32cr16.Po \ ++ ./$(DEPDIR)/eelf32crx.Po ./$(DEPDIR)/eelf32ebmip.Po \ ++ ./$(DEPDIR)/eelf32ebmipvxworks.Po ./$(DEPDIR)/eelf32elmip.Po \ ++ ./$(DEPDIR)/eelf32elmipvxworks.Po \ ++ ./$(DEPDIR)/eelf32epiphany.Po \ ++ ./$(DEPDIR)/eelf32epiphany_4x4.Po ./$(DEPDIR)/eelf32fr30.Po \ ++ ./$(DEPDIR)/eelf32frv.Po ./$(DEPDIR)/eelf32frvfd.Po \ ++ ./$(DEPDIR)/eelf32ft32.Po ./$(DEPDIR)/eelf32ip2k.Po \ ++ ./$(DEPDIR)/eelf32iq10.Po ./$(DEPDIR)/eelf32iq2000.Po \ ++ ./$(DEPDIR)/eelf32l4300.Po ./$(DEPDIR)/eelf32lm32.Po \ ++ ./$(DEPDIR)/eelf32lm32fd.Po ./$(DEPDIR)/eelf32lmip.Po \ ++ ./$(DEPDIR)/eelf32loongarch.Po ./$(DEPDIR)/eelf32lppc.Po \ ++ ./$(DEPDIR)/eelf32lppclinux.Po ./$(DEPDIR)/eelf32lppcnto.Po \ ++ ./$(DEPDIR)/eelf32lppcsim.Po ./$(DEPDIR)/eelf32lr5900.Po \ ++ ./$(DEPDIR)/eelf32lr5900n32.Po ./$(DEPDIR)/eelf32lriscv.Po \ ++ ./$(DEPDIR)/eelf32lriscv_ilp32.Po \ ++ ./$(DEPDIR)/eelf32lriscv_ilp32f.Po ./$(DEPDIR)/eelf32lsmip.Po \ ++ ./$(DEPDIR)/eelf32ltsmip.Po ./$(DEPDIR)/eelf32ltsmip_fbsd.Po \ ++ ./$(DEPDIR)/eelf32ltsmipn32.Po \ ++ ./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po ./$(DEPDIR)/eelf32m32c.Po \ ++ ./$(DEPDIR)/eelf32mb_linux.Po ./$(DEPDIR)/eelf32mbel_linux.Po \ ++ ./$(DEPDIR)/eelf32mcore.Po ./$(DEPDIR)/eelf32mep.Po \ ++ ./$(DEPDIR)/eelf32metag.Po ./$(DEPDIR)/eelf32microblaze.Po \ ++ ./$(DEPDIR)/eelf32microblazeel.Po \ ++ ./$(DEPDIR)/eelf32mipswindiss.Po ./$(DEPDIR)/eelf32moxie.Po \ ++ ./$(DEPDIR)/eelf32mt.Po ./$(DEPDIR)/eelf32or1k.Po \ ++ ./$(DEPDIR)/eelf32or1k_linux.Po ./$(DEPDIR)/eelf32ppc.Po \ ++ ./$(DEPDIR)/eelf32ppc_fbsd.Po ./$(DEPDIR)/eelf32ppchaiku.Po \ ++ ./$(DEPDIR)/eelf32ppclinux.Po ./$(DEPDIR)/eelf32ppcnto.Po \ ++ ./$(DEPDIR)/eelf32ppcsim.Po ./$(DEPDIR)/eelf32ppcvxworks.Po \ ++ ./$(DEPDIR)/eelf32ppcwindiss.Po ./$(DEPDIR)/eelf32rl78.Po \ ++ ./$(DEPDIR)/eelf32rx.Po ./$(DEPDIR)/eelf32rx_linux.Po \ ++ ./$(DEPDIR)/eelf32tilegx.Po ./$(DEPDIR)/eelf32tilegx_be.Po \ ++ ./$(DEPDIR)/eelf32tilepro.Po ./$(DEPDIR)/eelf32vax.Po \ ++ ./$(DEPDIR)/eelf32visium.Po ./$(DEPDIR)/eelf32xstormy16.Po \ ++ ./$(DEPDIR)/eelf32xtensa.Po ./$(DEPDIR)/eelf32z80.Po \ ++ ./$(DEPDIR)/eelf64_aix.Po ./$(DEPDIR)/eelf64_ia64.Po \ ++ ./$(DEPDIR)/eelf64_ia64_fbsd.Po ./$(DEPDIR)/eelf64_ia64_vms.Po \ ++ ./$(DEPDIR)/eelf64_s390.Po ./$(DEPDIR)/eelf64_sparc.Po \ ++ ./$(DEPDIR)/eelf64_sparc_fbsd.Po \ ++ ./$(DEPDIR)/eelf64_sparc_sol2.Po ./$(DEPDIR)/eelf64alpha.Po \ ++ ./$(DEPDIR)/eelf64alpha_fbsd.Po \ ++ ./$(DEPDIR)/eelf64alpha_nbsd.Po ./$(DEPDIR)/eelf64bmip.Po \ ++ ./$(DEPDIR)/eelf64bpf.Po ./$(DEPDIR)/eelf64briscv.Po \ ++ ./$(DEPDIR)/eelf64briscv_lp64.Po \ ++ ./$(DEPDIR)/eelf64briscv_lp64f.Po ./$(DEPDIR)/eelf64btsmip.Po \ ++ ./$(DEPDIR)/eelf64btsmip_fbsd.Po ./$(DEPDIR)/eelf64hppa.Po \ ++ ./$(DEPDIR)/eelf64loongarch.Po ./$(DEPDIR)/eelf64lppc.Po \ ++ ./$(DEPDIR)/eelf64lppc_fbsd.Po ./$(DEPDIR)/eelf64lriscv.Po \ ++ ./$(DEPDIR)/eelf64lriscv_lp64.Po \ ++ ./$(DEPDIR)/eelf64lriscv_lp64f.Po ./$(DEPDIR)/eelf64ltsmip.Po \ ++ ./$(DEPDIR)/eelf64ltsmip_fbsd.Po ./$(DEPDIR)/eelf64mmix.Po \ ++ ./$(DEPDIR)/eelf64ppc.Po ./$(DEPDIR)/eelf64ppc_fbsd.Po \ ++ ./$(DEPDIR)/eelf64rdos.Po ./$(DEPDIR)/eelf64tilegx.Po \ ++ ./$(DEPDIR)/eelf64tilegx_be.Po ./$(DEPDIR)/eelf_i386.Po \ ++ ./$(DEPDIR)/eelf_i386_be.Po ./$(DEPDIR)/eelf_i386_fbsd.Po \ ++ ./$(DEPDIR)/eelf_i386_haiku.Po ./$(DEPDIR)/eelf_i386_ldso.Po \ ++ ./$(DEPDIR)/eelf_i386_sb.Po ./$(DEPDIR)/eelf_i386_sol2.Po \ ++ ./$(DEPDIR)/eelf_i386_vxworks.Po ./$(DEPDIR)/eelf_iamcu.Po \ ++ ./$(DEPDIR)/eelf_mipsel_haiku.Po ./$(DEPDIR)/eelf_s390.Po \ ++ ./$(DEPDIR)/eelf_x86_64.Po ./$(DEPDIR)/eelf_x86_64_cloudabi.Po \ ++ ./$(DEPDIR)/eelf_x86_64_fbsd.Po \ ++ ./$(DEPDIR)/eelf_x86_64_haiku.Po \ ++ ./$(DEPDIR)/eelf_x86_64_sol2.Po ./$(DEPDIR)/eh8300elf.Po \ ++ ./$(DEPDIR)/eh8300elf_linux.Po ./$(DEPDIR)/eh8300helf.Po \ ++ ./$(DEPDIR)/eh8300helf_linux.Po ./$(DEPDIR)/eh8300hnelf.Po \ ++ ./$(DEPDIR)/eh8300self.Po ./$(DEPDIR)/eh8300self_linux.Po \ ++ ./$(DEPDIR)/eh8300snelf.Po ./$(DEPDIR)/eh8300sxelf.Po \ ++ ./$(DEPDIR)/eh8300sxelf_linux.Po ./$(DEPDIR)/eh8300sxnelf.Po \ ++ ./$(DEPDIR)/ehppa64linux.Po ./$(DEPDIR)/ehppaelf.Po \ ++ ./$(DEPDIR)/ehppalinux.Po ./$(DEPDIR)/ehppanbsd.Po \ ++ ./$(DEPDIR)/ehppaobsd.Po ./$(DEPDIR)/ei386aout.Po \ ++ ./$(DEPDIR)/ei386beos.Po ./$(DEPDIR)/ei386bsd.Po \ ++ ./$(DEPDIR)/ei386go32.Po ./$(DEPDIR)/ei386lynx.Po \ ++ ./$(DEPDIR)/ei386moss.Po ./$(DEPDIR)/ei386msdos.Po \ ++ ./$(DEPDIR)/ei386nto.Po ./$(DEPDIR)/ei386pe.Po \ ++ ./$(DEPDIR)/ei386pe_posix.Po ./$(DEPDIR)/ei386pep.Po \ ++ ./$(DEPDIR)/em32relf.Po ./$(DEPDIR)/em32relf_linux.Po \ ++ ./$(DEPDIR)/em32rlelf.Po ./$(DEPDIR)/em32rlelf_linux.Po \ ++ ./$(DEPDIR)/em68hc11elf.Po ./$(DEPDIR)/em68hc11elfb.Po \ ++ ./$(DEPDIR)/em68hc12elf.Po ./$(DEPDIR)/em68hc12elfb.Po \ ++ ./$(DEPDIR)/em68kelf.Po ./$(DEPDIR)/em68kelfnbsd.Po \ ++ ./$(DEPDIR)/em9s12zelf.Po ./$(DEPDIR)/emcorepe.Po \ ++ ./$(DEPDIR)/emmo.Po ./$(DEPDIR)/emn10200.Po \ ++ ./$(DEPDIR)/emn10300.Po ./$(DEPDIR)/emoxiebox.Po \ ++ ./$(DEPDIR)/emsp430X.Po ./$(DEPDIR)/emsp430elf.Po \ ++ ./$(DEPDIR)/ends32belf.Po ./$(DEPDIR)/ends32belf16m.Po \ ++ ./$(DEPDIR)/ends32belf_linux.Po ./$(DEPDIR)/ends32elf.Po \ ++ ./$(DEPDIR)/ends32elf16m.Po ./$(DEPDIR)/ends32elf_linux.Po \ ++ ./$(DEPDIR)/enios2elf.Po ./$(DEPDIR)/enios2linux.Po \ ++ ./$(DEPDIR)/ens32knbsd.Po ./$(DEPDIR)/epc532macha.Po \ ++ ./$(DEPDIR)/epdp11.Po ./$(DEPDIR)/epjelf.Po \ ++ ./$(DEPDIR)/epjlelf.Po ./$(DEPDIR)/eppcmacos.Po \ ++ ./$(DEPDIR)/epruelf.Po ./$(DEPDIR)/escore3_elf.Po \ ++ ./$(DEPDIR)/escore7_elf.Po ./$(DEPDIR)/esh.Po \ ++ ./$(DEPDIR)/eshelf.Po ./$(DEPDIR)/eshelf_fd.Po \ ++ ./$(DEPDIR)/eshelf_linux.Po ./$(DEPDIR)/eshelf_nbsd.Po \ ++ ./$(DEPDIR)/eshelf_nto.Po ./$(DEPDIR)/eshelf_uclinux.Po \ ++ ./$(DEPDIR)/eshelf_vxworks.Po ./$(DEPDIR)/eshl.Po \ ++ ./$(DEPDIR)/eshlelf.Po ./$(DEPDIR)/eshlelf_fd.Po \ ++ ./$(DEPDIR)/eshlelf_linux.Po ./$(DEPDIR)/eshlelf_nbsd.Po \ ++ ./$(DEPDIR)/eshlelf_nto.Po ./$(DEPDIR)/eshlelf_vxworks.Po \ ++ ./$(DEPDIR)/eshpe.Po ./$(DEPDIR)/etic30coff.Po \ ++ ./$(DEPDIR)/etic3xcoff.Po ./$(DEPDIR)/etic3xcoff_onchip.Po \ ++ ./$(DEPDIR)/etic4xcoff.Po ./$(DEPDIR)/etic54xcoff.Po \ ++ ./$(DEPDIR)/ev850.Po ./$(DEPDIR)/ev850_rh850.Po \ ++ ./$(DEPDIR)/evanilla.Po ./$(DEPDIR)/evaxnbsd.Po \ ++ ./$(DEPDIR)/exgateelf.Po ./$(DEPDIR)/ez80.Po \ ++ ./$(DEPDIR)/ez8001.Po ./$(DEPDIR)/ez8002.Po \ ++ ./$(DEPDIR)/ldbuildid.Po ./$(DEPDIR)/ldcref.Po \ ++ ./$(DEPDIR)/ldctor.Po ./$(DEPDIR)/ldelf.Po \ ++ ./$(DEPDIR)/ldelfgen.Po ./$(DEPDIR)/ldemul.Po \ ++ ./$(DEPDIR)/ldexp.Po ./$(DEPDIR)/ldfile.Po \ ++ ./$(DEPDIR)/ldgram.Po ./$(DEPDIR)/ldlang.Po \ ++ ./$(DEPDIR)/ldlex-wrapper.Po ./$(DEPDIR)/ldlex.Po \ ++ ./$(DEPDIR)/ldmain.Po ./$(DEPDIR)/ldmisc.Po \ ++ ./$(DEPDIR)/ldver.Po ./$(DEPDIR)/ldwrite.Po \ ++ ./$(DEPDIR)/lexsup.Po ./$(DEPDIR)/libdep_plugin.Plo \ ++ ./$(DEPDIR)/libldtestplug2_la-testplug2.Plo \ ++ ./$(DEPDIR)/libldtestplug3_la-testplug3.Plo \ ++ ./$(DEPDIR)/libldtestplug4_la-testplug4.Plo \ ++ ./$(DEPDIR)/libldtestplug_la-testplug.Plo ./$(DEPDIR)/mri.Po \ ++ ./$(DEPDIR)/pdb.Po ./$(DEPDIR)/pe-dll.Po \ ++ ./$(DEPDIR)/pep-dll.Po ./$(DEPDIR)/plugin.Po + am__mv = mv -f + COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +@@ -336,8 +498,8 @@ am__recursive_targets = \ + $(am__extra_recursive_targets) + AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope +-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ +- $(LISP)config.in ++am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ ++ config.in + # Read a list of newline-separated strings from the standard input, + # and print each of them once, without duplicates. Input order is + # *not* preserved. +@@ -354,9 +516,6 @@ am__define_uniq_tagged_files = \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +-ETAGS = etags +-CTAGS = ctags +-CSCOPE = cscope + DEJATOOL = $(PACKAGE) + RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir + DIST_SUBDIRS = $(SUBDIRS) +@@ -369,21 +528,21 @@ AUTOCONF = @AUTOCONF@ + AUTOHEADER = @AUTOHEADER@ + AUTOMAKE = @AUTOMAKE@ + AWK = @AWK@ +-CATALOGS = @CATALOGS@ +-CATOBJEXT = @CATOBJEXT@ + CC = @CC@ + CCDEPMODE = @CCDEPMODE@ + CFLAGS = @CFLAGS@ + CPP = @CPP@ + CPPFLAGS = @CPPFLAGS@ ++CSCOPE = @CSCOPE@ ++CTAGS = @CTAGS@ + CXX = @CXX@ + CXXCPP = @CXXCPP@ + CXXDEPMODE = @CXXDEPMODE@ + CXXFLAGS = @CXXFLAGS@ + CYGPATH_W = @CYGPATH_W@ +-DATADIRNAME = @DATADIRNAME@ + DEFS = @DEFS@ + DEPDIR = @DEPDIR@ ++DLLTOOL = @DLLTOOL@ + DSYMUTIL = @DSYMUTIL@ + DUMPBIN = @DUMPBIN@ + ECHO_C = @ECHO_C@ +@@ -394,29 +553,27 @@ EMUL = @EMUL@ + EMULATION_LIBPATH = @EMULATION_LIBPATH@ + EMULATION_OFILES = @EMULATION_OFILES@ + EMUL_EXTRA_OFILES = @EMUL_EXTRA_OFILES@ ++ETAGS = @ETAGS@ + EXEEXT = @EXEEXT@ + FGREP = @FGREP@ +-GENCAT = @GENCAT@ ++FILECMD = @FILECMD@ ++GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ + GMSGFMT = @GMSGFMT@ ++GMSGFMT_015 = @GMSGFMT_015@ + GREP = @GREP@ + HDEFINES = @HDEFINES@ +-INCINTL = @INCINTL@ + INSTALL = @INSTALL@ + INSTALL_DATA = @INSTALL_DATA@ + INSTALL_PROGRAM = @INSTALL_PROGRAM@ + INSTALL_SCRIPT = @INSTALL_SCRIPT@ + INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +-INSTOBJEXT = @INSTOBJEXT@ + JANSSON_CFLAGS = @JANSSON_CFLAGS@ + JANSSON_LIBS = @JANSSON_LIBS@ +-LARGEFILE_CPPFLAGS = @LARGEFILE_CPPFLAGS@ + LD = @LD@ + LDFLAGS = @LDFLAGS@ + LEX = `if [ -f ../flex/flex ]; then echo ../flex/flex; else echo @LEX@; fi` + LEXLIB = @LEXLIB@ + LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +-LIBINTL = @LIBINTL@ +-LIBINTL_DEP = @LIBINTL_DEP@ + LIBOBJS = @LIBOBJS@ + LIBS = @LIBS@ + LIBTOOL = @LIBTOOL@ +@@ -432,16 +589,17 @@ LIB_PATH = @LIB_PATH@ + LIPO = @LIPO@ + LN_S = @LN_S@ + LTLIBOBJS = @LTLIBOBJS@ ++LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ + MAINT = @MAINT@ + MAKEINFO = @MAKEINFO@ ++MANIFEST_TOOL = @MANIFEST_TOOL@ + MKDIR_P = @MKDIR_P@ +-MKINSTALLDIRS = @MKINSTALLDIRS@ + MSGFMT = @MSGFMT@ + MSGMERGE = @MSGMERGE@ ++MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@ + NATIVE_LIB_DIRS = @NATIVE_LIB_DIRS@ + NM = @NM@ + NMEDIT = @NMEDIT@ +-NO_WERROR = @NO_WERROR@ + OBJDUMP = @OBJDUMP@ + OBJEXT = @OBJEXT@ + OTOOL = @OTOOL@ +@@ -457,7 +615,6 @@ PATH_SEPARATOR = @PATH_SEPARATOR@ + PKG_CONFIG = @PKG_CONFIG@ + PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ + PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +-POSUB = @POSUB@ + RANLIB = @RANLIB@ + SED = @SED@ + SET_MAKE = @SET_MAKE@ +@@ -473,18 +630,16 @@ TESTCTFLIB = @TESTCTFLIB@ + TESTSFRAMELIB = @TESTSFRAMELIB@ + USE_NLS = @USE_NLS@ + VERSION = @VERSION@ +-WARN_CFLAGS = @WARN_CFLAGS@ +-WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@ +-WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@ + XGETTEXT = @XGETTEXT@ ++XGETTEXT_015 = @XGETTEXT_015@ ++XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ + YACC = `if [ -f ../bison/bison ]; then echo ../bison/bison -y -L$(srcdir)/../bison/; else echo @YACC@; fi` + YFLAGS = -d +-ZSTD_CFLAGS = @ZSTD_CFLAGS@ +-ZSTD_LIBS = @ZSTD_LIBS@ + abs_builddir = @abs_builddir@ + abs_srcdir = @abs_srcdir@ + abs_top_builddir = @abs_top_builddir@ + abs_top_srcdir = @abs_top_srcdir@ ++ac_ct_AR = @ac_ct_AR@ + ac_ct_CC = @ac_ct_CC@ + ac_ct_CXX = @ac_ct_CXX@ + ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +@@ -502,7 +657,6 @@ build_vendor = @build_vendor@ + builddir = @builddir@ + datadir = @datadir@ + datarootdir = @datarootdir@ +-do_compare = @do_compare@ + docdir = @docdir@ + dvidir = @dvidir@ + elf_list_options = @elf_list_options@ +@@ -546,8 +700,6 @@ top_build_prefix = @top_build_prefix@ + top_builddir = @top_builddir@ + top_srcdir = @top_srcdir@ + use_sysroot = @use_sysroot@ +-zlibdir = @zlibdir@ +-zlibinc = @zlibinc@ + AUTOMAKE_OPTIONS = dejagnu no-texinfo.tex no-dist foreign info-in-builddir + ACLOCAL_AMFLAGS = -I .. -I ../config -I ../bfd + TEXINFO_TEX = ../texinfo/texinfo.tex +@@ -568,6 +720,8 @@ ELF_CLFAGS = -DELF_LIST_OPTIONS=@elf_list_options@ \ + -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \ + -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@ + ++WARN_CFLAGS = @WARN_CFLAGS@ ++NO_WERROR = @NO_WERROR@ + AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS) $(JANSSON_CFLAGS) $(ZSTD_CFLAGS) + + # We put the scripts in the directory $(scriptdir)/ldscripts. +@@ -653,6 +807,7 @@ LIBIBERTY = ../libiberty/libiberty.a + + # These all start with e so 'make clean' can find them. + ALL_EMULATION_SOURCES = \ ++ eelf_i386_sb.c \ + eaix5ppc.c \ + eaix5rs6.c \ + eaixppc.c \ +@@ -1095,8 +1250,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ +- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ +- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ ++ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ ++ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + + $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +@@ -1124,6 +1279,55 @@ distclean-hdr: + -rm -f config.h stamp-h1 + po/Makefile.in: $(top_builddir)/config.status $(top_srcdir)/po/Make-in + cd $(top_builddir) && $(SHELL) ./config.status $@ ++install-binPROGRAMS: $(bin_PROGRAMS) ++ @$(NORMAL_INSTALL) ++ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ ++ if test -n "$$list"; then \ ++ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ ++ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ ++ fi; \ ++ for p in $$list; do echo "$$p $$p"; done | \ ++ sed 's/$(EXEEXT)$$//' | \ ++ while read p p1; do if test -f $$p \ ++ || test -f $$p1 \ ++ ; then echo "$$p"; echo "$$p"; else :; fi; \ ++ done | \ ++ sed -e 'p;s,.*/,,;n;h' \ ++ -e 's|.*|.|' \ ++ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ ++ sed 'N;N;N;s,\n, ,g' | \ ++ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ ++ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ ++ if ($$2 == $$4) files[d] = files[d] " " $$1; \ ++ else { print "f", $$3 "/" $$4, $$1; } } \ ++ END { for (d in files) print "f", d, files[d] }' | \ ++ while read type dir files; do \ ++ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ ++ test -z "$$files" || { \ ++ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ ++ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ ++ } \ ++ ; done ++ ++uninstall-binPROGRAMS: ++ @$(NORMAL_UNINSTALL) ++ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ ++ files=`for p in $$list; do echo "$$p"; done | \ ++ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ ++ -e 's/$$/$(EXEEXT)/' \ ++ `; \ ++ test -n "$$list" || exit 0; \ ++ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ ++ cd "$(DESTDIR)$(bindir)" && rm -f $$files ++ ++clean-binPROGRAMS: ++ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ ++ echo " rm -f" $$list; \ ++ rm -f $$list || exit $$?; \ ++ test -n "$(EXEEXT)" || exit 0; \ ++ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ ++ echo " rm -f" $$list; \ ++ rm -f $$list + + install-bfdpluginLTLIBRARIES: $(bfdplugin_LTLIBRARIES) + @$(NORMAL_INSTALL) +@@ -1185,55 +1389,6 @@ libldtestplug3.la: $(libldtestplug3_la_OBJECTS) $(libldtestplug3_la_DEPENDENCIES + + libldtestplug4.la: $(libldtestplug4_la_OBJECTS) $(libldtestplug4_la_DEPENDENCIES) $(EXTRA_libldtestplug4_la_DEPENDENCIES) + $(AM_V_CCLD)$(libldtestplug4_la_LINK) $(libldtestplug4_la_OBJECTS) $(libldtestplug4_la_LIBADD) $(LIBS) +-install-binPROGRAMS: $(bin_PROGRAMS) +- @$(NORMAL_INSTALL) +- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ +- if test -n "$$list"; then \ +- echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ +- $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ +- fi; \ +- for p in $$list; do echo "$$p $$p"; done | \ +- sed 's/$(EXEEXT)$$//' | \ +- while read p p1; do if test -f $$p \ +- || test -f $$p1 \ +- ; then echo "$$p"; echo "$$p"; else :; fi; \ +- done | \ +- sed -e 'p;s,.*/,,;n;h' \ +- -e 's|.*|.|' \ +- -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ +- sed 'N;N;N;s,\n, ,g' | \ +- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ +- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ +- if ($$2 == $$4) files[d] = files[d] " " $$1; \ +- else { print "f", $$3 "/" $$4, $$1; } } \ +- END { for (d in files) print "f", d, files[d] }' | \ +- while read type dir files; do \ +- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ +- test -z "$$files" || { \ +- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ +- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ +- } \ +- ; done +- +-uninstall-binPROGRAMS: +- @$(NORMAL_UNINSTALL) +- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ +- files=`for p in $$list; do echo "$$p"; done | \ +- sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ +- -e 's/$$/$(EXEEXT)/' \ +- `; \ +- test -n "$$list" || exit 0; \ +- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ +- cd "$(DESTDIR)$(bindir)" && rm -f $$files +- +-clean-binPROGRAMS: +- @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ +- echo " rm -f" $$list; \ +- rm -f $$list || exit $$?; \ +- test -n "$(EXEEXT)" || exit 0; \ +- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ +- echo " rm -f" $$list; \ +- rm -f $$list + ldgram.h: ldgram.c + @if test ! -f $@; then rm -f ldgram.c; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) ldgram.c; else :; fi +@@ -1251,339 +1406,346 @@ mostlyclean-compile: + distclean-compile: + -rm -f *.tab.c + +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deffilep.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabib.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32b.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsdb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32b.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64pe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixrs6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealpha.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealphavms.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux_nps.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elfx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earm_wince_pe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fuchsia.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_fdpiceabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_phoenix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fuchsia.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmpe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr1.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr25.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr3.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr31.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr35.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr4.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr5.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr51.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecriself.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrislinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed10velf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_e.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_o.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30velf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_dlx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_spu.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_le.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_le.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_le.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_x86_64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32am33lin.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32b4300.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfin.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfinfd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmipn32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32cr16.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32crx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmipvxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmipvxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany_4x4.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32fr30.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frvfd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ft32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq2000.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32l4300.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32fd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32loongarch.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900n32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32m32c.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mb_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mbel_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mcore.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mep.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32metag.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblaze.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblazeel.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppchaiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcnto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcsim.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcvxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcwindiss.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rl78.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilepro.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32vax.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32visium.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_vms.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_s390.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64rdos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_ldso.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_iamcu.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_mipsel_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_s390.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_cloudabi.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_fbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_haiku.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sol2.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300hnelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300snelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxnelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppa64linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppalinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppanbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaobsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386aout.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386beos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386bsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386go32.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386lynx.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386moss.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386msdos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386nto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe_posix.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pep.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elfb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelfnbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em9s12zelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emcorepe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emoxiebox.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430X.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf16m.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf16m.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epc532macha.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdp11.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjlelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eppcmacos.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epruelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore3_elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore7_elf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esh.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_fd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_uclinux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshl.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_fd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_linux.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nto.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_vxworks.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshpe.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic30coff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff_onchip.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic4xcoff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic54xcoff.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850_rh850.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evanilla.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaxnbsd.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exgateelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez80.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldbuildid.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcref.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldctor.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelf.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelfgen.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldemul.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldexp.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldfile.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldgram.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlang.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex-wrapper.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmain.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmisc.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldver.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldwrite.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexsup.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdep_plugin.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug2_la-testplug2.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug3_la-testplug3.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug4_la-testplug4.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug_la-testplug.Plo@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mri.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdb.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-dll.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pep-dll.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deffilep.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64cloudabib.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elf32b.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64elfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64fbsdb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linux32b.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64linuxb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaarch64pe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5ppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaix5rs6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaixrs6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealpha.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ealphavms.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earclinux_nps.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earcv2elfx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earm_wince_pe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_fuchsia.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_eabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_linux_fdpiceabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nacl.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_phoenix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelf_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_fuchsia.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_eabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nacl.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmelfb_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmnto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/earmpe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr1.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr25.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr3.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr31.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr35.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr4.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr5.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr51.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega4.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecriself.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrislinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecskyelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed10velf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_e.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30v_o.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed30velf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_dlx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_sparc_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_spu.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_elf_le.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_le.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_tic6x_linux_le.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32_x86_64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32am33lin.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32b4300.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfin.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bfinfd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bmipn32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32briscv_ilp32f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32bsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32btsmipn32_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32cr16.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32crx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ebmipvxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32elmipvxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32epiphany_4x4.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32fr30.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32frvfd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ft32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ip2k.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq10.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32iq2000.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32l4300.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lm32fd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32loongarch.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900n32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32m32c.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mb_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mbel_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mcore.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mep.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32metag.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblaze.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32microblazeel.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32moxie.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mt.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32or1k_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppchaiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcnto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcsim.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcvxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ppcwindiss.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rl78.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32rx_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilegx_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32tilepro.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32vax.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32visium.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xstormy16.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_vms.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_s390.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_sparc_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64briscv_lp64f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64loongarch.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ppc_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64rdos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64tilegx_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_ldso.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_iamcu.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_mipsel_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_s390.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_cloudabi.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_fbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_haiku.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sol2.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300elf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300helf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300hnelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300self_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300snelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eh8300sxnelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppa64linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppalinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppanbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ehppaobsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386aout.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386beos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386bsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386go32.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386lynx.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386moss.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386msdos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386nto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pe_posix.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ei386pep.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32relf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em32rlelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc11elfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68hc12elfb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em68kelfnbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/em9s12zelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emcorepe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emmo.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10200.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emn10300.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emoxiebox.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430X.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emsp430elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf16m.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32belf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf16m.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ends32elf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enios2linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ens32knbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epc532macha.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdp11.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epjlelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eppcmacos.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epruelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore3_elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escore7_elf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esh.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_fd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_nto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_uclinux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshelf_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshl.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_fd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_linux.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_nto.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshlelf_vxworks.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eshpe.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic30coff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic3xcoff_onchip.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic4xcoff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etic54xcoff.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev850_rh850.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evanilla.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evaxnbsd.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exgateelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez80.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldbuildid.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcref.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldctor.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelf.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelfgen.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldemul.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldexp.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldfile.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldgram.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlang.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex-wrapper.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmain.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmisc.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldver.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldwrite.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexsup.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdep_plugin.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug2_la-testplug2.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug3_la-testplug3.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug4_la-testplug4.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libldtestplug_la-testplug.Plo@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mri.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pdb.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pe-dll.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pep-dll.Po@am__quote@ # am--include-marker ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin.Po@am__quote@ # am--include-marker ++ ++$(am__depfiles_remade): ++ @$(MKDIR_P) $(@D) ++ @echo '# dummy' >$@-t && $(am__mv) $@-t $@ ++ ++am--depfiles: $(am__depfiles_remade) + + .c.o: + @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@@ -1936,7 +2098,7 @@ site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) + @echo '# Do not edit here. If you wish to override these values' >>site.tmp + @echo '# edit the last section' >>site.tmp + @echo 'set srcdir "$(srcdir)"' >>site.tmp +- @echo "set objdir `pwd`" >>site.tmp ++ @echo "set objdir \"`pwd`\"" >>site.tmp + @echo 'set build_alias "$(build_alias)"' >>site.tmp + @echo 'set build_triplet $(build_triplet)' >>site.tmp + @echo 'set host_alias "$(host_alias)"' >>site.tmp +@@ -1966,16 +2128,17 @@ check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU + check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +-all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) $(PROGRAMS) $(MANS) \ ++all-am: Makefile $(INFO_DEPS) $(PROGRAMS) $(LTLIBRARIES) $(MANS) \ + config.h + installdirs: installdirs-recursive + installdirs-am: +- for dir in "$(DESTDIR)$(bfdplugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ ++ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bfdplugindir)" "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done + install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +-install-exec: install-exec-recursive ++install-exec: $(BUILT_SOURCES) ++ $(MAKE) $(AM_MAKEFLAGS) install-exec-recursive + install-data: install-data-recursive + uninstall: uninstall-recursive + +@@ -2022,7 +2185,340 @@ clean-am: clean-aminfo clean-bfdpluginLTLIBRARIES clean-binPROGRAMS \ + + distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) +- -rm -rf ./$(DEPDIR) ++ -rm -f ./$(DEPDIR)/deffilep.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabi.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabib.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64elfb.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsd.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsdb.Po ++ -rm -f ./$(DEPDIR)/eaarch64haiku.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64linuxb.Po ++ -rm -f ./$(DEPDIR)/eaarch64pe.Po ++ -rm -f ./$(DEPDIR)/eaix5ppc.Po ++ -rm -f ./$(DEPDIR)/eaix5rs6.Po ++ -rm -f ./$(DEPDIR)/eaixppc.Po ++ -rm -f ./$(DEPDIR)/eaixrs6.Po ++ -rm -f ./$(DEPDIR)/ealpha.Po ++ -rm -f ./$(DEPDIR)/ealphavms.Po ++ -rm -f ./$(DEPDIR)/earcelf.Po ++ -rm -f ./$(DEPDIR)/earclinux.Po ++ -rm -f ./$(DEPDIR)/earclinux_nps.Po ++ -rm -f ./$(DEPDIR)/earcv2elf.Po ++ -rm -f ./$(DEPDIR)/earcv2elfx.Po ++ -rm -f ./$(DEPDIR)/earm_wince_pe.Po ++ -rm -f ./$(DEPDIR)/earmelf.Po ++ -rm -f ./$(DEPDIR)/earmelf_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelf_haiku.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_phoenix.Po ++ -rm -f ./$(DEPDIR)/earmelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/earmelfb.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmnto.Po ++ -rm -f ./$(DEPDIR)/earmpe.Po ++ -rm -f ./$(DEPDIR)/eavr1.Po ++ -rm -f ./$(DEPDIR)/eavr2.Po ++ -rm -f ./$(DEPDIR)/eavr25.Po ++ -rm -f ./$(DEPDIR)/eavr3.Po ++ -rm -f ./$(DEPDIR)/eavr31.Po ++ -rm -f ./$(DEPDIR)/eavr35.Po ++ -rm -f ./$(DEPDIR)/eavr4.Po ++ -rm -f ./$(DEPDIR)/eavr5.Po ++ -rm -f ./$(DEPDIR)/eavr51.Po ++ -rm -f ./$(DEPDIR)/eavr6.Po ++ -rm -f ./$(DEPDIR)/eavrtiny.Po ++ -rm -f ./$(DEPDIR)/eavrxmega1.Po ++ -rm -f ./$(DEPDIR)/eavrxmega2.Po ++ -rm -f ./$(DEPDIR)/eavrxmega3.Po ++ -rm -f ./$(DEPDIR)/eavrxmega4.Po ++ -rm -f ./$(DEPDIR)/eavrxmega5.Po ++ -rm -f ./$(DEPDIR)/eavrxmega6.Po ++ -rm -f ./$(DEPDIR)/eavrxmega7.Po ++ -rm -f ./$(DEPDIR)/ecrisaout.Po ++ -rm -f ./$(DEPDIR)/ecriself.Po ++ -rm -f ./$(DEPDIR)/ecrislinux.Po ++ -rm -f ./$(DEPDIR)/ecskyelf.Po ++ -rm -f ./$(DEPDIR)/ecskyelf_linux.Po ++ -rm -f ./$(DEPDIR)/ed10velf.Po ++ -rm -f ./$(DEPDIR)/ed30v_e.Po ++ -rm -f ./$(DEPDIR)/ed30v_o.Po ++ -rm -f ./$(DEPDIR)/ed30velf.Po ++ -rm -f ./$(DEPDIR)/eelf32_dlx.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32_spu.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf32am33lin.Po ++ -rm -f ./$(DEPDIR)/eelf32b4300.Po ++ -rm -f ./$(DEPDIR)/eelf32bfin.Po ++ -rm -f ./$(DEPDIR)/eelf32bfinfd.Po ++ -rm -f ./$(DEPDIR)/eelf32bmip.Po ++ -rm -f ./$(DEPDIR)/eelf32bmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32bsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32cr16.Po ++ -rm -f ./$(DEPDIR)/eelf32crx.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32elmip.Po ++ -rm -f ./$(DEPDIR)/eelf32elmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany_4x4.Po ++ -rm -f ./$(DEPDIR)/eelf32fr30.Po ++ -rm -f ./$(DEPDIR)/eelf32frv.Po ++ -rm -f ./$(DEPDIR)/eelf32frvfd.Po ++ -rm -f ./$(DEPDIR)/eelf32ft32.Po ++ -rm -f ./$(DEPDIR)/eelf32ip2k.Po ++ -rm -f ./$(DEPDIR)/eelf32iq10.Po ++ -rm -f ./$(DEPDIR)/eelf32iq2000.Po ++ -rm -f ./$(DEPDIR)/eelf32l4300.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32fd.Po ++ -rm -f ./$(DEPDIR)/eelf32lmip.Po ++ -rm -f ./$(DEPDIR)/eelf32loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf32lppc.Po ++ -rm -f ./$(DEPDIR)/eelf32lppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900n32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32lsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32m32c.Po ++ -rm -f ./$(DEPDIR)/eelf32mb_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mbel_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mcore.Po ++ -rm -f ./$(DEPDIR)/eelf32mep.Po ++ -rm -f ./$(DEPDIR)/eelf32metag.Po ++ -rm -f ./$(DEPDIR)/eelf32microblaze.Po ++ -rm -f ./$(DEPDIR)/eelf32microblazeel.Po ++ -rm -f ./$(DEPDIR)/eelf32mipswindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32moxie.Po ++ -rm -f ./$(DEPDIR)/eelf32mt.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ppchaiku.Po ++ -rm -f ./$(DEPDIR)/eelf32ppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcwindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32rl78.Po ++ -rm -f ./$(DEPDIR)/eelf32rx.Po ++ -rm -f ./$(DEPDIR)/eelf32rx_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf32tilepro.Po ++ -rm -f ./$(DEPDIR)/eelf32vax.Po ++ -rm -f ./$(DEPDIR)/eelf32visium.Po ++ -rm -f ./$(DEPDIR)/eelf32xstormy16.Po ++ -rm -f ./$(DEPDIR)/eelf32xtensa.Po ++ -rm -f ./$(DEPDIR)/eelf32z80.Po ++ -rm -f ./$(DEPDIR)/eelf64_aix.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_vms.Po ++ -rm -f ./$(DEPDIR)/eelf64_s390.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_nbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64bmip.Po ++ -rm -f ./$(DEPDIR)/eelf64bpf.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64hppa.Po ++ -rm -f ./$(DEPDIR)/eelf64loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64mmix.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64rdos.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_ldso.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sb.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf_iamcu.Po ++ -rm -f ./$(DEPDIR)/eelf_mipsel_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_s390.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_cloudabi.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_sol2.Po ++ -rm -f ./$(DEPDIR)/eh8300elf.Po ++ -rm -f ./$(DEPDIR)/eh8300elf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300helf.Po ++ -rm -f ./$(DEPDIR)/eh8300helf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300hnelf.Po ++ -rm -f ./$(DEPDIR)/eh8300self.Po ++ -rm -f ./$(DEPDIR)/eh8300self_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300snelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300sxnelf.Po ++ -rm -f ./$(DEPDIR)/ehppa64linux.Po ++ -rm -f ./$(DEPDIR)/ehppaelf.Po ++ -rm -f ./$(DEPDIR)/ehppalinux.Po ++ -rm -f ./$(DEPDIR)/ehppanbsd.Po ++ -rm -f ./$(DEPDIR)/ehppaobsd.Po ++ -rm -f ./$(DEPDIR)/ei386aout.Po ++ -rm -f ./$(DEPDIR)/ei386beos.Po ++ -rm -f ./$(DEPDIR)/ei386bsd.Po ++ -rm -f ./$(DEPDIR)/ei386go32.Po ++ -rm -f ./$(DEPDIR)/ei386lynx.Po ++ -rm -f ./$(DEPDIR)/ei386moss.Po ++ -rm -f ./$(DEPDIR)/ei386msdos.Po ++ -rm -f ./$(DEPDIR)/ei386nto.Po ++ -rm -f ./$(DEPDIR)/ei386pe.Po ++ -rm -f ./$(DEPDIR)/ei386pe_posix.Po ++ -rm -f ./$(DEPDIR)/ei386pep.Po ++ -rm -f ./$(DEPDIR)/em32relf.Po ++ -rm -f ./$(DEPDIR)/em32relf_linux.Po ++ -rm -f ./$(DEPDIR)/em32rlelf.Po ++ -rm -f ./$(DEPDIR)/em32rlelf_linux.Po ++ -rm -f ./$(DEPDIR)/em68hc11elf.Po ++ -rm -f ./$(DEPDIR)/em68hc11elfb.Po ++ -rm -f ./$(DEPDIR)/em68hc12elf.Po ++ -rm -f ./$(DEPDIR)/em68hc12elfb.Po ++ -rm -f ./$(DEPDIR)/em68kelf.Po ++ -rm -f ./$(DEPDIR)/em68kelfnbsd.Po ++ -rm -f ./$(DEPDIR)/em9s12zelf.Po ++ -rm -f ./$(DEPDIR)/emcorepe.Po ++ -rm -f ./$(DEPDIR)/emmo.Po ++ -rm -f ./$(DEPDIR)/emn10200.Po ++ -rm -f ./$(DEPDIR)/emn10300.Po ++ -rm -f ./$(DEPDIR)/emoxiebox.Po ++ -rm -f ./$(DEPDIR)/emsp430X.Po ++ -rm -f ./$(DEPDIR)/emsp430elf.Po ++ -rm -f ./$(DEPDIR)/ends32belf.Po ++ -rm -f ./$(DEPDIR)/ends32belf16m.Po ++ -rm -f ./$(DEPDIR)/ends32belf_linux.Po ++ -rm -f ./$(DEPDIR)/ends32elf.Po ++ -rm -f ./$(DEPDIR)/ends32elf16m.Po ++ -rm -f ./$(DEPDIR)/ends32elf_linux.Po ++ -rm -f ./$(DEPDIR)/enios2elf.Po ++ -rm -f ./$(DEPDIR)/enios2linux.Po ++ -rm -f ./$(DEPDIR)/ens32knbsd.Po ++ -rm -f ./$(DEPDIR)/epc532macha.Po ++ -rm -f ./$(DEPDIR)/epdp11.Po ++ -rm -f ./$(DEPDIR)/epjelf.Po ++ -rm -f ./$(DEPDIR)/epjlelf.Po ++ -rm -f ./$(DEPDIR)/eppcmacos.Po ++ -rm -f ./$(DEPDIR)/epruelf.Po ++ -rm -f ./$(DEPDIR)/escore3_elf.Po ++ -rm -f ./$(DEPDIR)/escore7_elf.Po ++ -rm -f ./$(DEPDIR)/esh.Po ++ -rm -f ./$(DEPDIR)/eshelf.Po ++ -rm -f ./$(DEPDIR)/eshelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshelf_uclinux.Po ++ -rm -f ./$(DEPDIR)/eshelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshl.Po ++ -rm -f ./$(DEPDIR)/eshlelf.Po ++ -rm -f ./$(DEPDIR)/eshlelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshlelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshpe.Po ++ -rm -f ./$(DEPDIR)/etic30coff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff_onchip.Po ++ -rm -f ./$(DEPDIR)/etic4xcoff.Po ++ -rm -f ./$(DEPDIR)/etic54xcoff.Po ++ -rm -f ./$(DEPDIR)/ev850.Po ++ -rm -f ./$(DEPDIR)/ev850_rh850.Po ++ -rm -f ./$(DEPDIR)/evanilla.Po ++ -rm -f ./$(DEPDIR)/evaxnbsd.Po ++ -rm -f ./$(DEPDIR)/exgateelf.Po ++ -rm -f ./$(DEPDIR)/ez80.Po ++ -rm -f ./$(DEPDIR)/ez8001.Po ++ -rm -f ./$(DEPDIR)/ez8002.Po ++ -rm -f ./$(DEPDIR)/ldbuildid.Po ++ -rm -f ./$(DEPDIR)/ldcref.Po ++ -rm -f ./$(DEPDIR)/ldctor.Po ++ -rm -f ./$(DEPDIR)/ldelf.Po ++ -rm -f ./$(DEPDIR)/ldelfgen.Po ++ -rm -f ./$(DEPDIR)/ldemul.Po ++ -rm -f ./$(DEPDIR)/ldexp.Po ++ -rm -f ./$(DEPDIR)/ldfile.Po ++ -rm -f ./$(DEPDIR)/ldgram.Po ++ -rm -f ./$(DEPDIR)/ldlang.Po ++ -rm -f ./$(DEPDIR)/ldlex-wrapper.Po ++ -rm -f ./$(DEPDIR)/ldlex.Po ++ -rm -f ./$(DEPDIR)/ldmain.Po ++ -rm -f ./$(DEPDIR)/ldmisc.Po ++ -rm -f ./$(DEPDIR)/ldver.Po ++ -rm -f ./$(DEPDIR)/ldwrite.Po ++ -rm -f ./$(DEPDIR)/lexsup.Po ++ -rm -f ./$(DEPDIR)/libdep_plugin.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug2_la-testplug2.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug3_la-testplug3.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug4_la-testplug4.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug_la-testplug.Plo ++ -rm -f ./$(DEPDIR)/mri.Po ++ -rm -f ./$(DEPDIR)/pdb.Po ++ -rm -f ./$(DEPDIR)/pe-dll.Po ++ -rm -f ./$(DEPDIR)/pep-dll.Po ++ -rm -f ./$(DEPDIR)/plugin.Po + -rm -f Makefile + distclean-am: clean-am distclean-DEJAGNU distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ +@@ -2163,7 +2659,340 @@ installcheck-am: + maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache +- -rm -rf ./$(DEPDIR) ++ -rm -f ./$(DEPDIR)/deffilep.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabi.Po ++ -rm -f ./$(DEPDIR)/eaarch64cloudabib.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32.Po ++ -rm -f ./$(DEPDIR)/eaarch64elf32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64elfb.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsd.Po ++ -rm -f ./$(DEPDIR)/eaarch64fbsdb.Po ++ -rm -f ./$(DEPDIR)/eaarch64haiku.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32.Po ++ -rm -f ./$(DEPDIR)/eaarch64linux32b.Po ++ -rm -f ./$(DEPDIR)/eaarch64linuxb.Po ++ -rm -f ./$(DEPDIR)/eaarch64pe.Po ++ -rm -f ./$(DEPDIR)/eaix5ppc.Po ++ -rm -f ./$(DEPDIR)/eaix5rs6.Po ++ -rm -f ./$(DEPDIR)/eaixppc.Po ++ -rm -f ./$(DEPDIR)/eaixrs6.Po ++ -rm -f ./$(DEPDIR)/ealpha.Po ++ -rm -f ./$(DEPDIR)/ealphavms.Po ++ -rm -f ./$(DEPDIR)/earcelf.Po ++ -rm -f ./$(DEPDIR)/earclinux.Po ++ -rm -f ./$(DEPDIR)/earclinux_nps.Po ++ -rm -f ./$(DEPDIR)/earcv2elf.Po ++ -rm -f ./$(DEPDIR)/earcv2elfx.Po ++ -rm -f ./$(DEPDIR)/earm_wince_pe.Po ++ -rm -f ./$(DEPDIR)/earmelf.Po ++ -rm -f ./$(DEPDIR)/earmelf_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelf_haiku.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelf_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmelf_phoenix.Po ++ -rm -f ./$(DEPDIR)/earmelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/earmelfb.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fbsd.Po ++ -rm -f ./$(DEPDIR)/earmelfb_fuchsia.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_eabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_linux_fdpiceabi.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nacl.Po ++ -rm -f ./$(DEPDIR)/earmelfb_nbsd.Po ++ -rm -f ./$(DEPDIR)/earmnto.Po ++ -rm -f ./$(DEPDIR)/earmpe.Po ++ -rm -f ./$(DEPDIR)/eavr1.Po ++ -rm -f ./$(DEPDIR)/eavr2.Po ++ -rm -f ./$(DEPDIR)/eavr25.Po ++ -rm -f ./$(DEPDIR)/eavr3.Po ++ -rm -f ./$(DEPDIR)/eavr31.Po ++ -rm -f ./$(DEPDIR)/eavr35.Po ++ -rm -f ./$(DEPDIR)/eavr4.Po ++ -rm -f ./$(DEPDIR)/eavr5.Po ++ -rm -f ./$(DEPDIR)/eavr51.Po ++ -rm -f ./$(DEPDIR)/eavr6.Po ++ -rm -f ./$(DEPDIR)/eavrtiny.Po ++ -rm -f ./$(DEPDIR)/eavrxmega1.Po ++ -rm -f ./$(DEPDIR)/eavrxmega2.Po ++ -rm -f ./$(DEPDIR)/eavrxmega3.Po ++ -rm -f ./$(DEPDIR)/eavrxmega4.Po ++ -rm -f ./$(DEPDIR)/eavrxmega5.Po ++ -rm -f ./$(DEPDIR)/eavrxmega6.Po ++ -rm -f ./$(DEPDIR)/eavrxmega7.Po ++ -rm -f ./$(DEPDIR)/ecrisaout.Po ++ -rm -f ./$(DEPDIR)/ecriself.Po ++ -rm -f ./$(DEPDIR)/ecrislinux.Po ++ -rm -f ./$(DEPDIR)/ecskyelf.Po ++ -rm -f ./$(DEPDIR)/ecskyelf_linux.Po ++ -rm -f ./$(DEPDIR)/ed10velf.Po ++ -rm -f ./$(DEPDIR)/ed30v_e.Po ++ -rm -f ./$(DEPDIR)/ed30v_o.Po ++ -rm -f ./$(DEPDIR)/ed30velf.Po ++ -rm -f ./$(DEPDIR)/eelf32_dlx.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf32_sparc_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32_spu.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_elf_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_be.Po ++ -rm -f ./$(DEPDIR)/eelf32_tic6x_linux_le.Po ++ -rm -f ./$(DEPDIR)/eelf32_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf32am33lin.Po ++ -rm -f ./$(DEPDIR)/eelf32b4300.Po ++ -rm -f ./$(DEPDIR)/eelf32bfin.Po ++ -rm -f ./$(DEPDIR)/eelf32bfinfd.Po ++ -rm -f ./$(DEPDIR)/eelf32bmip.Po ++ -rm -f ./$(DEPDIR)/eelf32bmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32briscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32bsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32btsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32cr16.Po ++ -rm -f ./$(DEPDIR)/eelf32crx.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ebmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32elmip.Po ++ -rm -f ./$(DEPDIR)/eelf32elmipvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany.Po ++ -rm -f ./$(DEPDIR)/eelf32epiphany_4x4.Po ++ -rm -f ./$(DEPDIR)/eelf32fr30.Po ++ -rm -f ./$(DEPDIR)/eelf32frv.Po ++ -rm -f ./$(DEPDIR)/eelf32frvfd.Po ++ -rm -f ./$(DEPDIR)/eelf32ft32.Po ++ -rm -f ./$(DEPDIR)/eelf32ip2k.Po ++ -rm -f ./$(DEPDIR)/eelf32iq10.Po ++ -rm -f ./$(DEPDIR)/eelf32iq2000.Po ++ -rm -f ./$(DEPDIR)/eelf32l4300.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32.Po ++ -rm -f ./$(DEPDIR)/eelf32lm32fd.Po ++ -rm -f ./$(DEPDIR)/eelf32lmip.Po ++ -rm -f ./$(DEPDIR)/eelf32loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf32lppc.Po ++ -rm -f ./$(DEPDIR)/eelf32lppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32lppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900.Po ++ -rm -f ./$(DEPDIR)/eelf32lr5900n32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32.Po ++ -rm -f ./$(DEPDIR)/eelf32lriscv_ilp32f.Po ++ -rm -f ./$(DEPDIR)/eelf32lsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32.Po ++ -rm -f ./$(DEPDIR)/eelf32ltsmipn32_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32m32c.Po ++ -rm -f ./$(DEPDIR)/eelf32mb_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mbel_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32mcore.Po ++ -rm -f ./$(DEPDIR)/eelf32mep.Po ++ -rm -f ./$(DEPDIR)/eelf32metag.Po ++ -rm -f ./$(DEPDIR)/eelf32microblaze.Po ++ -rm -f ./$(DEPDIR)/eelf32microblazeel.Po ++ -rm -f ./$(DEPDIR)/eelf32mipswindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32moxie.Po ++ -rm -f ./$(DEPDIR)/eelf32mt.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k.Po ++ -rm -f ./$(DEPDIR)/eelf32or1k_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc.Po ++ -rm -f ./$(DEPDIR)/eelf32ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf32ppchaiku.Po ++ -rm -f ./$(DEPDIR)/eelf32ppclinux.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcnto.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcsim.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcvxworks.Po ++ -rm -f ./$(DEPDIR)/eelf32ppcwindiss.Po ++ -rm -f ./$(DEPDIR)/eelf32rl78.Po ++ -rm -f ./$(DEPDIR)/eelf32rx.Po ++ -rm -f ./$(DEPDIR)/eelf32rx_linux.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf32tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf32tilepro.Po ++ -rm -f ./$(DEPDIR)/eelf32vax.Po ++ -rm -f ./$(DEPDIR)/eelf32visium.Po ++ -rm -f ./$(DEPDIR)/eelf32xstormy16.Po ++ -rm -f ./$(DEPDIR)/eelf32xtensa.Po ++ -rm -f ./$(DEPDIR)/eelf32z80.Po ++ -rm -f ./$(DEPDIR)/eelf64_aix.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_ia64_vms.Po ++ -rm -f ./$(DEPDIR)/eelf64_s390.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64_sparc_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64alpha_nbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64bmip.Po ++ -rm -f ./$(DEPDIR)/eelf64bpf.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64briscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64btsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64hppa.Po ++ -rm -f ./$(DEPDIR)/eelf64loongarch.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc.Po ++ -rm -f ./$(DEPDIR)/eelf64lppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64.Po ++ -rm -f ./$(DEPDIR)/eelf64lriscv_lp64f.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip.Po ++ -rm -f ./$(DEPDIR)/eelf64ltsmip_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64mmix.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc.Po ++ -rm -f ./$(DEPDIR)/eelf64ppc_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf64rdos.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx.Po ++ -rm -f ./$(DEPDIR)/eelf64tilegx_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_be.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_ldso.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sb.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_sol2.Po ++ -rm -f ./$(DEPDIR)/eelf_i386_vxworks.Po ++ -rm -f ./$(DEPDIR)/eelf_iamcu.Po ++ -rm -f ./$(DEPDIR)/eelf_mipsel_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_s390.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_cloudabi.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_fbsd.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_haiku.Po ++ -rm -f ./$(DEPDIR)/eelf_x86_64_sol2.Po ++ -rm -f ./$(DEPDIR)/eh8300elf.Po ++ -rm -f ./$(DEPDIR)/eh8300elf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300helf.Po ++ -rm -f ./$(DEPDIR)/eh8300helf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300hnelf.Po ++ -rm -f ./$(DEPDIR)/eh8300self.Po ++ -rm -f ./$(DEPDIR)/eh8300self_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300snelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf.Po ++ -rm -f ./$(DEPDIR)/eh8300sxelf_linux.Po ++ -rm -f ./$(DEPDIR)/eh8300sxnelf.Po ++ -rm -f ./$(DEPDIR)/ehppa64linux.Po ++ -rm -f ./$(DEPDIR)/ehppaelf.Po ++ -rm -f ./$(DEPDIR)/ehppalinux.Po ++ -rm -f ./$(DEPDIR)/ehppanbsd.Po ++ -rm -f ./$(DEPDIR)/ehppaobsd.Po ++ -rm -f ./$(DEPDIR)/ei386aout.Po ++ -rm -f ./$(DEPDIR)/ei386beos.Po ++ -rm -f ./$(DEPDIR)/ei386bsd.Po ++ -rm -f ./$(DEPDIR)/ei386go32.Po ++ -rm -f ./$(DEPDIR)/ei386lynx.Po ++ -rm -f ./$(DEPDIR)/ei386moss.Po ++ -rm -f ./$(DEPDIR)/ei386msdos.Po ++ -rm -f ./$(DEPDIR)/ei386nto.Po ++ -rm -f ./$(DEPDIR)/ei386pe.Po ++ -rm -f ./$(DEPDIR)/ei386pe_posix.Po ++ -rm -f ./$(DEPDIR)/ei386pep.Po ++ -rm -f ./$(DEPDIR)/em32relf.Po ++ -rm -f ./$(DEPDIR)/em32relf_linux.Po ++ -rm -f ./$(DEPDIR)/em32rlelf.Po ++ -rm -f ./$(DEPDIR)/em32rlelf_linux.Po ++ -rm -f ./$(DEPDIR)/em68hc11elf.Po ++ -rm -f ./$(DEPDIR)/em68hc11elfb.Po ++ -rm -f ./$(DEPDIR)/em68hc12elf.Po ++ -rm -f ./$(DEPDIR)/em68hc12elfb.Po ++ -rm -f ./$(DEPDIR)/em68kelf.Po ++ -rm -f ./$(DEPDIR)/em68kelfnbsd.Po ++ -rm -f ./$(DEPDIR)/em9s12zelf.Po ++ -rm -f ./$(DEPDIR)/emcorepe.Po ++ -rm -f ./$(DEPDIR)/emmo.Po ++ -rm -f ./$(DEPDIR)/emn10200.Po ++ -rm -f ./$(DEPDIR)/emn10300.Po ++ -rm -f ./$(DEPDIR)/emoxiebox.Po ++ -rm -f ./$(DEPDIR)/emsp430X.Po ++ -rm -f ./$(DEPDIR)/emsp430elf.Po ++ -rm -f ./$(DEPDIR)/ends32belf.Po ++ -rm -f ./$(DEPDIR)/ends32belf16m.Po ++ -rm -f ./$(DEPDIR)/ends32belf_linux.Po ++ -rm -f ./$(DEPDIR)/ends32elf.Po ++ -rm -f ./$(DEPDIR)/ends32elf16m.Po ++ -rm -f ./$(DEPDIR)/ends32elf_linux.Po ++ -rm -f ./$(DEPDIR)/enios2elf.Po ++ -rm -f ./$(DEPDIR)/enios2linux.Po ++ -rm -f ./$(DEPDIR)/ens32knbsd.Po ++ -rm -f ./$(DEPDIR)/epc532macha.Po ++ -rm -f ./$(DEPDIR)/epdp11.Po ++ -rm -f ./$(DEPDIR)/epjelf.Po ++ -rm -f ./$(DEPDIR)/epjlelf.Po ++ -rm -f ./$(DEPDIR)/eppcmacos.Po ++ -rm -f ./$(DEPDIR)/epruelf.Po ++ -rm -f ./$(DEPDIR)/escore3_elf.Po ++ -rm -f ./$(DEPDIR)/escore7_elf.Po ++ -rm -f ./$(DEPDIR)/esh.Po ++ -rm -f ./$(DEPDIR)/eshelf.Po ++ -rm -f ./$(DEPDIR)/eshelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshelf_uclinux.Po ++ -rm -f ./$(DEPDIR)/eshelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshl.Po ++ -rm -f ./$(DEPDIR)/eshlelf.Po ++ -rm -f ./$(DEPDIR)/eshlelf_fd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_linux.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nbsd.Po ++ -rm -f ./$(DEPDIR)/eshlelf_nto.Po ++ -rm -f ./$(DEPDIR)/eshlelf_vxworks.Po ++ -rm -f ./$(DEPDIR)/eshpe.Po ++ -rm -f ./$(DEPDIR)/etic30coff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff.Po ++ -rm -f ./$(DEPDIR)/etic3xcoff_onchip.Po ++ -rm -f ./$(DEPDIR)/etic4xcoff.Po ++ -rm -f ./$(DEPDIR)/etic54xcoff.Po ++ -rm -f ./$(DEPDIR)/ev850.Po ++ -rm -f ./$(DEPDIR)/ev850_rh850.Po ++ -rm -f ./$(DEPDIR)/evanilla.Po ++ -rm -f ./$(DEPDIR)/evaxnbsd.Po ++ -rm -f ./$(DEPDIR)/exgateelf.Po ++ -rm -f ./$(DEPDIR)/ez80.Po ++ -rm -f ./$(DEPDIR)/ez8001.Po ++ -rm -f ./$(DEPDIR)/ez8002.Po ++ -rm -f ./$(DEPDIR)/ldbuildid.Po ++ -rm -f ./$(DEPDIR)/ldcref.Po ++ -rm -f ./$(DEPDIR)/ldctor.Po ++ -rm -f ./$(DEPDIR)/ldelf.Po ++ -rm -f ./$(DEPDIR)/ldelfgen.Po ++ -rm -f ./$(DEPDIR)/ldemul.Po ++ -rm -f ./$(DEPDIR)/ldexp.Po ++ -rm -f ./$(DEPDIR)/ldfile.Po ++ -rm -f ./$(DEPDIR)/ldgram.Po ++ -rm -f ./$(DEPDIR)/ldlang.Po ++ -rm -f ./$(DEPDIR)/ldlex-wrapper.Po ++ -rm -f ./$(DEPDIR)/ldlex.Po ++ -rm -f ./$(DEPDIR)/ldmain.Po ++ -rm -f ./$(DEPDIR)/ldmisc.Po ++ -rm -f ./$(DEPDIR)/ldver.Po ++ -rm -f ./$(DEPDIR)/ldwrite.Po ++ -rm -f ./$(DEPDIR)/lexsup.Po ++ -rm -f ./$(DEPDIR)/libdep_plugin.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug2_la-testplug2.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug3_la-testplug3.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug4_la-testplug4.Plo ++ -rm -f ./$(DEPDIR)/libldtestplug_la-testplug.Plo ++ -rm -f ./$(DEPDIR)/mri.Po ++ -rm -f ./$(DEPDIR)/pdb.Po ++ -rm -f ./$(DEPDIR)/pe-dll.Po ++ -rm -f ./$(DEPDIR)/pep-dll.Po ++ -rm -f ./$(DEPDIR)/plugin.Po + -rm -f Makefile + maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic +@@ -2188,21 +3017,22 @@ uninstall-am: uninstall-bfdpluginLTLIBRARIES uninstall-binPROGRAMS \ + uninstall-man: uninstall-man1 + + .MAKE: $(am__recursive_targets) all check check-am install install-am \ +- install-strip ++ install-exec install-strip + + .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ +- am--refresh check check-DEJAGNU check-am clean clean-aminfo \ +- clean-bfdpluginLTLIBRARIES clean-binPROGRAMS clean-cscope \ +- clean-generic clean-libtool clean-noinstLTLIBRARIES cscope \ +- cscopelist-am ctags ctags-am dist-info distclean \ +- distclean-DEJAGNU distclean-compile distclean-generic \ +- distclean-hdr distclean-libtool distclean-local distclean-tags \ +- dvi dvi-am html html-am html-local info info-am install \ +- install-am install-bfdpluginLTLIBRARIES install-binPROGRAMS \ +- install-data install-data-am install-data-local install-dvi \ +- install-dvi-am install-exec install-exec-am install-exec-local \ +- install-html install-html-am install-info install-info-am \ +- install-man install-man1 install-pdf install-pdf-am install-ps \ ++ am--depfiles am--refresh check check-DEJAGNU check-am clean \ ++ clean-aminfo clean-bfdpluginLTLIBRARIES clean-binPROGRAMS \ ++ clean-cscope clean-generic clean-libtool \ ++ clean-noinstLTLIBRARIES cscope cscopelist-am ctags ctags-am \ ++ dist-info distclean distclean-DEJAGNU distclean-compile \ ++ distclean-generic distclean-hdr distclean-libtool \ ++ distclean-local distclean-tags dvi dvi-am html html-am \ ++ html-local info info-am install install-am \ ++ install-bfdpluginLTLIBRARIES install-binPROGRAMS install-data \ ++ install-data-am install-data-local install-dvi install-dvi-am \ ++ install-exec install-exec-am install-exec-local install-html \ ++ install-html-am install-info install-info-am install-man \ ++ install-man1 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ +@@ -2444,6 +3274,8 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS) + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32xtensa.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32z80.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386.Pc@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_sb.Pc@am__quote@ ++#@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_x86_64_sb.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_be.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_fbsd.Pc@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf_i386_haiku.Pc@am__quote@ +diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 +index 893e973e..1cd19c59 100644 +--- a/ld/aclocal.m4 ++++ b/ld/aclocal.m4 +@@ -1,6 +1,6 @@ +-# generated automatically by aclocal 1.15.1 -*- Autoconf -*- ++# generated automatically by aclocal 1.16.5 -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -20,7 +20,9991 @@ You have another version of autoconf. It may work, but is not guaranteed to. + If you have problems, you may need to regenerate the build system entirely. + To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +-# Copyright (C) 2002-2017 Free Software Foundation, Inc. ++# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- ++# ++# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software ++# Foundation, Inc. ++# Written by Gordon Matzigkeit, 1996 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++m4_define([_LT_COPYING], [dnl ++# Copyright (C) 2014 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. ++ ++# GNU Libtool 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 of the License, or ++# (at your option) any later version. ++# ++# As a special exception to the GNU General Public License, if you ++# distribute this file as part of a program or library that is built ++# using GNU Libtool, you may include this file under the same ++# distribution terms that you use for the rest of that program. ++# ++# GNU Libtool 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, see <http://www.gnu.org/licenses/>. ++]) ++ ++# serial 59 LT_INIT ++ ++ ++# LT_PREREQ(VERSION) ++# ------------------ ++# Complain and exit if this libtool version is less that VERSION. ++m4_defun([LT_PREREQ], ++[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, ++ [m4_default([$3], ++ [m4_fatal([Libtool version $1 or higher is required], ++ 63)])], ++ [$2])]) ++ ++ ++# _LT_CHECK_BUILDDIR ++# ------------------ ++# Complain if the absolute build directory name contains unusual characters ++m4_defun([_LT_CHECK_BUILDDIR], ++[case `pwd` in ++ *\ * | *\ *) ++ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; ++esac ++]) ++ ++ ++# LT_INIT([OPTIONS]) ++# ------------------ ++AC_DEFUN([LT_INIT], ++[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK ++AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl ++AC_BEFORE([$0], [LT_LANG])dnl ++AC_BEFORE([$0], [LT_OUTPUT])dnl ++AC_BEFORE([$0], [LTDL_INIT])dnl ++m4_require([_LT_CHECK_BUILDDIR])dnl ++ ++dnl Autoconf doesn't catch unexpanded LT_ macros by default: ++m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl ++m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl ++dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 ++dnl unless we require an AC_DEFUNed macro: ++AC_REQUIRE([LTOPTIONS_VERSION])dnl ++AC_REQUIRE([LTSUGAR_VERSION])dnl ++AC_REQUIRE([LTVERSION_VERSION])dnl ++AC_REQUIRE([LTOBSOLETE_VERSION])dnl ++m4_require([_LT_PROG_LTMAIN])dnl ++ ++_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) ++ ++dnl Parse OPTIONS ++_LT_SET_OPTIONS([$0], [$1]) ++ ++# This can be used to rebuild libtool when needed ++LIBTOOL_DEPS=$ltmain ++ ++# Always use our own libtool. ++LIBTOOL='$(SHELL) $(top_builddir)/libtool' ++AC_SUBST(LIBTOOL)dnl ++ ++_LT_SETUP ++ ++# Only expand once: ++m4_define([LT_INIT]) ++])# LT_INIT ++ ++# Old names: ++AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) ++AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_PROG_LIBTOOL], []) ++dnl AC_DEFUN([AM_PROG_LIBTOOL], []) ++ ++ ++# _LT_PREPARE_CC_BASENAME ++# ----------------------- ++m4_defun([_LT_PREPARE_CC_BASENAME], [ ++# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. ++func_cc_basename () ++{ ++ for cc_temp in @S|@*""; do ++ case $cc_temp in ++ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; ++ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; ++ \-*) ;; ++ *) break;; ++ esac ++ done ++ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ++} ++])# _LT_PREPARE_CC_BASENAME ++ ++ ++# _LT_CC_BASENAME(CC) ++# ------------------- ++# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, ++# but that macro is also expanded into generated libtool script, which ++# arranges for $SED and $ECHO to be set by different means. ++m4_defun([_LT_CC_BASENAME], ++[m4_require([_LT_PREPARE_CC_BASENAME])dnl ++AC_REQUIRE([_LT_DECL_SED])dnl ++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl ++func_cc_basename $1 ++cc_basename=$func_cc_basename_result ++]) ++ ++ ++# _LT_FILEUTILS_DEFAULTS ++# ---------------------- ++# It is okay to use these file commands and assume they have been set ++# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. ++m4_defun([_LT_FILEUTILS_DEFAULTS], ++[: ${CP="cp -f"} ++: ${MV="mv -f"} ++: ${RM="rm -f"} ++])# _LT_FILEUTILS_DEFAULTS ++ ++ ++# _LT_SETUP ++# --------- ++m4_defun([_LT_SETUP], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl ++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl ++ ++_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl ++dnl ++_LT_DECL([], [host_alias], [0], [The host system])dnl ++_LT_DECL([], [host], [0])dnl ++_LT_DECL([], [host_os], [0])dnl ++dnl ++_LT_DECL([], [build_alias], [0], [The build system])dnl ++_LT_DECL([], [build], [0])dnl ++_LT_DECL([], [build_os], [0])dnl ++dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([LT_PATH_LD])dnl ++AC_REQUIRE([LT_PATH_NM])dnl ++dnl ++AC_REQUIRE([AC_PROG_LN_S])dnl ++test -z "$LN_S" && LN_S="ln -s" ++_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl ++dnl ++AC_REQUIRE([LT_CMD_MAX_LEN])dnl ++_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl ++_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl ++dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_CHECK_SHELL_FEATURES])dnl ++m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl ++m4_require([_LT_CMD_RELOAD])dnl ++m4_require([_LT_DECL_FILECMD])dnl ++m4_require([_LT_CHECK_MAGIC_METHOD])dnl ++m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl ++m4_require([_LT_CMD_OLD_ARCHIVE])dnl ++m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl ++m4_require([_LT_WITH_SYSROOT])dnl ++m4_require([_LT_CMD_TRUNCATE])dnl ++ ++_LT_CONFIG_LIBTOOL_INIT([ ++# See if we are running on zsh, and set the options that allow our ++# commands through without removal of \ escapes INIT. ++if test -n "\${ZSH_VERSION+set}"; then ++ setopt NO_GLOB_SUBST ++fi ++]) ++if test -n "${ZSH_VERSION+set}"; then ++ setopt NO_GLOB_SUBST ++fi ++ ++_LT_CHECK_OBJDIR ++ ++m4_require([_LT_TAG_COMPILER])dnl ++ ++case $host_os in ++aix3*) ++ # AIX sometimes has problems with the GCC collect2 program. For some ++ # reason, if we set the COLLECT_NAMES environment variable, the problems ++ # vanish in a puff of smoke. ++ if test set != "${COLLECT_NAMES+set}"; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++ fi ++ ;; ++esac ++ ++# Global variables: ++ofile=libtool ++can_build_shared=yes ++ ++# All known linkers require a '.a' archive for static linking (except MSVC and ++# ICC, which need '.lib'). ++libext=a ++ ++with_gnu_ld=$lt_cv_prog_gnu_ld ++ ++old_CC=$CC ++old_CFLAGS=$CFLAGS ++ ++# Set sane defaults for various variables ++test -z "$CC" && CC=cc ++test -z "$LTCC" && LTCC=$CC ++test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS ++test -z "$LD" && LD=ld ++test -z "$ac_objext" && ac_objext=o ++ ++_LT_CC_BASENAME([$compiler]) ++ ++# Only perform the check for file, if the check method requires it ++test -z "$MAGIC_CMD" && MAGIC_CMD=file ++case $deplibs_check_method in ++file_magic*) ++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then ++ _LT_PATH_MAGIC ++ fi ++ ;; ++esac ++ ++# Use C for the default configuration in the libtool script ++LT_SUPPORTED_TAG([CC]) ++_LT_LANG_C_CONFIG ++_LT_LANG_DEFAULT_CONFIG ++_LT_CONFIG_COMMANDS ++])# _LT_SETUP ++ ++ ++# _LT_PREPARE_SED_QUOTE_VARS ++# -------------------------- ++# Define a few sed substitution that help us do robust quoting. ++m4_defun([_LT_PREPARE_SED_QUOTE_VARS], ++[# Backslashify metacharacters that are still active within ++# double-quoted strings. ++sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' ++ ++# Same as above, but do not quote variable references. ++double_quote_subst='s/\([["`\\]]\)/\\\1/g' ++ ++# Sed substitution to delay expansion of an escaped shell variable in a ++# double_quote_subst'ed string. ++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' ++ ++# Sed substitution to delay expansion of an escaped single quote. ++delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' ++ ++# Sed substitution to avoid accidental globbing in evaled expressions ++no_glob_subst='s/\*/\\\*/g' ++]) ++ ++# _LT_PROG_LTMAIN ++# --------------- ++# Note that this code is called both from 'configure', and 'config.status' ++# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, ++# 'config.status' has no value for ac_aux_dir unless we are using Automake, ++# so we pass a copy along to make sure it has a sensible value anyway. ++m4_defun([_LT_PROG_LTMAIN], ++[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl ++_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ++ltmain=$ac_aux_dir/ltmain.sh ++])# _LT_PROG_LTMAIN ++ ++ ++ ++# So that we can recreate a full libtool script including additional ++# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS ++# in macros and then make a single call at the end using the 'libtool' ++# label. ++ ++ ++# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) ++# ---------------------------------------- ++# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. ++m4_define([_LT_CONFIG_LIBTOOL_INIT], ++[m4_ifval([$1], ++ [m4_append([_LT_OUTPUT_LIBTOOL_INIT], ++ [$1 ++])])]) ++ ++# Initialize. ++m4_define([_LT_OUTPUT_LIBTOOL_INIT]) ++ ++ ++# _LT_CONFIG_LIBTOOL([COMMANDS]) ++# ------------------------------ ++# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. ++m4_define([_LT_CONFIG_LIBTOOL], ++[m4_ifval([$1], ++ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], ++ [$1 ++])])]) ++ ++# Initialize. ++m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) ++ ++ ++# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) ++# ----------------------------------------------------- ++m4_defun([_LT_CONFIG_SAVE_COMMANDS], ++[_LT_CONFIG_LIBTOOL([$1]) ++_LT_CONFIG_LIBTOOL_INIT([$2]) ++]) ++ ++ ++# _LT_FORMAT_COMMENT([COMMENT]) ++# ----------------------------- ++# Add leading comment marks to the start of each line, and a trailing ++# full-stop to the whole comment if one is not present already. ++m4_define([_LT_FORMAT_COMMENT], ++[m4_ifval([$1], [ ++m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], ++ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) ++)]) ++ ++ ++ ++ ++ ++# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) ++# ------------------------------------------------------------------- ++# CONFIGNAME is the name given to the value in the libtool script. ++# VARNAME is the (base) name used in the configure script. ++# VALUE may be 0, 1 or 2 for a computed quote escaped value based on ++# VARNAME. Any other value will be used directly. ++m4_define([_LT_DECL], ++[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], ++ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], ++ [m4_ifval([$1], [$1], [$2])]) ++ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) ++ m4_ifval([$4], ++ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) ++ lt_dict_add_subkey([lt_decl_dict], [$2], ++ [tagged?], [m4_ifval([$5], [yes], [no])])]) ++]) ++ ++ ++# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) ++# -------------------------------------------------------- ++m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) ++ ++ ++# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) ++# ------------------------------------------------ ++m4_define([lt_decl_tag_varnames], ++[_lt_decl_filter([tagged?], [yes], $@)]) ++ ++ ++# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) ++# --------------------------------------------------------- ++m4_define([_lt_decl_filter], ++[m4_case([$#], ++ [0], [m4_fatal([$0: too few arguments: $#])], ++ [1], [m4_fatal([$0: too few arguments: $#: $1])], ++ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], ++ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], ++ [lt_dict_filter([lt_decl_dict], $@)])[]dnl ++]) ++ ++ ++# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) ++# -------------------------------------------------- ++m4_define([lt_decl_quote_varnames], ++[_lt_decl_filter([value], [1], $@)]) ++ ++ ++# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) ++# --------------------------------------------------- ++m4_define([lt_decl_dquote_varnames], ++[_lt_decl_filter([value], [2], $@)]) ++ ++ ++# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) ++# --------------------------------------------------- ++m4_define([lt_decl_varnames_tagged], ++[m4_assert([$# <= 2])dnl ++_$0(m4_quote(m4_default([$1], [[, ]])), ++ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), ++ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) ++m4_define([_lt_decl_varnames_tagged], ++[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) ++ ++ ++# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) ++# ------------------------------------------------ ++m4_define([lt_decl_all_varnames], ++[_$0(m4_quote(m4_default([$1], [[, ]])), ++ m4_if([$2], [], ++ m4_quote(lt_decl_varnames), ++ m4_quote(m4_shift($@))))[]dnl ++]) ++m4_define([_lt_decl_all_varnames], ++[lt_join($@, lt_decl_varnames_tagged([$1], ++ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ++]) ++ ++ ++# _LT_CONFIG_STATUS_DECLARE([VARNAME]) ++# ------------------------------------ ++# Quote a variable value, and forward it to 'config.status' so that its ++# declaration there will have the same value as in 'configure'. VARNAME ++# must have a single quote delimited value for this to work. ++m4_define([_LT_CONFIG_STATUS_DECLARE], ++[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) ++ ++ ++# _LT_CONFIG_STATUS_DECLARATIONS ++# ------------------------------ ++# We delimit libtool config variables with single quotes, so when ++# we write them to config.status, we have to be sure to quote all ++# embedded single quotes properly. In configure, this macro expands ++# each variable declared with _LT_DECL (and _LT_TAGDECL) into: ++# ++# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' ++m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], ++[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), ++ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) ++ ++ ++# _LT_LIBTOOL_TAGS ++# ---------------- ++# Output comment and list of tags supported by the script ++m4_defun([_LT_LIBTOOL_TAGS], ++[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl ++available_tags='_LT_TAGS'dnl ++]) ++ ++ ++# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) ++# ----------------------------------- ++# Extract the dictionary values for VARNAME (optionally with TAG) and ++# expand to a commented shell variable setting: ++# ++# # Some comment about what VAR is for. ++# visible_name=$lt_internal_name ++m4_define([_LT_LIBTOOL_DECLARE], ++[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], ++ [description])))[]dnl ++m4_pushdef([_libtool_name], ++ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl ++m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), ++ [0], [_libtool_name=[$]$1], ++ [1], [_libtool_name=$lt_[]$1], ++ [2], [_libtool_name=$lt_[]$1], ++ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl ++m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ++]) ++ ++ ++# _LT_LIBTOOL_CONFIG_VARS ++# ----------------------- ++# Produce commented declarations of non-tagged libtool config variables ++# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' ++# script. Tagged libtool config variables (even for the LIBTOOL CONFIG ++# section) are produced by _LT_LIBTOOL_TAG_VARS. ++m4_defun([_LT_LIBTOOL_CONFIG_VARS], ++[m4_foreach([_lt_var], ++ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), ++ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) ++ ++ ++# _LT_LIBTOOL_TAG_VARS(TAG) ++# ------------------------- ++m4_define([_LT_LIBTOOL_TAG_VARS], ++[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), ++ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) ++ ++ ++# _LT_TAGVAR(VARNAME, [TAGNAME]) ++# ------------------------------ ++m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) ++ ++ ++# _LT_CONFIG_COMMANDS ++# ------------------- ++# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of ++# variables for single and double quote escaping we saved from calls ++# to _LT_DECL, we can put quote escaped variables declarations ++# into 'config.status', and then the shell code to quote escape them in ++# for loops in 'config.status'. Finally, any additional code accumulated ++# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. ++m4_defun([_LT_CONFIG_COMMANDS], ++[AC_PROVIDE_IFELSE([LT_OUTPUT], ++ dnl If the libtool generation code has been placed in $CONFIG_LT, ++ dnl instead of duplicating it all over again into config.status, ++ dnl then we will have config.status run $CONFIG_LT later, so it ++ dnl needs to know what name is stored there: ++ [AC_CONFIG_COMMANDS([libtool], ++ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], ++ dnl If the libtool generation code is destined for config.status, ++ dnl expand the accumulated commands and init code now: ++ [AC_CONFIG_COMMANDS([libtool], ++ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ++])#_LT_CONFIG_COMMANDS ++ ++ ++# Initialize. ++m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], ++[ ++ ++# The HP-UX ksh and POSIX shell print the target directory to stdout ++# if CDPATH is set. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++sed_quote_subst='$sed_quote_subst' ++double_quote_subst='$double_quote_subst' ++delay_variable_subst='$delay_variable_subst' ++_LT_CONFIG_STATUS_DECLARATIONS ++LTCC='$LTCC' ++LTCFLAGS='$LTCFLAGS' ++compiler='$compiler_DEFAULT' ++ ++# A function that is used when there is no print builtin or printf. ++func_fallback_echo () ++{ ++ eval 'cat <<_LTECHO_EOF ++\$[]1 ++_LTECHO_EOF' ++} ++ ++# Quote evaled strings. ++for var in lt_decl_all_varnames([[ \ ++]], lt_decl_quote_varnames); do ++ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ *[[\\\\\\\`\\"\\\$]]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++# Double-quote double-evaled strings. ++for var in lt_decl_all_varnames([[ \ ++]], lt_decl_dquote_varnames); do ++ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in ++ *[[\\\\\\\`\\"\\\$]]*) ++ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ++ ;; ++ *) ++ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ++ ;; ++ esac ++done ++ ++_LT_OUTPUT_LIBTOOL_INIT ++]) ++ ++# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) ++# ------------------------------------ ++# Generate a child script FILE with all initialization necessary to ++# reuse the environment learned by the parent script, and make the ++# file executable. If COMMENT is supplied, it is inserted after the ++# '#!' sequence but before initialization text begins. After this ++# macro, additional text can be appended to FILE to form the body of ++# the child script. The macro ends with non-zero status if the ++# file could not be fully written (such as if the disk is full). ++m4_ifdef([AS_INIT_GENERATED], ++[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], ++[m4_defun([_LT_GENERATED_FILE_INIT], ++[m4_require([AS_PREPARE])]dnl ++[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl ++[lt_write_fail=0 ++cat >$1 <<_ASEOF || lt_write_fail=1 ++#! $SHELL ++# Generated by $as_me. ++$2 ++SHELL=\${CONFIG_SHELL-$SHELL} ++export SHELL ++_ASEOF ++cat >>$1 <<\_ASEOF || lt_write_fail=1 ++AS_SHELL_SANITIZE ++_AS_PREPARE ++exec AS_MESSAGE_FD>&1 ++_ASEOF ++test 0 = "$lt_write_fail" && chmod +x $1[]dnl ++m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT ++ ++# LT_OUTPUT ++# --------- ++# This macro allows early generation of the libtool script (before ++# AC_OUTPUT is called), incase it is used in configure for compilation ++# tests. ++AC_DEFUN([LT_OUTPUT], ++[: ${CONFIG_LT=./config.lt} ++AC_MSG_NOTICE([creating $CONFIG_LT]) ++_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], ++[# Run this file to recreate a libtool stub with the current configuration.]) ++ ++cat >>"$CONFIG_LT" <<\_LTEOF ++lt_cl_silent=false ++exec AS_MESSAGE_LOG_FD>>config.log ++{ ++ echo ++ AS_BOX([Running $as_me.]) ++} >&AS_MESSAGE_LOG_FD ++ ++lt_cl_help="\ ++'$as_me' creates a local libtool stub from the current configuration, ++for use in further configure time tests before the real libtool is ++generated. ++ ++Usage: $[0] [[OPTIONS]] ++ ++ -h, --help print this help, then exit ++ -V, --version print version number, then exit ++ -q, --quiet do not print progress messages ++ -d, --debug don't remove temporary files ++ ++Report bugs to <bug-libtool@gnu.org>." ++ ++lt_cl_version="\ ++m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl ++m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) ++configured by $[0], generated by m4_PACKAGE_STRING. ++ ++Copyright (C) 2011 Free Software Foundation, Inc. ++This config.lt script is free software; the Free Software Foundation ++gives unlimited permision to copy, distribute and modify it." ++ ++while test 0 != $[#] ++do ++ case $[1] in ++ --version | --v* | -V ) ++ echo "$lt_cl_version"; exit 0 ;; ++ --help | --h* | -h ) ++ echo "$lt_cl_help"; exit 0 ;; ++ --debug | --d* | -d ) ++ debug=: ;; ++ --quiet | --q* | --silent | --s* | -q ) ++ lt_cl_silent=: ;; ++ ++ -*) AC_MSG_ERROR([unrecognized option: $[1] ++Try '$[0] --help' for more information.]) ;; ++ ++ *) AC_MSG_ERROR([unrecognized argument: $[1] ++Try '$[0] --help' for more information.]) ;; ++ esac ++ shift ++done ++ ++if $lt_cl_silent; then ++ exec AS_MESSAGE_FD>/dev/null ++fi ++_LTEOF ++ ++cat >>"$CONFIG_LT" <<_LTEOF ++_LT_OUTPUT_LIBTOOL_COMMANDS_INIT ++_LTEOF ++ ++cat >>"$CONFIG_LT" <<\_LTEOF ++AC_MSG_NOTICE([creating $ofile]) ++_LT_OUTPUT_LIBTOOL_COMMANDS ++AS_EXIT(0) ++_LTEOF ++chmod +x "$CONFIG_LT" ++ ++# configure is writing to config.log, but config.lt does its own redirection, ++# appending to config.log, which fails on DOS, as config.log is still kept ++# open by configure. Here we exec the FD to /dev/null, effectively closing ++# config.log, so it can be properly (re)opened and appended to by config.lt. ++lt_cl_success=: ++test yes = "$silent" && ++ lt_config_lt_args="$lt_config_lt_args --quiet" ++exec AS_MESSAGE_LOG_FD>/dev/null ++$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false ++exec AS_MESSAGE_LOG_FD>>config.log ++$lt_cl_success || AS_EXIT(1) ++])# LT_OUTPUT ++ ++ ++# _LT_CONFIG(TAG) ++# --------------- ++# If TAG is the built-in tag, create an initial libtool script with a ++# default configuration from the untagged config vars. Otherwise add code ++# to config.status for appending the configuration named by TAG from the ++# matching tagged config vars. ++m4_defun([_LT_CONFIG], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++_LT_CONFIG_SAVE_COMMANDS([ ++ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl ++ m4_if(_LT_TAG, [C], [ ++ # See if we are running on zsh, and set the options that allow our ++ # commands through without removal of \ escapes. ++ if test -n "${ZSH_VERSION+set}"; then ++ setopt NO_GLOB_SUBST ++ fi ++ ++ cfgfile=${ofile}T ++ trap "$RM \"$cfgfile\"; exit 1" 1 2 15 ++ $RM "$cfgfile" ++ ++ cat <<_LT_EOF >> "$cfgfile" ++#! $SHELL ++# Generated automatically by $as_me ($PACKAGE) $VERSION ++# NOTE: Changes made to this file will be lost: look at ltmain.sh. ++ ++# Provide generalized library-building support services. ++# Written by Gordon Matzigkeit, 1996 ++ ++_LT_COPYING ++_LT_LIBTOOL_TAGS ++ ++# Configured defaults for sys_lib_dlsearch_path munging. ++: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} ++ ++# ### BEGIN LIBTOOL CONFIG ++_LT_LIBTOOL_CONFIG_VARS ++_LT_LIBTOOL_TAG_VARS ++# ### END LIBTOOL CONFIG ++ ++_LT_EOF ++ ++ cat <<'_LT_EOF' >> "$cfgfile" ++ ++# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE ++ ++_LT_PREPARE_MUNGE_PATH_LIST ++_LT_PREPARE_CC_BASENAME ++ ++# ### END FUNCTIONS SHARED WITH CONFIGURE ++ ++_LT_EOF ++ ++ case $host_os in ++ aix3*) ++ cat <<\_LT_EOF >> "$cfgfile" ++# AIX sometimes has problems with the GCC collect2 program. For some ++# reason, if we set the COLLECT_NAMES environment variable, the problems ++# vanish in a puff of smoke. ++if test set != "${COLLECT_NAMES+set}"; then ++ COLLECT_NAMES= ++ export COLLECT_NAMES ++fi ++_LT_EOF ++ ;; ++ esac ++ ++ _LT_PROG_LTMAIN ++ ++ # We use sed instead of cat because bash on DJGPP gets confused if ++ # if finds mixed CR/LF and LF-only lines. Since sed operates in ++ # text mode, it properly converts lines to CR/LF. This bash problem ++ # is reportedly fixed, but why not run on old versions too? ++ $SED '$q' "$ltmain" >> "$cfgfile" \ ++ || (rm -f "$cfgfile"; exit 1) ++ ++ mv -f "$cfgfile" "$ofile" || ++ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") ++ chmod +x "$ofile" ++], ++[cat <<_LT_EOF >> "$ofile" ++ ++dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded ++dnl in a comment (ie after a #). ++# ### BEGIN LIBTOOL TAG CONFIG: $1 ++_LT_LIBTOOL_TAG_VARS(_LT_TAG) ++# ### END LIBTOOL TAG CONFIG: $1 ++_LT_EOF ++])dnl /m4_if ++], ++[m4_if([$1], [], [ ++ PACKAGE='$PACKAGE' ++ VERSION='$VERSION' ++ RM='$RM' ++ ofile='$ofile'], []) ++])dnl /_LT_CONFIG_SAVE_COMMANDS ++])# _LT_CONFIG ++ ++ ++# LT_SUPPORTED_TAG(TAG) ++# --------------------- ++# Trace this macro to discover what tags are supported by the libtool ++# --tag option, using: ++# autoconf --trace 'LT_SUPPORTED_TAG:$1' ++AC_DEFUN([LT_SUPPORTED_TAG], []) ++ ++ ++# C support is built-in for now ++m4_define([_LT_LANG_C_enabled], []) ++m4_define([_LT_TAGS], []) ++ ++ ++# LT_LANG(LANG) ++# ------------- ++# Enable libtool support for the given language if not already enabled. ++AC_DEFUN([LT_LANG], ++[AC_BEFORE([$0], [LT_OUTPUT])dnl ++m4_case([$1], ++ [C], [_LT_LANG(C)], ++ [C++], [_LT_LANG(CXX)], ++ [Go], [_LT_LANG(GO)], ++ [Java], [_LT_LANG(GCJ)], ++ [Fortran 77], [_LT_LANG(F77)], ++ [Fortran], [_LT_LANG(FC)], ++ [Windows Resource], [_LT_LANG(RC)], ++ [m4_ifdef([_LT_LANG_]$1[_CONFIG], ++ [_LT_LANG($1)], ++ [m4_fatal([$0: unsupported language: "$1"])])])dnl ++])# LT_LANG ++ ++ ++# _LT_LANG(LANGNAME) ++# ------------------ ++m4_defun([_LT_LANG], ++[m4_ifdef([_LT_LANG_]$1[_enabled], [], ++ [LT_SUPPORTED_TAG([$1])dnl ++ m4_append([_LT_TAGS], [$1 ])dnl ++ m4_define([_LT_LANG_]$1[_enabled], [])dnl ++ _LT_LANG_$1_CONFIG($1)])dnl ++])# _LT_LANG ++ ++ ++m4_ifndef([AC_PROG_GO], [ ++# NOTE: This macro has been submitted for inclusion into # ++# GNU Autoconf as AC_PROG_GO. When it is available in # ++# a released version of Autoconf we should remove this # ++# macro and use it instead. # ++m4_defun([AC_PROG_GO], ++[AC_LANG_PUSH(Go)dnl ++AC_ARG_VAR([GOC], [Go compiler command])dnl ++AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl ++_AC_ARG_VAR_LDFLAGS()dnl ++AC_CHECK_TOOL(GOC, gccgo) ++if test -z "$GOC"; then ++ if test -n "$ac_tool_prefix"; then ++ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) ++ fi ++fi ++if test -z "$GOC"; then ++ AC_CHECK_PROG(GOC, gccgo, gccgo, false) ++fi ++])#m4_defun ++])#m4_ifndef ++ ++ ++# _LT_LANG_DEFAULT_CONFIG ++# ----------------------- ++m4_defun([_LT_LANG_DEFAULT_CONFIG], ++[AC_PROVIDE_IFELSE([AC_PROG_CXX], ++ [LT_LANG(CXX)], ++ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) ++ ++AC_PROVIDE_IFELSE([AC_PROG_F77], ++ [LT_LANG(F77)], ++ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) ++ ++AC_PROVIDE_IFELSE([AC_PROG_FC], ++ [LT_LANG(FC)], ++ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) ++ ++dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal ++dnl pulling things in needlessly. ++AC_PROVIDE_IFELSE([AC_PROG_GCJ], ++ [LT_LANG(GCJ)], ++ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], ++ [LT_LANG(GCJ)], ++ [AC_PROVIDE_IFELSE([LT_PROG_GCJ], ++ [LT_LANG(GCJ)], ++ [m4_ifdef([AC_PROG_GCJ], ++ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) ++ m4_ifdef([A][M_PROG_GCJ], ++ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) ++ m4_ifdef([LT_PROG_GCJ], ++ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) ++ ++AC_PROVIDE_IFELSE([AC_PROG_GO], ++ [LT_LANG(GO)], ++ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) ++ ++AC_PROVIDE_IFELSE([LT_PROG_RC], ++ [LT_LANG(RC)], ++ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ++])# _LT_LANG_DEFAULT_CONFIG ++ ++# Obsolete macros: ++AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) ++AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) ++AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) ++AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) ++AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_CXX], []) ++dnl AC_DEFUN([AC_LIBTOOL_F77], []) ++dnl AC_DEFUN([AC_LIBTOOL_FC], []) ++dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) ++dnl AC_DEFUN([AC_LIBTOOL_RC], []) ++ ++ ++# _LT_TAG_COMPILER ++# ---------------- ++m4_defun([_LT_TAG_COMPILER], ++[AC_REQUIRE([AC_PROG_CC])dnl ++ ++_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl ++_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl ++_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl ++_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl ++ ++# If no C compiler was specified, use CC. ++LTCC=${LTCC-"$CC"} ++ ++# If no C compiler flags were specified, use CFLAGS. ++LTCFLAGS=${LTCFLAGS-"$CFLAGS"} ++ ++# Allow CC to be a program name with arguments. ++compiler=$CC ++])# _LT_TAG_COMPILER ++ ++ ++# _LT_COMPILER_BOILERPLATE ++# ------------------------ ++# Check for compiler boilerplate output or warnings with ++# the simple compiler test code. ++m4_defun([_LT_COMPILER_BOILERPLATE], ++[m4_require([_LT_DECL_SED])dnl ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_compile_test_code" >conftest.$ac_ext ++eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_compiler_boilerplate=`cat conftest.err` ++$RM conftest* ++])# _LT_COMPILER_BOILERPLATE ++ ++ ++# _LT_LINKER_BOILERPLATE ++# ---------------------- ++# Check for linker boilerplate output or warnings with ++# the simple link test code. ++m4_defun([_LT_LINKER_BOILERPLATE], ++[m4_require([_LT_DECL_SED])dnl ++ac_outfile=conftest.$ac_objext ++echo "$lt_simple_link_test_code" >conftest.$ac_ext ++eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err ++_lt_linker_boilerplate=`cat conftest.err` ++$RM -r conftest* ++])# _LT_LINKER_BOILERPLATE ++ ++# _LT_REQUIRED_DARWIN_CHECKS ++# ------------------------- ++m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ ++ case $host_os in ++ rhapsody* | darwin*) ++ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) ++ AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) ++ AC_CHECK_TOOL([LIPO], [lipo], [:]) ++ AC_CHECK_TOOL([OTOOL], [otool], [:]) ++ AC_CHECK_TOOL([OTOOL64], [otool64], [:]) ++ _LT_DECL([], [DSYMUTIL], [1], ++ [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) ++ _LT_DECL([], [NMEDIT], [1], ++ [Tool to change global to local symbols on Mac OS X]) ++ _LT_DECL([], [LIPO], [1], ++ [Tool to manipulate fat objects and archives on Mac OS X]) ++ _LT_DECL([], [OTOOL], [1], ++ [ldd/readelf like tool for Mach-O binaries on Mac OS X]) ++ _LT_DECL([], [OTOOL64], [1], ++ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) ++ ++ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], ++ [lt_cv_apple_cc_single_mod=no ++ if test -z "$LT_MULTI_MODULE"; then ++ # By default we will add the -single_module flag. You can override ++ # by either setting the environment variable LT_MULTI_MODULE ++ # non-empty at configure time, or by adding -multi_module to the ++ # link flags. ++ rm -rf libconftest.dylib* ++ echo "int foo(void){return 1;}" > conftest.c ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD ++ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ ++ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err ++ _lt_result=$? ++ # If there is a non-empty error log, and "single_module" ++ # appears in it, assume the flag caused a linker warning ++ if test -s conftest.err && $GREP single_module conftest.err; then ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ # Otherwise, if the output was created with a 0 exit code from ++ # the compiler, it worked. ++ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then ++ lt_cv_apple_cc_single_mod=yes ++ else ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ fi ++ rm -rf libconftest.dylib* ++ rm -f conftest.* ++ fi]) ++ ++ AC_CACHE_CHECK([for -exported_symbols_list linker flag], ++ [lt_cv_ld_exported_symbols_list], ++ [lt_cv_ld_exported_symbols_list=no ++ save_LDFLAGS=$LDFLAGS ++ echo "_main" > conftest.sym ++ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], ++ [lt_cv_ld_exported_symbols_list=yes], ++ [lt_cv_ld_exported_symbols_list=no]) ++ LDFLAGS=$save_LDFLAGS ++ ]) ++ ++ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], ++ [lt_cv_ld_force_load=no ++ cat > conftest.c << _LT_EOF ++int forced_loaded() { return 2;} ++_LT_EOF ++ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD ++ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD ++ echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD ++ $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD ++ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD ++ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD ++ cat > conftest.c << _LT_EOF ++int main() { return 0;} ++_LT_EOF ++ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD ++ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err ++ _lt_result=$? ++ if test -s conftest.err && $GREP force_load conftest.err; then ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then ++ lt_cv_ld_force_load=yes ++ else ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ fi ++ rm -f conftest.err libconftest.a conftest conftest.c ++ rm -rf conftest.dSYM ++ ]) ++ case $host_os in ++ rhapsody* | darwin1.[[012]]) ++ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; ++ darwin1.*) ++ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; ++ darwin*) ++ case $MACOSX_DEPLOYMENT_TARGET,$host in ++ 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) ++ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; ++ *) ++ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; ++ esac ++ ;; ++ esac ++ if test yes = "$lt_cv_apple_cc_single_mod"; then ++ _lt_dar_single_mod='$single_module' ++ fi ++ if test yes = "$lt_cv_ld_exported_symbols_list"; then ++ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' ++ else ++ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' ++ fi ++ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then ++ _lt_dsymutil='~$DSYMUTIL $lib || :' ++ else ++ _lt_dsymutil= ++ fi ++ ;; ++ esac ++]) ++ ++ ++# _LT_DARWIN_LINKER_FEATURES([TAG]) ++# --------------------------------- ++# Checks for linker and compiler features on darwin ++m4_defun([_LT_DARWIN_LINKER_FEATURES], ++[ ++ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_automatic, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ if test yes = "$lt_cv_ld_force_load"; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' ++ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], ++ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='' ++ fi ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined ++ case $cc_basename in ++ ifort*|nagfor*) _lt_dar_can_shared=yes ;; ++ *) _lt_dar_can_shared=$GCC ;; ++ esac ++ if test yes = "$_lt_dar_can_shared"; then ++ output_verbose_link_cmd=func_echo_all ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" ++ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" ++ _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" ++ m4_if([$1], [CXX], ++[ if test yes != "$lt_cv_apple_cc_single_mod"; then ++ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" ++ fi ++],[]) ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++]) ++ ++# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) ++# ---------------------------------- ++# Links a minimal program and checks the executable ++# for the system default hardcoded library path. In most cases, ++# this is /usr/lib:/lib, but when the MPI compilers are used ++# the location of the communication and MPI libs are included too. ++# If we don't find anything, use the default library path according ++# to the aix ld manual. ++# Store the results from the different compilers for each TAGNAME. ++# Allow to override them for all tags through lt_cv_aix_libpath. ++m4_defun([_LT_SYS_MODULE_PATH_AIX], ++[m4_require([_LT_DECL_SED])dnl ++if test set = "${lt_cv_aix_libpath+set}"; then ++ aix_libpath=$lt_cv_aix_libpath ++else ++ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], ++ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ ++ lt_aix_libpath_sed='[ ++ /Import File Strings/,/^$/ { ++ /^0/ { ++ s/^0 *\([^ ]*\) *$/\1/ ++ p ++ } ++ }]' ++ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++ # Check for a 64-bit object if we didn't find anything. ++ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then ++ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` ++ fi],[]) ++ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then ++ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib ++ fi ++ ]) ++ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) ++fi ++])# _LT_SYS_MODULE_PATH_AIX ++ ++ ++# _LT_SHELL_INIT(ARG) ++# ------------------- ++m4_define([_LT_SHELL_INIT], ++[m4_divert_text([M4SH-INIT], [$1 ++])])# _LT_SHELL_INIT ++ ++ ++ ++# _LT_PROG_ECHO_BACKSLASH ++# ----------------------- ++# Find how we can fake an echo command that does not interpret backslash. ++# In particular, with Autoconf 2.60 or later we add some code to the start ++# of the generated configure script that will find a shell with a builtin ++# printf (that we can use as an echo command). ++m4_defun([_LT_PROG_ECHO_BACKSLASH], ++[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ++ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO ++ ++AC_MSG_CHECKING([how to print strings]) ++# Test print first, because it will be a builtin if present. ++if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ ++ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ++ ECHO='print -r --' ++elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ++ ECHO='printf %s\n' ++else ++ # Use this function as a fallback that always works. ++ func_fallback_echo () ++ { ++ eval 'cat <<_LTECHO_EOF ++$[]1 ++_LTECHO_EOF' ++ } ++ ECHO='func_fallback_echo' ++fi ++ ++# func_echo_all arg... ++# Invoke $ECHO with all args, space-separated. ++func_echo_all () ++{ ++ $ECHO "$*" ++} ++ ++case $ECHO in ++ printf*) AC_MSG_RESULT([printf]) ;; ++ print*) AC_MSG_RESULT([print -r]) ;; ++ *) AC_MSG_RESULT([cat]) ;; ++esac ++ ++m4_ifdef([_AS_DETECT_SUGGESTED], ++[_AS_DETECT_SUGGESTED([ ++ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ++ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ++ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ++ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO ++ PATH=/empty FPATH=/empty; export PATH FPATH ++ test "X`printf %s $ECHO`" = "X$ECHO" \ ++ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) ++ ++_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) ++_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ++])# _LT_PROG_ECHO_BACKSLASH ++ ++ ++# _LT_WITH_SYSROOT ++# ---------------- ++AC_DEFUN([_LT_WITH_SYSROOT], ++[m4_require([_LT_DECL_SED])dnl ++AC_MSG_CHECKING([for sysroot]) ++AC_ARG_WITH([sysroot], ++[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], ++ [Search for dependent libraries within DIR (or the compiler's sysroot ++ if not specified).])], ++[], [with_sysroot=no]) ++ ++dnl lt_sysroot will always be passed unquoted. We quote it here ++dnl in case the user passed a directory name. ++lt_sysroot= ++case $with_sysroot in #( ++ yes) ++ if test yes = "$GCC"; then ++ lt_sysroot=`$CC --print-sysroot 2>/dev/null` ++ fi ++ ;; #( ++ /*) ++ lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ++ ;; #( ++ no|'') ++ ;; #( ++ *) ++ AC_MSG_RESULT([$with_sysroot]) ++ AC_MSG_ERROR([The sysroot must be an absolute path.]) ++ ;; ++esac ++ ++ AC_MSG_RESULT([${lt_sysroot:-no}]) ++_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl ++[dependent libraries, and where our libraries should be installed.])]) ++ ++# _LT_ENABLE_LOCK ++# --------------- ++m4_defun([_LT_ENABLE_LOCK], ++[AC_ARG_ENABLE([libtool-lock], ++ [AS_HELP_STRING([--disable-libtool-lock], ++ [avoid locking (might break parallel builds)])]) ++test no = "$enable_libtool_lock" || enable_libtool_lock=yes ++ ++# Some flags need to be propagated to the compiler or linker for good ++# libtool support. ++case $host in ++ia64-*-hpux*) ++ # Find out what ABI is being produced by ac_compile, and set mode ++ # options accordingly. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `$FILECMD conftest.$ac_objext` in ++ *ELF-32*) ++ HPUX_IA64_MODE=32 ++ ;; ++ *ELF-64*) ++ HPUX_IA64_MODE=64 ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++*-*-irix6*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. ++ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ if test yes = "$lt_cv_prog_gnu_ld"; then ++ case `$FILECMD conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -melf32bsmip" ++ ;; ++ *N32*) ++ LD="${LD-ld} -melf32bmipn32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -melf64bmip" ++ ;; ++ esac ++ else ++ case `$FILECMD conftest.$ac_objext` in ++ *32-bit*) ++ LD="${LD-ld} -32" ++ ;; ++ *N32*) ++ LD="${LD-ld} -n32" ++ ;; ++ *64-bit*) ++ LD="${LD-ld} -64" ++ ;; ++ esac ++ fi ++ fi ++ rm -rf conftest* ++ ;; ++ ++mips64*-*linux*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. ++ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ emul=elf ++ case `$FILECMD conftest.$ac_objext` in ++ *32-bit*) ++ emul="${emul}32" ++ ;; ++ *64-bit*) ++ emul="${emul}64" ++ ;; ++ esac ++ case `$FILECMD conftest.$ac_objext` in ++ *MSB*) ++ emul="${emul}btsmip" ++ ;; ++ *LSB*) ++ emul="${emul}ltsmip" ++ ;; ++ esac ++ case `$FILECMD conftest.$ac_objext` in ++ *N32*) ++ emul="${emul}n32" ++ ;; ++ esac ++ LD="${LD-ld} -m $emul" ++ fi ++ rm -rf conftest* ++ ;; ++ ++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ ++s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. Note that the listed cases only cover the ++ # situations where additional linker options are needed (such as when ++ # doing 32-bit compilation for a host where ld defaults to 64-bit, or ++ # vice versa); the common cases where no linker options are needed do ++ # not appear in the list. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `$FILECMD conftest.o` in ++ *32-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_i386_fbsd" ++ ;; ++ x86_64-*linux*) ++ case `$FILECMD conftest.o` in ++ *x86-64*) ++ LD="${LD-ld} -m elf32_x86_64" ++ ;; ++ *) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++ esac ++ ;; ++ powerpc64le-*linux*) ++ LD="${LD-ld} -m elf32lppclinux" ++ ;; ++ powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++ LD="${LD-ld} -m elf_s390" ++ ;; ++ sparc64-*linux*) ++ LD="${LD-ld} -m elf32_sparc" ++ ;; ++ esac ++ ;; ++ *64-bit*) ++ case $host in ++ x86_64-*kfreebsd*-gnu) ++ LD="${LD-ld} -m elf_x86_64_fbsd" ++ ;; ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ powerpcle-*linux*) ++ LD="${LD-ld} -m elf64lppc" ++ ;; ++ powerpc-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*|s390*-*tpf*) ++ LD="${LD-ld} -m elf64_s390" ++ ;; ++ sparc*-*linux*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++ ++*-*-sco3.2v5*) ++ # On SCO OpenServer 5, we need -belf to get full-featured binaries. ++ SAVE_CFLAGS=$CFLAGS ++ CFLAGS="$CFLAGS -belf" ++ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, ++ [AC_LANG_PUSH(C) ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) ++ AC_LANG_POP]) ++ if test yes != "$lt_cv_cc_needs_belf"; then ++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf ++ CFLAGS=$SAVE_CFLAGS ++ fi ++ ;; ++*-*solaris*) ++ # Find out what ABI is being produced by ac_compile, and set linker ++ # options accordingly. ++ echo 'int i;' > conftest.$ac_ext ++ if AC_TRY_EVAL(ac_compile); then ++ case `$FILECMD conftest.o` in ++ *64-bit*) ++ case $lt_cv_prog_gnu_ld in ++ yes*) ++ case $host in ++ i?86-*-solaris*|x86_64-*-solaris*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++ sparc*-*-solaris*) ++ LD="${LD-ld} -m elf64_sparc" ++ ;; ++ esac ++ # GNU ld 2.21 introduced _sol2 emulations. Use them if available. ++ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then ++ LD=${LD-ld}_sol2 ++ fi ++ ;; ++ *) ++ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then ++ LD="${LD-ld} -64" ++ fi ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ rm -rf conftest* ++ ;; ++esac ++ ++need_locks=$enable_libtool_lock ++])# _LT_ENABLE_LOCK ++ ++ ++# _LT_PROG_AR ++# ----------- ++m4_defun([_LT_PROG_AR], ++[AC_CHECK_TOOLS(AR, [ar], false) ++: ${AR=ar} ++_LT_DECL([], [AR], [1], [The archiver]) ++ ++# Use ARFLAGS variable as AR's operation code to sync the variable naming with ++# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have ++# higher priority because thats what people were doing historically (setting ++# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS ++# variable obsoleted/removed. ++ ++test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} ++lt_ar_flags=$AR_FLAGS ++_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) ++ ++# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override ++# by AR_FLAGS because that was never working and AR_FLAGS is about to die. ++_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], ++ [Flags to create an archive]) ++ ++AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], ++ [lt_cv_ar_at_file=no ++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM], ++ [echo conftest.$ac_objext > conftest.lst ++ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' ++ AC_TRY_EVAL([lt_ar_try]) ++ if test 0 -eq "$ac_status"; then ++ # Ensure the archiver fails upon bogus file names. ++ rm -f conftest.$ac_objext libconftest.a ++ AC_TRY_EVAL([lt_ar_try]) ++ if test 0 -ne "$ac_status"; then ++ lt_cv_ar_at_file=@ ++ fi ++ fi ++ rm -f conftest.* libconftest.a ++ ]) ++ ]) ++ ++if test no = "$lt_cv_ar_at_file"; then ++ archiver_list_spec= ++else ++ archiver_list_spec=$lt_cv_ar_at_file ++fi ++_LT_DECL([], [archiver_list_spec], [1], ++ [How to feed a file listing to the archiver]) ++])# _LT_PROG_AR ++ ++ ++# _LT_CMD_OLD_ARCHIVE ++# ------------------- ++m4_defun([_LT_CMD_OLD_ARCHIVE], ++[_LT_PROG_AR ++ ++AC_CHECK_TOOL(STRIP, strip, :) ++test -z "$STRIP" && STRIP=: ++_LT_DECL([], [STRIP], [1], [A symbol stripping program]) ++ ++AC_CHECK_TOOL(RANLIB, ranlib, :) ++test -z "$RANLIB" && RANLIB=: ++_LT_DECL([], [RANLIB], [1], ++ [Commands used to install an old-style archive]) ++ ++# Determine commands to create old-style static archives. ++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' ++old_postinstall_cmds='chmod 644 $oldlib' ++old_postuninstall_cmds= ++ ++if test -n "$RANLIB"; then ++ case $host_os in ++ bitrig* | openbsd*) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ++ ;; ++ *) ++ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ++ ;; ++ esac ++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" ++fi ++ ++case $host_os in ++ darwin*) ++ lock_old_archive_extraction=yes ;; ++ *) ++ lock_old_archive_extraction=no ;; ++esac ++_LT_DECL([], [old_postinstall_cmds], [2]) ++_LT_DECL([], [old_postuninstall_cmds], [2]) ++_LT_TAGDECL([], [old_archive_cmds], [2], ++ [Commands used to build an old-style archive]) ++_LT_DECL([], [lock_old_archive_extraction], [0], ++ [Whether to use a lock for old archive extraction]) ++])# _LT_CMD_OLD_ARCHIVE ++ ++ ++# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ---------------------------------------------------------------- ++# Check whether the given compiler option works ++AC_DEFUN([_LT_COMPILER_OPTION], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_SED])dnl ++AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ # The option is referenced via a variable to avoid confusing sed. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>conftest.err) ++ ac_status=$? ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s "$ac_outfile"; then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings other than the usual output. ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ fi ++ $RM conftest* ++]) ++ ++if test yes = "[$]$2"; then ++ m4_if([$5], , :, [$5]) ++else ++ m4_if([$6], , :, [$6]) ++fi ++])# _LT_COMPILER_OPTION ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) ++ ++ ++# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, ++# [ACTION-SUCCESS], [ACTION-FAILURE]) ++# ---------------------------------------------------- ++# Check whether the given linker option works ++AC_DEFUN([_LT_LINKER_OPTION], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_SED])dnl ++AC_CACHE_CHECK([$1], [$2], ++ [$2=no ++ save_LDFLAGS=$LDFLAGS ++ LDFLAGS="$LDFLAGS $3" ++ echo "$lt_simple_link_test_code" > conftest.$ac_ext ++ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then ++ # The linker can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ if test -s conftest.err; then ++ # Append any errors to the config.log. ++ cat conftest.err 1>&AS_MESSAGE_LOG_FD ++ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp ++ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 ++ if diff conftest.exp conftest.er2 >/dev/null; then ++ $2=yes ++ fi ++ else ++ $2=yes ++ fi ++ fi ++ $RM -r conftest* ++ LDFLAGS=$save_LDFLAGS ++]) ++ ++if test yes = "[$]$2"; then ++ m4_if([$4], , :, [$4]) ++else ++ m4_if([$5], , :, [$5]) ++fi ++])# _LT_LINKER_OPTION ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) ++ ++ ++# LT_CMD_MAX_LEN ++#--------------- ++AC_DEFUN([LT_CMD_MAX_LEN], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++# find the maximum length of command line arguments ++AC_MSG_CHECKING([the maximum length of command line arguments]) ++AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ++ i=0 ++ teststring=ABCD ++ ++ case $build_os in ++ msdosdjgpp*) ++ # On DJGPP, this test can blow up pretty badly due to problems in libc ++ # (any single argument exceeding 2000 bytes causes a buffer overrun ++ # during glob expansion). Even if it were fixed, the result of this ++ # check would be larger than it should be. ++ lt_cv_sys_max_cmd_len=12288; # 12K is about right ++ ;; ++ ++ gnu*) ++ # Under GNU Hurd, this test is not required because there is ++ # no limit to the length of command line arguments. ++ # Libtool will interpret -1 as no limit whatsoever ++ lt_cv_sys_max_cmd_len=-1; ++ ;; ++ ++ cygwin* | mingw* | cegcc*) ++ # On Win9x/ME, this test blows up -- it succeeds, but takes ++ # about 5 minutes as the teststring grows exponentially. ++ # Worse, since 9x/ME are not pre-emptively multitasking, ++ # you end up with a "frozen" computer, even though with patience ++ # the test eventually succeeds (with a max line length of 256k). ++ # Instead, let's just punt: use the minimum linelength reported by ++ # all of the supported platforms: 8192 (on NT/2K/XP). ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ mint*) ++ # On MiNT this can take a long time and run out of memory. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ amigaos*) ++ # On AmigaOS with pdksh, this test takes hours, literally. ++ # So we just punt and use a minimum line length of 8192. ++ lt_cv_sys_max_cmd_len=8192; ++ ;; ++ ++ bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) ++ # This has been around since 386BSD, at least. Likely further. ++ if test -x /sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` ++ elif test -x /usr/sbin/sysctl; then ++ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` ++ else ++ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs ++ fi ++ # And add a safety zone ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ ;; ++ ++ interix*) ++ # We know the value 262144 and hardcode it with a safety zone (like BSD) ++ lt_cv_sys_max_cmd_len=196608 ++ ;; ++ ++ os2*) ++ # The test takes a long time on OS/2. ++ lt_cv_sys_max_cmd_len=8192 ++ ;; ++ ++ osf*) ++ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure ++ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not ++ # nice to cause kernel panics so lets avoid the loop below. ++ # First set a reasonable default. ++ lt_cv_sys_max_cmd_len=16384 ++ # ++ if test -x /sbin/sysconfig; then ++ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in ++ *1*) lt_cv_sys_max_cmd_len=-1 ;; ++ esac ++ fi ++ ;; ++ sco3.2v5*) ++ lt_cv_sys_max_cmd_len=102400 ++ ;; ++ sysv5* | sco5v6* | sysv4.2uw2*) ++ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` ++ if test -n "$kargmax"; then ++ lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` ++ else ++ lt_cv_sys_max_cmd_len=32768 ++ fi ++ ;; ++ *) ++ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` ++ if test -n "$lt_cv_sys_max_cmd_len" && \ ++ test undefined != "$lt_cv_sys_max_cmd_len"; then ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ++ else ++ # Make teststring a little bigger before we do anything with it. ++ # a 1K string should be a reasonable start. ++ for i in 1 2 3 4 5 6 7 8; do ++ teststring=$teststring$teststring ++ done ++ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} ++ # If test is not a shell built-in, we'll probably end up computing a ++ # maximum length that is only half of the actual maximum length, but ++ # we can't tell. ++ while { test X`env echo "$teststring$teststring" 2>/dev/null` \ ++ = "X$teststring$teststring"; } >/dev/null 2>&1 && ++ test 17 != "$i" # 1/2 MB should be enough ++ do ++ i=`expr $i + 1` ++ teststring=$teststring$teststring ++ done ++ # Only check the string length outside the loop. ++ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` ++ teststring= ++ # Add a significant safety factor because C++ compilers can tack on ++ # massive amounts of additional arguments before passing them to the ++ # linker. It appears as though 1/2 is a usable value. ++ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` ++ fi ++ ;; ++ esac ++]) ++if test -n "$lt_cv_sys_max_cmd_len"; then ++ AC_MSG_RESULT($lt_cv_sys_max_cmd_len) ++else ++ AC_MSG_RESULT(none) ++fi ++max_cmd_len=$lt_cv_sys_max_cmd_len ++_LT_DECL([], [max_cmd_len], [0], ++ [What is the maximum length of a command?]) ++])# LT_CMD_MAX_LEN ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) ++ ++ ++# _LT_HEADER_DLFCN ++# ---------------- ++m4_defun([_LT_HEADER_DLFCN], ++[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ++])# _LT_HEADER_DLFCN ++ ++ ++# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, ++# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) ++# ---------------------------------------------------------------- ++m4_defun([_LT_TRY_DLOPEN_SELF], ++[m4_require([_LT_HEADER_DLFCN])dnl ++if test yes = "$cross_compiling"; then : ++ [$4] ++else ++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 ++ lt_status=$lt_dlunknown ++ cat > conftest.$ac_ext <<_LT_EOF ++[#line $LINENO "configure" ++#include "confdefs.h" ++ ++#if HAVE_DLFCN_H ++#include <dlfcn.h> ++#endif ++ ++#include <stdio.h> ++ ++#ifdef RTLD_GLOBAL ++# define LT_DLGLOBAL RTLD_GLOBAL ++#else ++# ifdef DL_GLOBAL ++# define LT_DLGLOBAL DL_GLOBAL ++# else ++# define LT_DLGLOBAL 0 ++# endif ++#endif ++ ++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we ++ find out it does not work in some platform. */ ++#ifndef LT_DLLAZY_OR_NOW ++# ifdef RTLD_LAZY ++# define LT_DLLAZY_OR_NOW RTLD_LAZY ++# else ++# ifdef DL_LAZY ++# define LT_DLLAZY_OR_NOW DL_LAZY ++# else ++# ifdef RTLD_NOW ++# define LT_DLLAZY_OR_NOW RTLD_NOW ++# else ++# ifdef DL_NOW ++# define LT_DLLAZY_OR_NOW DL_NOW ++# else ++# define LT_DLLAZY_OR_NOW 0 ++# endif ++# endif ++# endif ++# endif ++#endif ++ ++/* When -fvisibility=hidden is used, assume the code has been annotated ++ correspondingly for the symbols needed. */ ++#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) ++int fnord () __attribute__((visibility("default"))); ++#endif ++ ++int fnord () { return 42; } ++int main () ++{ ++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); ++ int status = $lt_dlunknown; ++ ++ if (self) ++ { ++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore; ++ else ++ { ++ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; ++ else puts (dlerror ()); ++ } ++ /* dlclose (self); */ ++ } ++ else ++ puts (dlerror ()); ++ ++ return status; ++}] ++_LT_EOF ++ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then ++ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null ++ lt_status=$? ++ case x$lt_status in ++ x$lt_dlno_uscore) $1 ;; ++ x$lt_dlneed_uscore) $2 ;; ++ x$lt_dlunknown|x*) $3 ;; ++ esac ++ else : ++ # compilation failed ++ $3 ++ fi ++fi ++rm -fr conftest* ++])# _LT_TRY_DLOPEN_SELF ++ ++ ++# LT_SYS_DLOPEN_SELF ++# ------------------ ++AC_DEFUN([LT_SYS_DLOPEN_SELF], ++[m4_require([_LT_HEADER_DLFCN])dnl ++if test yes != "$enable_dlopen"; then ++ enable_dlopen=unknown ++ enable_dlopen_self=unknown ++ enable_dlopen_self_static=unknown ++else ++ lt_cv_dlopen=no ++ lt_cv_dlopen_libs= ++ ++ case $host_os in ++ beos*) ++ lt_cv_dlopen=load_add_on ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ;; ++ ++ mingw* | pw32* | cegcc*) ++ lt_cv_dlopen=LoadLibrary ++ lt_cv_dlopen_libs= ++ ;; ++ ++ cygwin*) ++ lt_cv_dlopen=dlopen ++ lt_cv_dlopen_libs= ++ ;; ++ ++ darwin*) ++ # if libdl is installed we need to link against it ++ AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ ++ lt_cv_dlopen=dyld ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=yes ++ ]) ++ ;; ++ ++ tpf*) ++ # Don't try to run any link tests for TPF. We know it's impossible ++ # because TPF is a cross-compiler, and we know how we open DSOs. ++ lt_cv_dlopen=dlopen ++ lt_cv_dlopen_libs= ++ lt_cv_dlopen_self=no ++ ;; ++ ++ *) ++ AC_CHECK_FUNC([shl_load], ++ [lt_cv_dlopen=shl_load], ++ [AC_CHECK_LIB([dld], [shl_load], ++ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], ++ [AC_CHECK_FUNC([dlopen], ++ [lt_cv_dlopen=dlopen], ++ [AC_CHECK_LIB([dl], [dlopen], ++ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], ++ [AC_CHECK_LIB([svld], [dlopen], ++ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], ++ [AC_CHECK_LIB([dld], [dld_link], ++ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ]) ++ ;; ++ esac ++ ++ if test no = "$lt_cv_dlopen"; then ++ enable_dlopen=no ++ else ++ enable_dlopen=yes ++ fi ++ ++ case $lt_cv_dlopen in ++ dlopen) ++ save_CPPFLAGS=$CPPFLAGS ++ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" ++ ++ save_LDFLAGS=$LDFLAGS ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" ++ ++ save_LIBS=$LIBS ++ LIBS="$lt_cv_dlopen_libs $LIBS" ++ ++ AC_CACHE_CHECK([whether a program can dlopen itself], ++ lt_cv_dlopen_self, [dnl ++ _LT_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, ++ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ++ ]) ++ ++ if test yes = "$lt_cv_dlopen_self"; then ++ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" ++ AC_CACHE_CHECK([whether a statically linked program can dlopen itself], ++ lt_cv_dlopen_self_static, [dnl ++ _LT_TRY_DLOPEN_SELF( ++ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, ++ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ++ ]) ++ fi ++ ++ CPPFLAGS=$save_CPPFLAGS ++ LDFLAGS=$save_LDFLAGS ++ LIBS=$save_LIBS ++ ;; ++ esac ++ ++ case $lt_cv_dlopen_self in ++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; ++ *) enable_dlopen_self=unknown ;; ++ esac ++ ++ case $lt_cv_dlopen_self_static in ++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; ++ *) enable_dlopen_self_static=unknown ;; ++ esac ++fi ++_LT_DECL([dlopen_support], [enable_dlopen], [0], ++ [Whether dlopen is supported]) ++_LT_DECL([dlopen_self], [enable_dlopen_self], [0], ++ [Whether dlopen of programs is supported]) ++_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], ++ [Whether dlopen of statically linked programs is supported]) ++])# LT_SYS_DLOPEN_SELF ++ ++# Old name: ++AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) ++ ++ ++# _LT_COMPILER_C_O([TAGNAME]) ++# --------------------------- ++# Check to see if options -c and -o are simultaneously supported by compiler. ++# This macro does not hard code the compiler like AC_PROG_CC_C_O. ++m4_defun([_LT_COMPILER_C_O], ++[m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_TAG_COMPILER])dnl ++AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], ++ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], ++ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no ++ $RM -r conftest 2>/dev/null ++ mkdir conftest ++ cd conftest ++ mkdir out ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ lt_compiler_flag="-o out/conftest2.$ac_objext" ++ # Insert the option either (1) after the last *FLAGS variable, or ++ # (2) before a word containing "conftest.", or (3) at the end. ++ # Note that $ac_compile itself does not contain backslashes and begins ++ # with a dollar sign (not a hyphen), so the echo should work correctly. ++ lt_compile=`echo "$ac_compile" | $SED \ ++ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ ++ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ ++ -e 's:$: $lt_compiler_flag:'` ++ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$lt_compile" 2>out/conftest.err) ++ ac_status=$? ++ cat out/conftest.err >&AS_MESSAGE_LOG_FD ++ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ if (exit $ac_status) && test -s out/conftest2.$ac_objext ++ then ++ # The compiler can only warn and ignore the option if not recognized ++ # So say no if there are warnings ++ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp ++ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 ++ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then ++ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ fi ++ fi ++ chmod u+w . 2>&AS_MESSAGE_LOG_FD ++ $RM conftest* ++ # SGI C++ compiler will create directory out/ii_files/ for ++ # template instantiation ++ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files ++ $RM out/* && rmdir out ++ cd .. ++ $RM -r conftest ++ $RM conftest* ++]) ++_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], ++ [Does compiler simultaneously support -c and -o options?]) ++])# _LT_COMPILER_C_O ++ ++ ++# _LT_COMPILER_FILE_LOCKS([TAGNAME]) ++# ---------------------------------- ++# Check to see if we can do hard links to lock some files if needed ++m4_defun([_LT_COMPILER_FILE_LOCKS], ++[m4_require([_LT_ENABLE_LOCK])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++_LT_COMPILER_C_O([$1]) ++ ++hard_links=nottested ++if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then ++ # do not overwrite the value of need_locks provided by the user ++ AC_MSG_CHECKING([if we can lock with hard links]) ++ hard_links=yes ++ $RM conftest* ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ touch conftest.a ++ ln conftest.a conftest.b 2>&5 || hard_links=no ++ ln conftest.a conftest.b 2>/dev/null && hard_links=no ++ AC_MSG_RESULT([$hard_links]) ++ if test no = "$hard_links"; then ++ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) ++ need_locks=warn ++ fi ++else ++ need_locks=no ++fi ++_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ++])# _LT_COMPILER_FILE_LOCKS ++ ++ ++# _LT_CHECK_OBJDIR ++# ---------------- ++m4_defun([_LT_CHECK_OBJDIR], ++[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], ++[rm -f .libs 2>/dev/null ++mkdir .libs 2>/dev/null ++if test -d .libs; then ++ lt_cv_objdir=.libs ++else ++ # MS-DOS does not allow filenames that begin with a dot. ++ lt_cv_objdir=_libs ++fi ++rmdir .libs 2>/dev/null]) ++objdir=$lt_cv_objdir ++_LT_DECL([], [objdir], [0], ++ [The name of the directory that contains temporary libtool files])dnl ++m4_pattern_allow([LT_OBJDIR])dnl ++AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", ++ [Define to the sub-directory where libtool stores uninstalled libraries.]) ++])# _LT_CHECK_OBJDIR ++ ++ ++# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) ++# -------------------------------------- ++# Check hardcoding attributes. ++m4_defun([_LT_LINKER_HARDCODE_LIBPATH], ++[AC_MSG_CHECKING([how to hardcode library paths into programs]) ++_LT_TAGVAR(hardcode_action, $1)= ++if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || ++ test -n "$_LT_TAGVAR(runpath_var, $1)" || ++ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then ++ ++ # We can hardcode non-existent directories. ++ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && ++ # If the only mechanism to avoid hardcoding is shlibpath_var, we ++ # have to relink, otherwise we might link with an installed library ++ # when we should be linking with a yet-to-be-installed one ++ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && ++ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then ++ # Linking always hardcodes the temporary library directory. ++ _LT_TAGVAR(hardcode_action, $1)=relink ++ else ++ # We can link without hardcoding, and we can hardcode nonexisting dirs. ++ _LT_TAGVAR(hardcode_action, $1)=immediate ++ fi ++else ++ # We cannot hardcode anything, or else we can only hardcode existing ++ # directories. ++ _LT_TAGVAR(hardcode_action, $1)=unsupported ++fi ++AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) ++ ++if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || ++ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then ++ # Fast installation is not supported ++ enable_fast_install=no ++elif test yes = "$shlibpath_overrides_runpath" || ++ test no = "$enable_shared"; then ++ # Fast installation is not necessary ++ enable_fast_install=needless ++fi ++_LT_TAGDECL([], [hardcode_action], [0], ++ [How to hardcode a shared library path into an executable]) ++])# _LT_LINKER_HARDCODE_LIBPATH ++ ++ ++# _LT_CMD_STRIPLIB ++# ---------------- ++m4_defun([_LT_CMD_STRIPLIB], ++[m4_require([_LT_DECL_EGREP]) ++striplib= ++old_striplib= ++AC_MSG_CHECKING([whether stripping libraries is possible]) ++if test -z "$STRIP"; then ++ AC_MSG_RESULT([no]) ++else ++ if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then ++ old_striplib="$STRIP --strip-debug" ++ striplib="$STRIP --strip-unneeded" ++ AC_MSG_RESULT([yes]) ++ else ++ case $host_os in ++ darwin*) ++ # FIXME - insert some real tests, host_os isn't really good enough ++ striplib="$STRIP -x" ++ old_striplib="$STRIP -S" ++ AC_MSG_RESULT([yes]) ++ ;; ++ freebsd*) ++ if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then ++ old_striplib="$STRIP --strip-debug" ++ striplib="$STRIP --strip-unneeded" ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++ fi ++ ;; ++ *) ++ AC_MSG_RESULT([no]) ++ ;; ++ esac ++ fi ++fi ++_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) ++_LT_DECL([], [striplib], [1]) ++])# _LT_CMD_STRIPLIB ++ ++ ++# _LT_PREPARE_MUNGE_PATH_LIST ++# --------------------------- ++# Make sure func_munge_path_list() is defined correctly. ++m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], ++[[# func_munge_path_list VARIABLE PATH ++# ----------------------------------- ++# VARIABLE is name of variable containing _space_ separated list of ++# directories to be munged by the contents of PATH, which is string ++# having a format: ++# "DIR[:DIR]:" ++# string "DIR[ DIR]" will be prepended to VARIABLE ++# ":DIR[:DIR]" ++# string "DIR[ DIR]" will be appended to VARIABLE ++# "DIRP[:DIRP]::[DIRA:]DIRA" ++# string "DIRP[ DIRP]" will be prepended to VARIABLE and string ++# "DIRA[ DIRA]" will be appended to VARIABLE ++# "DIR[:DIR]" ++# VARIABLE will be replaced by "DIR[ DIR]" ++func_munge_path_list () ++{ ++ case x@S|@2 in ++ x) ++ ;; ++ *:) ++ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" ++ ;; ++ x:*) ++ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" ++ ;; ++ *::*) ++ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" ++ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" ++ ;; ++ *) ++ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" ++ ;; ++ esac ++} ++]])# _LT_PREPARE_PATH_LIST ++ ++ ++# _LT_SYS_DYNAMIC_LINKER([TAG]) ++# ----------------------------- ++# PORTME Fill in your ld.so characteristics ++m4_defun([_LT_SYS_DYNAMIC_LINKER], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_OBJDUMP])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_CHECK_SHELL_FEATURES])dnl ++m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl ++AC_MSG_CHECKING([dynamic linker characteristics]) ++m4_if([$1], ++ [], [ ++if test yes = "$GCC"; then ++ case $host_os in ++ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; ++ *) lt_awk_arg='/^libraries:/' ;; ++ esac ++ case $host_os in ++ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; ++ *) lt_sed_strip_eq='s|=/|/|g' ;; ++ esac ++ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` ++ case $lt_search_path_spec in ++ *\;*) ++ # if the path contains ";" then we assume it to be the separator ++ # otherwise default to the standard path separator (i.e. ":") - it is ++ # assumed that no part of a normal pathname contains ";" but that should ++ # okay in the real world where ";" in dirpaths is itself problematic. ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ++ ;; ++ *) ++ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ++ ;; ++ esac ++ # Ok, now we have the path, separated by spaces, we can step through it ++ # and add multilib dir if necessary... ++ lt_tmp_lt_search_path_spec= ++ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` ++ # ...but if some path component already ends with the multilib dir we assume ++ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). ++ case "$lt_multi_os_dir; $lt_search_path_spec " in ++ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) ++ lt_multi_os_dir= ++ ;; ++ esac ++ for lt_sys_path in $lt_search_path_spec; do ++ if test -d "$lt_sys_path$lt_multi_os_dir"; then ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" ++ elif test -n "$lt_multi_os_dir"; then ++ test -d "$lt_sys_path" && \ ++ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" ++ fi ++ done ++ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' ++BEGIN {RS = " "; FS = "/|\n";} { ++ lt_foo = ""; ++ lt_count = 0; ++ for (lt_i = NF; lt_i > 0; lt_i--) { ++ if ($lt_i != "" && $lt_i != ".") { ++ if ($lt_i == "..") { ++ lt_count++; ++ } else { ++ if (lt_count == 0) { ++ lt_foo = "/" $lt_i lt_foo; ++ } else { ++ lt_count--; ++ } ++ } ++ } ++ } ++ if (lt_foo != "") { lt_freq[[lt_foo]]++; } ++ if (lt_freq[[lt_foo]] == 1) { print lt_foo; } ++}'` ++ # AWK program above erroneously prepends '/' to C:/dos/paths ++ # for these hosts. ++ case $host_os in ++ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ ++ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; ++ esac ++ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` ++else ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++fi]) ++library_names_spec= ++libname_spec='lib$name' ++soname_spec= ++shrext_cmds=.so ++postinstall_cmds= ++postuninstall_cmds= ++finish_cmds= ++finish_eval= ++shlibpath_var= ++shlibpath_overrides_runpath=unknown ++version_type=none ++dynamic_linker="$host_os ld.so" ++sys_lib_dlsearch_path_spec="/lib /usr/lib" ++need_lib_prefix=unknown ++hardcode_into_libs=no ++ ++# when you set need_version to no, make sure it does not cause -set_version ++# flags to be left without arguments ++need_version=unknown ++ ++AC_ARG_VAR([LT_SYS_LIBRARY_PATH], ++[User-defined run-time library search path.]) ++ ++case $host_os in ++aix3*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname.a' ++ shlibpath_var=LIBPATH ++ ++ # AIX 3 has no versioning support, so we append a major version to the name. ++ soname_spec='$libname$release$shared_ext$major' ++ ;; ++ ++aix[[4-9]]*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ hardcode_into_libs=yes ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 supports IA64 ++ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ else ++ # With GCC up to 2.95.x, collect2 would create an import file ++ # for dependence libraries. The import file would start with ++ # the line '#! .'. This would cause the generated library to ++ # depend on '.', always an invalid library. This was fixed in ++ # development snapshots of GCC prior to 3.0. ++ case $host_os in ++ aix4 | aix4.[[01]] | aix4.[[01]].*) ++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' ++ echo ' yes ' ++ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then ++ : ++ else ++ can_build_shared=no ++ fi ++ ;; ++ esac ++ # Using Import Files as archive members, it is possible to support ++ # filename-based versioning of shared library archives on AIX. While ++ # this would work for both with and without runtime linking, it will ++ # prevent static linking of such archives. So we do filename-based ++ # shared library versioning with .so extension only, which is used ++ # when both runtime linking and shared linking is enabled. ++ # Unfortunately, runtime linking may impact performance, so we do ++ # not want this to be the default eventually. Also, we use the ++ # versioned .so libs for executables only if there is the -brtl ++ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. ++ # To allow for filename-based versioning support, we need to create ++ # libNAME.so.V as an archive file, containing: ++ # *) an Import File, referring to the versioned filename of the ++ # archive as well as the shared archive member, telling the ++ # bitwidth (32 or 64) of that shared object, and providing the ++ # list of exported symbols of that shared object, eventually ++ # decorated with the 'weak' keyword ++ # *) the shared object with the F_LOADONLY flag set, to really avoid ++ # it being seen by the linker. ++ # At run time we better use the real file rather than another symlink, ++ # but for link time we create the symlink libNAME.so -> libNAME.so.V ++ ++ case $with_aix_soname,$aix_use_runtimelinking in ++ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct ++ # soname into executable. Probably we can add versioning support to ++ # collect2, so additional links can be useful in future. ++ aix,yes) # traditional libtool ++ dynamic_linker='AIX unversionable lib.so' ++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so ++ # instead of lib<name>.a to let people know that these are not ++ # typical AIX shared libraries. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ ;; ++ aix,no) # traditional AIX only ++ dynamic_linker='AIX lib.a[(]lib.so.V[)]' ++ # We preserve .a as extension for shared libraries through AIX4.2 ++ # and later when we are not doing run time linking. ++ library_names_spec='$libname$release.a $libname.a' ++ soname_spec='$libname$release$shared_ext$major' ++ ;; ++ svr4,*) # full svr4 only ++ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" ++ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' ++ # We do not specify a path in Import Files, so LIBPATH fires. ++ shlibpath_overrides_runpath=yes ++ ;; ++ *,yes) # both, prefer svr4 ++ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" ++ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' ++ # unpreferred sharedlib libNAME.a needs extra handling ++ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' ++ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' ++ # We do not specify a path in Import Files, so LIBPATH fires. ++ shlibpath_overrides_runpath=yes ++ ;; ++ *,no) # both, prefer aix ++ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" ++ library_names_spec='$libname$release.a $libname.a' ++ soname_spec='$libname$release$shared_ext$major' ++ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling ++ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' ++ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ++ ;; ++ esac ++ shlibpath_var=LIBPATH ++ fi ++ ;; ++ ++amigaos*) ++ case $host_cpu in ++ powerpc) ++ # Since July 2007 AmigaOS4 officially supports .so libraries. ++ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ ;; ++ m68k) ++ library_names_spec='$libname.ixlibrary $libname.a' ++ # Create ${libname}_ixlibrary.a entries in /sys/libs. ++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ++ ;; ++ esac ++ ;; ++ ++beos*) ++ library_names_spec='$libname$shared_ext' ++ dynamic_linker="$host_os ld.so" ++ shlibpath_var=LIBRARY_PATH ++ ;; ++ ++bsdi[[45]]*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" ++ # the default ld.so.conf also contains /usr/contrib/lib and ++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow ++ # libtool to hard-code these into programs ++ ;; ++ ++cygwin* | mingw* | pw32* | cegcc*) ++ version_type=windows ++ shrext_cmds=.dll ++ need_version=no ++ need_lib_prefix=no ++ ++ case $GCC,$cc_basename in ++ yes,*) ++ # gcc ++ library_names_spec='$libname.dll.a' ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \$file`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ ++ case $host_os in ++ cygwin*) ++ # Cygwin DLLs use 'cyg' prefix rather than 'lib' ++ soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++m4_if([$1], [],[ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ++ ;; ++ mingw* | cegcc*) ++ # MinGW DLLs use traditional 'lib' prefix ++ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++ ;; ++ pw32*) ++ # pw32 DLLs use 'pw' prefix rather than 'lib' ++ library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++ ;; ++ esac ++ dynamic_linker='Win32 ld.exe' ++ ;; ++ ++ *,cl* | *,icl*) ++ # Native MSVC or ICC ++ libname_spec='$name' ++ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ++ library_names_spec='$libname.dll.lib' ++ ++ case $build_os in ++ mingw*) ++ sys_lib_search_path_spec= ++ lt_save_ifs=$IFS ++ IFS=';' ++ for lt_path in $LIB ++ do ++ IFS=$lt_save_ifs ++ # Let DOS variable expansion print the short 8.3 style file name. ++ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` ++ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" ++ done ++ IFS=$lt_save_ifs ++ # Convert to MSYS style. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ++ ;; ++ cygwin*) ++ # Convert to unix form, then to dos form, then back to unix form ++ # but this time dos style (no spaces!) so that the unix form looks ++ # like /cygdrive/c/PROGRA~1:/cygdr... ++ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` ++ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` ++ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ ;; ++ *) ++ sys_lib_search_path_spec=$LIB ++ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then ++ # It is most probably a Windows format PATH. ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` ++ else ++ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ++ fi ++ # FIXME: find the short name or the path components, as spaces are ++ # common. (e.g. "Program Files" -> "PROGRA~1") ++ ;; ++ esac ++ ++ # DLL is installed to $(libdir)/../bin by postinstall_cmds ++ postinstall_cmds='base_file=`basename \$file`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ shlibpath_overrides_runpath=yes ++ dynamic_linker='Win32 link.exe' ++ ;; ++ ++ *) ++ # Assume MSVC and ICC wrapper ++ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' ++ dynamic_linker='Win32 ld.exe' ++ ;; ++ esac ++ # FIXME: first we should search . and the directory the executable is in ++ shlibpath_var=PATH ++ ;; ++ ++darwin* | rhapsody*) ++ dynamic_linker="$host_os dyld" ++ version_type=darwin ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' ++ soname_spec='$libname$release$major$shared_ext' ++ shlibpath_overrides_runpath=yes ++ shlibpath_var=DYLD_LIBRARY_PATH ++ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' ++m4_if([$1], [],[ ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) ++ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ++ ;; ++ ++dgux*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++freebsd* | dragonfly* | midnightbsd*) ++ # DragonFly does not have aout. When/if they implement a new ++ # versioning mechanism, adjust this. ++ if test -x /usr/bin/objformat; then ++ objformat=`/usr/bin/objformat` ++ else ++ case $host_os in ++ freebsd[[23]].*) objformat=aout ;; ++ *) objformat=elf ;; ++ esac ++ fi ++ version_type=freebsd-$objformat ++ case $version_type in ++ freebsd-elf*) ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ need_version=no ++ need_lib_prefix=no ++ ;; ++ freebsd-*) ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ need_version=yes ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_os in ++ freebsd2.*) ++ shlibpath_overrides_runpath=yes ++ ;; ++ freebsd3.[[01]]* | freebsdelf3.[[01]]*) ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ ++ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ *) # from 4.6 on, and DragonFly ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ esac ++ ;; ++ ++haiku*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ dynamic_linker="$host_os runtime_loader" ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' ++ hardcode_into_libs=yes ++ ;; ++ ++hpux9* | hpux10* | hpux11*) ++ # Give a soname corresponding to the major version so that dld.sl refuses to ++ # link against other versions. ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ case $host_cpu in ++ ia64*) ++ shrext_cmds='.so' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.so" ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ if test 32 = "$HPUX_IA64_MODE"; then ++ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" ++ sys_lib_dlsearch_path_spec=/usr/lib/hpux32 ++ else ++ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" ++ sys_lib_dlsearch_path_spec=/usr/lib/hpux64 ++ fi ++ ;; ++ hppa*64*) ++ shrext_cmds='.sl' ++ hardcode_into_libs=yes ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH ++ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ *) ++ shrext_cmds='.sl' ++ dynamic_linker="$host_os dld.sl" ++ shlibpath_var=SHLIB_PATH ++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ ;; ++ esac ++ # HP-UX runs *really* slowly unless shared libraries are mode 555, ... ++ postinstall_cmds='chmod 555 $lib' ++ # or fails outright, so override atomically: ++ install_override_mode=555 ++ ;; ++ ++interix[[3-9]]*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $host_os in ++ nonstopux*) version_type=nonstopux ;; ++ *) ++ if test yes = "$lt_cv_prog_gnu_ld"; then ++ version_type=linux # correct to gnu/linux during the next big refactor ++ else ++ version_type=irix ++ fi ;; ++ esac ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='$libname$release$shared_ext$major' ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' ++ case $host_os in ++ irix5* | nonstopux*) ++ libsuff= shlibsuff= ++ ;; ++ *) ++ case $LD in # libtool.m4 will add one of these switches to LD ++ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") ++ libsuff= shlibsuff= libmagic=32-bit;; ++ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") ++ libsuff=32 shlibsuff=N32 libmagic=N32;; ++ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") ++ libsuff=64 shlibsuff=64 libmagic=64-bit;; ++ *) libsuff= shlibsuff= libmagic=never-match;; ++ esac ++ ;; ++ esac ++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" ++ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" ++ hardcode_into_libs=yes ++ ;; ++ ++# No shared lib support for Linux oldld, aout, or coff. ++linux*oldld* | linux*aout* | linux*coff*) ++ dynamic_linker=no ++ ;; ++ ++linux*android*) ++ version_type=none # Android doesn't support versioned libraries. ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext' ++ soname_spec='$libname$release$shared_ext' ++ finish_cmds= ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ dynamic_linker='Android linker' ++ # Don't embed -rpath directories since the linker doesn't support them. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ ;; ++ ++# This must be glibc/ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ ++ # Some binutils ld are patched to set DT_RUNPATH ++ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], ++ [lt_cv_shlibpath_overrides_runpath=no ++ save_LDFLAGS=$LDFLAGS ++ save_libdir=$libdir ++ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ ++ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], ++ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], ++ [lt_cv_shlibpath_overrides_runpath=yes])]) ++ LDFLAGS=$save_LDFLAGS ++ libdir=$save_libdir ++ ]) ++ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath ++ ++ # This implies no fast_install, which is unacceptable. ++ # Some rework will be needed to allow for fast_install ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++ # Ideally, we could use ldconfig to report *all* directores which are ++ # searched for libraries, however this is still not possible. Aside from not ++ # being certain /sbin/ldconfig is available, command ++ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, ++ # even though it is searched at run-time. Try to do the best guess by ++ # appending ld.so.conf contents (and includes) to the search path. ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++ # powerpc, because MkLinux only supported shared libraries with the ++ # GNU dynamic linker. Since this was broken with cross compilers, ++ # most powerpc-linux boxes support dynamic linking these days and ++ # people can always --disable-shared, the test was removed, and we ++ # assume the GNU/Linux dynamic linker is in use. ++ dynamic_linker='GNU/Linux ld.so' ++ ;; ++ ++netbsd*) ++ version_type=sunos ++ need_lib_prefix=no ++ need_version=no ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ dynamic_linker='NetBSD (a.out) ld.so' ++ else ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ dynamic_linker='NetBSD ld.elf_so' ++ fi ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ ;; ++ ++newsos6) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++*nto* | *qnx*) ++ version_type=qnx ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ dynamic_linker='ldqnx.so' ++ ;; ++ ++openbsd* | bitrig*) ++ version_type=sunos ++ sys_lib_dlsearch_path_spec=/usr/lib ++ need_lib_prefix=no ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then ++ need_version=no ++ else ++ need_version=yes ++ fi ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ ;; ++ ++os2*) ++ libname_spec='$name' ++ version_type=windows ++ shrext_cmds=.dll ++ need_version=no ++ need_lib_prefix=no ++ # OS/2 can only load a DLL with a base name of 8 characters or less. ++ soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; ++ v=$($ECHO $release$versuffix | tr -d .-); ++ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); ++ $ECHO $n$v`$shared_ext' ++ library_names_spec='${libname}_dll.$libext' ++ dynamic_linker='OS/2 ld.exe' ++ shlibpath_var=BEGINLIBPATH ++ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ postinstall_cmds='base_file=`basename \$file`~ ++ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ ++ dldir=$destdir/`dirname \$dlpath`~ ++ test -d \$dldir || mkdir -p \$dldir~ ++ $install_prog $dir/$dlname \$dldir/$dlname~ ++ chmod a+x \$dldir/$dlname~ ++ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then ++ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; ++ fi' ++ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ ++ dlpath=$dir/\$dldll~ ++ $RM \$dlpath' ++ ;; ++ ++osf3* | osf4* | osf5*) ++ version_type=osf ++ need_lib_prefix=no ++ need_version=no ++ soname_spec='$libname$release$shared_ext$major' ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" ++ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ++ ;; ++ ++rdos*) ++ dynamic_linker=no ++ ;; ++ ++solaris*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ # ldd complains unless libraries are executable ++ postinstall_cmds='chmod +x $lib' ++ ;; ++ ++sunos4*) ++ version_type=sunos ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' ++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ if test yes = "$with_gnu_ld"; then ++ need_lib_prefix=no ++ fi ++ need_version=yes ++ ;; ++ ++sysv4 | sysv4.3*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ case $host_vendor in ++ sni) ++ shlibpath_overrides_runpath=no ++ need_lib_prefix=no ++ runpath_var=LD_RUN_PATH ++ ;; ++ siemens) ++ need_lib_prefix=no ++ ;; ++ motorola) ++ need_lib_prefix=no ++ need_version=no ++ shlibpath_overrides_runpath=no ++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ++ ;; ++ esac ++ ;; ++ ++sysv4*MP*) ++ if test -d /usr/nec; then ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' ++ soname_spec='$libname$shared_ext.$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ fi ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ version_type=sco ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=yes ++ hardcode_into_libs=yes ++ if test yes = "$with_gnu_ld"; then ++ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' ++ else ++ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' ++ case $host_os in ++ sco3.2v5*) ++ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ++ ;; ++ esac ++ fi ++ sys_lib_dlsearch_path_spec='/usr/lib' ++ ;; ++ ++tpf*) ++ # TPF is a cross-target only. Preferred cross-host = GNU/Linux. ++ version_type=linux # correct to gnu/linux during the next big refactor ++ need_lib_prefix=no ++ need_version=no ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ shlibpath_var=LD_LIBRARY_PATH ++ shlibpath_overrides_runpath=no ++ hardcode_into_libs=yes ++ ;; ++ ++uts4*) ++ version_type=linux # correct to gnu/linux during the next big refactor ++ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ++ soname_spec='$libname$release$shared_ext$major' ++ shlibpath_var=LD_LIBRARY_PATH ++ ;; ++ ++*) ++ dynamic_linker=no ++ ;; ++esac ++AC_MSG_RESULT([$dynamic_linker]) ++test no = "$dynamic_linker" && can_build_shared=no ++ ++variables_saved_for_relink="PATH $shlibpath_var $runpath_var" ++if test yes = "$GCC"; then ++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" ++fi ++ ++if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then ++ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec ++fi ++ ++if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then ++ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec ++fi ++ ++# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... ++configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec ++ ++# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code ++func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" ++ ++# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool ++configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH ++ ++_LT_DECL([], [variables_saved_for_relink], [1], ++ [Variables whose values should be saved in libtool wrapper scripts and ++ restored at link time]) ++_LT_DECL([], [need_lib_prefix], [0], ++ [Do we need the "lib" prefix for modules?]) ++_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) ++_LT_DECL([], [version_type], [0], [Library versioning type]) ++_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) ++_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) ++_LT_DECL([], [shlibpath_overrides_runpath], [0], ++ [Is shlibpath searched before the hard-coded library search path?]) ++_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) ++_LT_DECL([], [library_names_spec], [1], ++ [[List of archive names. First name is the real one, the rest are links. ++ The last name is the one that the linker finds with -lNAME]]) ++_LT_DECL([], [soname_spec], [1], ++ [[The coded name of the library, if different from the real name]]) ++_LT_DECL([], [install_override_mode], [1], ++ [Permission mode override for installation of shared libraries]) ++_LT_DECL([], [postinstall_cmds], [2], ++ [Command to use after installation of a shared archive]) ++_LT_DECL([], [postuninstall_cmds], [2], ++ [Command to use after uninstallation of a shared archive]) ++_LT_DECL([], [finish_cmds], [2], ++ [Commands used to finish a libtool library installation in a directory]) ++_LT_DECL([], [finish_eval], [1], ++ [[As "finish_cmds", except a single script fragment to be evaled but ++ not shown]]) ++_LT_DECL([], [hardcode_into_libs], [0], ++ [Whether we should hardcode library paths into libraries]) ++_LT_DECL([], [sys_lib_search_path_spec], [2], ++ [Compile-time system search path for libraries]) ++_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], ++ [Detected run-time system search path for libraries]) ++_LT_DECL([], [configure_time_lt_sys_library_path], [2], ++ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ++])# _LT_SYS_DYNAMIC_LINKER ++ ++ ++# _LT_PATH_TOOL_PREFIX(TOOL) ++# -------------------------- ++# find a file program that can recognize shared library ++AC_DEFUN([_LT_PATH_TOOL_PREFIX], ++[m4_require([_LT_DECL_EGREP])dnl ++AC_MSG_CHECKING([for $1]) ++AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, ++[case $MAGIC_CMD in ++[[\\/*] | ?:[\\/]*]) ++ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ++ ;; ++*) ++ lt_save_MAGIC_CMD=$MAGIC_CMD ++ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ++dnl $ac_dummy forces splitting on constant user-supplied paths. ++dnl POSIX.2 word splitting is done only on the output of word expansions, ++dnl not every word. This closes a longstanding sh security hole. ++ ac_dummy="m4_if([$2], , $PATH, [$2])" ++ for ac_dir in $ac_dummy; do ++ IFS=$lt_save_ifs ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$1"; then ++ lt_cv_path_MAGIC_CMD=$ac_dir/"$1" ++ if test -n "$file_magic_test_file"; then ++ case $deplibs_check_method in ++ "file_magic "*) ++ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` ++ MAGIC_CMD=$lt_cv_path_MAGIC_CMD ++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | ++ $EGREP "$file_magic_regex" > /dev/null; then ++ : ++ else ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the command libtool uses to detect shared libraries, ++*** $file_magic_cmd, produces output that libtool cannot recognize. ++*** The result is that libtool may fail to recognize shared libraries ++*** as such. This will affect the creation of libtool libraries that ++*** depend on shared libraries, but programs linked with such libtool ++*** libraries will work regardless of this problem. Nevertheless, you ++*** may want to report the problem to your system manager and/or to ++*** bug-libtool@gnu.org ++ ++_LT_EOF ++ fi ;; ++ esac ++ fi ++ break ++ fi ++ done ++ IFS=$lt_save_ifs ++ MAGIC_CMD=$lt_save_MAGIC_CMD ++ ;; ++esac]) ++MAGIC_CMD=$lt_cv_path_MAGIC_CMD ++if test -n "$MAGIC_CMD"; then ++ AC_MSG_RESULT($MAGIC_CMD) ++else ++ AC_MSG_RESULT(no) ++fi ++_LT_DECL([], [MAGIC_CMD], [0], ++ [Used to examine libraries when file_magic_cmd begins with "file"])dnl ++])# _LT_PATH_TOOL_PREFIX ++ ++# Old name: ++AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) ++ ++ ++# _LT_PATH_MAGIC ++# -------------- ++# find a file program that can recognize a shared library ++m4_defun([_LT_PATH_MAGIC], ++[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) ++if test -z "$lt_cv_path_MAGIC_CMD"; then ++ if test -n "$ac_tool_prefix"; then ++ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) ++ else ++ MAGIC_CMD=: ++ fi ++fi ++])# _LT_PATH_MAGIC ++ ++ ++# LT_PATH_LD ++# ---------- ++# find the pathname to the GNU or non-GNU linker ++AC_DEFUN([LT_PATH_LD], ++[AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_PROG_ECHO_BACKSLASH])dnl ++ ++AC_ARG_WITH([gnu-ld], ++ [AS_HELP_STRING([--with-gnu-ld], ++ [assume the C compiler uses GNU ld @<:@default=no@:>@])], ++ [test no = "$withval" || with_gnu_ld=yes], ++ [with_gnu_ld=no])dnl ++ ++ac_prog=ld ++if test yes = "$GCC"; then ++ # Check if gcc -print-prog-name=ld gives a path. ++ AC_MSG_CHECKING([for ld used by $CC]) ++ case $host in ++ *-*-mingw*) ++ # gcc leaves a trailing carriage return, which upsets mingw ++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; ++ *) ++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; ++ esac ++ case $ac_prog in ++ # Accept absolute paths. ++ [[\\/]]* | ?:[[\\/]]*) ++ re_direlt='/[[^/]][[^/]]*/\.\./' ++ # Canonicalize the pathname of ld ++ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` ++ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ++ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` ++ done ++ test -z "$LD" && LD=$ac_prog ++ ;; ++ "") ++ # If it fails, then pretend we aren't using GCC. ++ ac_prog=ld ++ ;; ++ *) ++ # If it is relative, then search for the first ld in PATH. ++ with_gnu_ld=unknown ++ ;; ++ esac ++elif test yes = "$with_gnu_ld"; then ++ AC_MSG_CHECKING([for GNU ld]) ++else ++ AC_MSG_CHECKING([for non-GNU ld]) ++fi ++AC_CACHE_VAL(lt_cv_path_LD, ++[if test -z "$LD"; then ++ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH; do ++ IFS=$lt_save_ifs ++ test -z "$ac_dir" && ac_dir=. ++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then ++ lt_cv_path_LD=$ac_dir/$ac_prog ++ # Check to see if the program is GNU ld. I'd rather use --version, ++ # but apparently some variants of GNU ld only accept -v. ++ # Break only if it was the GNU/non-GNU ld that we prefer. ++ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in ++ *GNU* | *'with BFD'*) ++ test no != "$with_gnu_ld" && break ++ ;; ++ *) ++ test yes != "$with_gnu_ld" && break ++ ;; ++ esac ++ fi ++ done ++ IFS=$lt_save_ifs ++else ++ lt_cv_path_LD=$LD # Let the user override the test with a path. ++fi]) ++LD=$lt_cv_path_LD ++if test -n "$LD"; then ++ AC_MSG_RESULT($LD) ++else ++ AC_MSG_RESULT(no) ++fi ++test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) ++_LT_PATH_LD_GNU ++AC_SUBST([LD]) ++ ++_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) ++])# LT_PATH_LD ++ ++# Old names: ++AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) ++AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_PROG_LD], []) ++dnl AC_DEFUN([AC_PROG_LD], []) ++ ++ ++# _LT_PATH_LD_GNU ++#- -------------- ++m4_defun([_LT_PATH_LD_GNU], ++[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, ++[# I'd rather use --version here, but apparently some GNU lds only accept -v. ++case `$LD -v 2>&1 </dev/null` in ++*GNU* | *'with BFD'*) ++ lt_cv_prog_gnu_ld=yes ++ ;; ++*) ++ lt_cv_prog_gnu_ld=no ++ ;; ++esac]) ++with_gnu_ld=$lt_cv_prog_gnu_ld ++])# _LT_PATH_LD_GNU ++ ++ ++# _LT_CMD_RELOAD ++# -------------- ++# find reload flag for linker ++# -- PORTME Some linkers may need a different reload flag. ++m4_defun([_LT_CMD_RELOAD], ++[AC_CACHE_CHECK([for $LD option to reload object files], ++ lt_cv_ld_reload_flag, ++ [lt_cv_ld_reload_flag='-r']) ++reload_flag=$lt_cv_ld_reload_flag ++case $reload_flag in ++"" | " "*) ;; ++*) reload_flag=" $reload_flag" ;; ++esac ++reload_cmds='$LD$reload_flag -o $output$reload_objs' ++case $host_os in ++ cygwin* | mingw* | pw32* | cegcc*) ++ if test yes != "$GCC"; then ++ reload_cmds=false ++ fi ++ ;; ++ darwin*) ++ if test yes = "$GCC"; then ++ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' ++ else ++ reload_cmds='$LD$reload_flag -o $output$reload_objs' ++ fi ++ ;; ++esac ++_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl ++_LT_TAGDECL([], [reload_cmds], [2])dnl ++])# _LT_CMD_RELOAD ++ ++ ++# _LT_PATH_DD ++# ----------- ++# find a working dd ++m4_defun([_LT_PATH_DD], ++[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD], ++[printf 0123456789abcdef0123456789abcdef >conftest.i ++cat conftest.i conftest.i >conftest2.i ++: ${lt_DD:=$DD} ++AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], ++[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then ++ cmp -s conftest.i conftest.out \ ++ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: ++fi]) ++rm -f conftest.i conftest2.i conftest.out]) ++])# _LT_PATH_DD ++ ++ ++# _LT_CMD_TRUNCATE ++# ---------------- ++# find command to truncate a binary pipe ++m4_defun([_LT_CMD_TRUNCATE], ++[m4_require([_LT_PATH_DD]) ++AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], ++[printf 0123456789abcdef0123456789abcdef >conftest.i ++cat conftest.i conftest.i >conftest2.i ++lt_cv_truncate_bin= ++if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then ++ cmp -s conftest.i conftest.out \ ++ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" ++fi ++rm -f conftest.i conftest2.i conftest.out ++test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) ++_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], ++ [Command to truncate a binary pipe]) ++])# _LT_CMD_TRUNCATE ++ ++ ++# _LT_CHECK_MAGIC_METHOD ++# ---------------------- ++# how to check for library dependencies ++# -- PORTME fill in with the dynamic library characteristics ++m4_defun([_LT_CHECK_MAGIC_METHOD], ++[m4_require([_LT_DECL_EGREP]) ++m4_require([_LT_DECL_OBJDUMP]) ++AC_CACHE_CHECK([how to recognize dependent libraries], ++lt_cv_deplibs_check_method, ++[lt_cv_file_magic_cmd='$MAGIC_CMD' ++lt_cv_file_magic_test_file= ++lt_cv_deplibs_check_method='unknown' ++# Need to set the preceding variable on all platforms that support ++# interlibrary dependencies. ++# 'none' -- dependencies not supported. ++# 'unknown' -- same as none, but documents that we really don't know. ++# 'pass_all' -- all dependencies passed with no checks. ++# 'test_compile' -- check by making test program. ++# 'file_magic [[regex]]' -- check by looking for files in library path ++# that responds to the $file_magic_cmd with a given extended regex. ++# If you have 'file' or equivalent on your system and you're not sure ++# whether 'pass_all' will *always* work, you probably want this one. ++ ++case $host_os in ++aix[[4-9]]*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++beos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++bsdi[[45]]*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' ++ lt_cv_file_magic_cmd='$FILECMD -L' ++ lt_cv_file_magic_test_file=/shlib/libc.so ++ ;; ++ ++cygwin*) ++ # func_win32_libid is a shell function defined in ltmain.sh ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ ;; ++ ++mingw* | pw32*) ++ # Base MSYS/MinGW do not provide the 'file' command needed by ++ # func_win32_libid shell function, so use a weaker test based on 'objdump', ++ # unless we find 'file', for example because we are cross-compiling. ++ if ( file / ) >/dev/null 2>&1; then ++ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' ++ lt_cv_file_magic_cmd='func_win32_libid' ++ else ++ # Keep this pattern in sync with the one in func_win32_libid. ++ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ fi ++ ;; ++ ++cegcc*) ++ # use the weaker test based on 'objdump'. See mingw*. ++ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' ++ lt_cv_file_magic_cmd='$OBJDUMP -f' ++ ;; ++ ++darwin* | rhapsody*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++freebsd* | dragonfly* | midnightbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ case $host_cpu in ++ i*86 ) ++ # Not sure whether the presence of OpenBSD here was a mistake. ++ # Let's accept both of them until this is cleared up. ++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' ++ lt_cv_file_magic_cmd=$FILECMD ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ++ ;; ++ esac ++ else ++ lt_cv_deplibs_check_method=pass_all ++ fi ++ ;; ++ ++haiku*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++hpux10.20* | hpux11*) ++ lt_cv_file_magic_cmd=$FILECMD ++ case $host_cpu in ++ ia64*) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' ++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ++ ;; ++ hppa*64*) ++ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] ++ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ++ ;; ++ *) ++ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' ++ lt_cv_file_magic_test_file=/usr/lib/libc.sl ++ ;; ++ esac ++ ;; ++ ++interix[[3-9]]*) ++ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ++ ;; ++ ++irix5* | irix6* | nonstopux*) ++ case $LD in ++ *-32|*"-32 ") libmagic=32-bit;; ++ *-n32|*"-n32 ") libmagic=N32;; ++ *-64|*"-64 ") libmagic=64-bit;; ++ *) libmagic=never-match;; ++ esac ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++# This must be glibc/ELF. ++linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' ++ fi ++ ;; ++ ++newos6*) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' ++ lt_cv_file_magic_cmd=$FILECMD ++ lt_cv_file_magic_test_file=/usr/lib/libnls.so ++ ;; ++ ++*nto* | *qnx*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++openbsd* | bitrig*) ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' ++ else ++ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' ++ fi ++ ;; ++ ++osf3* | osf4* | osf5*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++rdos*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++solaris*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ ++sysv4 | sysv4.3*) ++ case $host_vendor in ++ motorola) ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' ++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ++ ;; ++ ncr) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ sequent) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ++ ;; ++ sni) ++ lt_cv_file_magic_cmd='/bin/file' ++ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" ++ lt_cv_file_magic_test_file=/lib/libc.so ++ ;; ++ siemens) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ pc) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++ esac ++ ;; ++ ++tpf*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++os2*) ++ lt_cv_deplibs_check_method=pass_all ++ ;; ++esac ++]) ++ ++file_magic_glob= ++want_nocaseglob=no ++if test "$build" = "$host"; then ++ case $host_os in ++ mingw* | pw32*) ++ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then ++ want_nocaseglob=yes ++ else ++ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` ++ fi ++ ;; ++ esac ++fi ++ ++file_magic_cmd=$lt_cv_file_magic_cmd ++deplibs_check_method=$lt_cv_deplibs_check_method ++test -z "$deplibs_check_method" && deplibs_check_method=unknown ++ ++_LT_DECL([], [deplibs_check_method], [1], ++ [Method to check whether dependent libraries are shared objects]) ++_LT_DECL([], [file_magic_cmd], [1], ++ [Command to use when deplibs_check_method = "file_magic"]) ++_LT_DECL([], [file_magic_glob], [1], ++ [How to find potential files when deplibs_check_method = "file_magic"]) ++_LT_DECL([], [want_nocaseglob], [1], ++ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ++])# _LT_CHECK_MAGIC_METHOD ++ ++ ++# LT_PATH_NM ++# ---------- ++# find the pathname to a BSD- or MS-compatible name lister ++AC_DEFUN([LT_PATH_NM], ++[AC_REQUIRE([AC_PROG_CC])dnl ++AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, ++[if test -n "$NM"; then ++ # Let the user override the test. ++ lt_cv_path_NM=$NM ++else ++ lt_nm_to_check=${ac_tool_prefix}nm ++ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then ++ lt_nm_to_check="$lt_nm_to_check nm" ++ fi ++ for lt_tmp_nm in $lt_nm_to_check; do ++ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ++ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do ++ IFS=$lt_save_ifs ++ test -z "$ac_dir" && ac_dir=. ++ tmp_nm=$ac_dir/$lt_tmp_nm ++ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then ++ # Check to see if the nm accepts a BSD-compat flag. ++ # Adding the 'sed 1q' prevents false positives on HP-UX, which says: ++ # nm: unknown option "B" ignored ++ # Tru64's nm complains that /dev/null is an invalid object file ++ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty ++ case $build_os in ++ mingw*) lt_bad_file=conftest.nm/nofile ;; ++ *) lt_bad_file=/dev/null ;; ++ esac ++ case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in ++ *$lt_bad_file* | *'Invalid file or object type'*) ++ lt_cv_path_NM="$tmp_nm -B" ++ break 2 ++ ;; ++ *) ++ case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in ++ */dev/null*) ++ lt_cv_path_NM="$tmp_nm -p" ++ break 2 ++ ;; ++ *) ++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but ++ continue # so that we can try to find one that supports BSD flags ++ ;; ++ esac ++ ;; ++ esac ++ fi ++ done ++ IFS=$lt_save_ifs ++ done ++ : ${lt_cv_path_NM=no} ++fi]) ++if test no != "$lt_cv_path_NM"; then ++ NM=$lt_cv_path_NM ++else ++ # Didn't find any BSD compatible name lister, look for dumpbin. ++ if test -n "$DUMPBIN"; then : ++ # Let the user override the test. ++ else ++ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) ++ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in ++ *COFF*) ++ DUMPBIN="$DUMPBIN -symbols -headers" ++ ;; ++ *) ++ DUMPBIN=: ++ ;; ++ esac ++ fi ++ AC_SUBST([DUMPBIN]) ++ if test : != "$DUMPBIN"; then ++ NM=$DUMPBIN ++ fi ++fi ++test -z "$NM" && NM=nm ++AC_SUBST([NM]) ++_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl ++ ++AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], ++ [lt_cv_nm_interface="BSD nm" ++ echo "int some_variable = 0;" > conftest.$ac_ext ++ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$ac_compile" 2>conftest.err) ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) ++ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) ++ cat conftest.out >&AS_MESSAGE_LOG_FD ++ if $GREP 'External.*some_variable' conftest.out > /dev/null; then ++ lt_cv_nm_interface="MS dumpbin" ++ fi ++ rm -f conftest*]) ++])# LT_PATH_NM ++ ++# Old names: ++AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) ++AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_PROG_NM], []) ++dnl AC_DEFUN([AC_PROG_NM], []) ++ ++# _LT_CHECK_SHAREDLIB_FROM_LINKLIB ++# -------------------------------- ++# how to determine the name of the shared library ++# associated with a specific link library. ++# -- PORTME fill in with the dynamic library characteristics ++m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], ++[m4_require([_LT_DECL_EGREP]) ++m4_require([_LT_DECL_OBJDUMP]) ++m4_require([_LT_DECL_DLLTOOL]) ++AC_CACHE_CHECK([how to associate runtime and link libraries], ++lt_cv_sharedlib_from_linklib_cmd, ++[lt_cv_sharedlib_from_linklib_cmd='unknown' ++ ++case $host_os in ++cygwin* | mingw* | pw32* | cegcc*) ++ # two different shell functions defined in ltmain.sh; ++ # decide which one to use based on capabilities of $DLLTOOL ++ case `$DLLTOOL --help 2>&1` in ++ *--identify-strict*) ++ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ++ ;; ++ *) ++ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ++ ;; ++ esac ++ ;; ++*) ++ # fallback: assume linklib IS sharedlib ++ lt_cv_sharedlib_from_linklib_cmd=$ECHO ++ ;; ++esac ++]) ++sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd ++test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO ++ ++_LT_DECL([], [sharedlib_from_linklib_cmd], [1], ++ [Command to associate shared and link libraries]) ++])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB ++ ++ ++# _LT_PATH_MANIFEST_TOOL ++# ---------------------- ++# locate the manifest tool ++m4_defun([_LT_PATH_MANIFEST_TOOL], ++[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) ++test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt ++AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], ++ [lt_cv_path_mainfest_tool=no ++ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD ++ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out ++ cat conftest.err >&AS_MESSAGE_LOG_FD ++ if $GREP 'Manifest Tool' conftest.out > /dev/null; then ++ lt_cv_path_mainfest_tool=yes ++ fi ++ rm -f conftest*]) ++if test yes != "$lt_cv_path_mainfest_tool"; then ++ MANIFEST_TOOL=: ++fi ++_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ++])# _LT_PATH_MANIFEST_TOOL ++ ++ ++# _LT_DLL_DEF_P([FILE]) ++# --------------------- ++# True iff FILE is a Windows DLL '.def' file. ++# Keep in sync with func_dll_def_p in the libtool script ++AC_DEFUN([_LT_DLL_DEF_P], ++[dnl ++ test DEF = "`$SED -n dnl ++ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace ++ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments ++ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl ++ -e q dnl Only consider the first "real" line ++ $1`" dnl ++])# _LT_DLL_DEF_P ++ ++ ++# LT_LIB_M ++# -------- ++# check for math library ++AC_DEFUN([LT_LIB_M], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++LIBM= ++case $host in ++*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) ++ # These system don't have libm, or don't need it ++ ;; ++*-ncr-sysv4.3*) ++ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) ++ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ++ ;; ++*) ++ AC_CHECK_LIB(m, cos, LIBM=-lm) ++ ;; ++esac ++AC_SUBST([LIBM]) ++])# LT_LIB_M ++ ++# Old name: ++AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_CHECK_LIBM], []) ++ ++ ++# _LT_COMPILER_NO_RTTI([TAGNAME]) ++# ------------------------------- ++m4_defun([_LT_COMPILER_NO_RTTI], ++[m4_require([_LT_TAG_COMPILER])dnl ++ ++_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++ ++if test yes = "$GCC"; then ++ case $cc_basename in ++ nvcc*) ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; ++ esac ++ ++ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], ++ lt_cv_prog_compiler_rtti_exceptions, ++ [-fno-rtti -fno-exceptions], [], ++ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) ++fi ++_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], ++ [Compiler flag to turn off builtin functions]) ++])# _LT_COMPILER_NO_RTTI ++ ++ ++# _LT_CMD_GLOBAL_SYMBOLS ++# ---------------------- ++m4_defun([_LT_CMD_GLOBAL_SYMBOLS], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_PROG_CC])dnl ++AC_REQUIRE([AC_PROG_AWK])dnl ++AC_REQUIRE([LT_PATH_NM])dnl ++AC_REQUIRE([LT_PATH_LD])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_TAG_COMPILER])dnl ++ ++# Check for command to grab the raw symbol name followed by C symbol from nm. ++AC_MSG_CHECKING([command to parse $NM output from $compiler object]) ++AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], ++[ ++# These are sane defaults that work on at least a few old systems. ++# [They come from Ultrix. What could be older than Ultrix?!! ;)] ++ ++# Character class describing NM global symbol codes. ++symcode='[[BCDEGRST]]' ++ ++# Regexp to match symbols that can be accessed directly from C. ++sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' ++ ++# Define system-specific variables. ++case $host_os in ++aix*) ++ symcode='[[BCDT]]' ++ ;; ++cygwin* | mingw* | pw32* | cegcc*) ++ symcode='[[ABCDGISTW]]' ++ ;; ++hpux*) ++ if test ia64 = "$host_cpu"; then ++ symcode='[[ABCDEGRST]]' ++ fi ++ ;; ++irix* | nonstopux*) ++ symcode='[[BCDEGRST]]' ++ ;; ++osf*) ++ symcode='[[BCDEGQRST]]' ++ ;; ++solaris*) ++ symcode='[[BDRT]]' ++ ;; ++sco3.2v5*) ++ symcode='[[DT]]' ++ ;; ++sysv4.2uw2*) ++ symcode='[[DT]]' ++ ;; ++sysv5* | sco5v6* | unixware* | OpenUNIX*) ++ symcode='[[ABDT]]' ++ ;; ++sysv4) ++ symcode='[[DFNSTU]]' ++ ;; ++esac ++ ++# If we're using GNU nm, then use its standard symbol codes. ++case `$NM -V 2>&1` in ++*GNU* | *'with BFD'*) ++ symcode='[[ABCDGIRSTW]]' ;; ++esac ++ ++if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ # Gets list of data symbols to import. ++ lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" ++ # Adjust the below global symbol transforms to fixup imported variables. ++ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" ++ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" ++ lt_c_name_lib_hook="\ ++ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ ++ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" ++else ++ # Disable hooks by default. ++ lt_cv_sys_global_symbol_to_import= ++ lt_cdecl_hook= ++ lt_c_name_hook= ++ lt_c_name_lib_hook= ++fi ++ ++# Transform an extracted symbol line into a proper C declaration. ++# Some systems (esp. on ia64) link data and code symbols differently, ++# so use this general approach. ++lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ ++$lt_cdecl_hook\ ++" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ ++" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" ++ ++# Transform an extracted symbol line into symbol name and symbol address ++lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ ++$lt_c_name_hook\ ++" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ ++" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" ++ ++# Transform an extracted symbol line into symbol name with lib prefix and ++# symbol address. ++lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ ++$lt_c_name_lib_hook\ ++" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ ++" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ ++" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" ++ ++# Handle CRLF in mingw tool chain ++opt_cr= ++case $build_os in ++mingw*) ++ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ++ ;; ++esac ++ ++# Try without a prefix underscore, then with it. ++for ac_symprfx in "" "_"; do ++ ++ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. ++ symxfrm="\\1 $ac_symprfx\\2 \\2" ++ ++ # Write the raw and C identifiers. ++ if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ # Fake it for dumpbin and say T for any non-static function, ++ # D for any global variable and I for any imported variable. ++ # Also find C++ and __fastcall symbols from MSVC++ or ICC, ++ # which start with @ or ?. ++ lt_cv_sys_global_symbol_pipe="$AWK ['"\ ++" {last_section=section; section=\$ 3};"\ ++" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ ++" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ ++" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ ++" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ ++" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ ++" \$ 0!~/External *\|/{next};"\ ++" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ ++" {if(hide[section]) next};"\ ++" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ ++" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ ++" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ ++" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ ++" ' prfx=^$ac_symprfx]" ++ else ++ lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" ++ fi ++ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" ++ ++ # Check to see that the pipe works correctly. ++ pipe_works=no ++ ++ rm -f conftest* ++ cat > conftest.$ac_ext <<_LT_EOF ++#ifdef __cplusplus ++extern "C" { ++#endif ++char nm_test_var; ++void nm_test_func(void); ++void nm_test_func(void){} ++#ifdef __cplusplus ++} ++#endif ++int main(){nm_test_var='a';nm_test_func();return(0);} ++_LT_EOF ++ ++ if AC_TRY_EVAL(ac_compile); then ++ # Now try to grab the symbols. ++ nlist=conftest.nm ++ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then ++ # Try sorting and uniquifying the output. ++ if sort "$nlist" | uniq > "$nlist"T; then ++ mv -f "$nlist"T "$nlist" ++ else ++ rm -f "$nlist"T ++ fi ++ ++ # Make sure that we snagged all the symbols we need. ++ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then ++ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then ++ cat <<_LT_EOF > conftest.$ac_ext ++/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ ++#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE ++/* DATA imports from DLLs on WIN32 can't be const, because runtime ++ relocations are performed -- see ld's documentation on pseudo-relocs. */ ++# define LT@&t@_DLSYM_CONST ++#elif defined __osf__ ++/* This system does not cope well with relocations in const data. */ ++# define LT@&t@_DLSYM_CONST ++#else ++# define LT@&t@_DLSYM_CONST const ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++_LT_EOF ++ # Now generate the symbol file. ++ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' ++ ++ cat <<_LT_EOF >> conftest.$ac_ext ++ ++/* The mapping between symbol names and symbols. */ ++LT@&t@_DLSYM_CONST struct { ++ const char *name; ++ void *address; ++} ++lt__PROGRAM__LTX_preloaded_symbols[[]] = ++{ ++ { "@PROGRAM@", (void *) 0 }, ++_LT_EOF ++ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext ++ cat <<\_LT_EOF >> conftest.$ac_ext ++ {0, (void *) 0} ++}; ++ ++/* This works around a problem in FreeBSD linker */ ++#ifdef FREEBSD_WORKAROUND ++static const void *lt_preloaded_setup() { ++ return lt__PROGRAM__LTX_preloaded_symbols; ++} ++#endif ++ ++#ifdef __cplusplus ++} ++#endif ++_LT_EOF ++ # Now try linking the two files. ++ mv conftest.$ac_objext conftstm.$ac_objext ++ lt_globsym_save_LIBS=$LIBS ++ lt_globsym_save_CFLAGS=$CFLAGS ++ LIBS=conftstm.$ac_objext ++ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" ++ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then ++ pipe_works=yes ++ fi ++ LIBS=$lt_globsym_save_LIBS ++ CFLAGS=$lt_globsym_save_CFLAGS ++ else ++ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD ++ fi ++ else ++ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD ++ cat conftest.$ac_ext >&5 ++ fi ++ rm -rf conftest* conftst* ++ ++ # Do not use the global_symbol_pipe unless it works. ++ if test yes = "$pipe_works"; then ++ break ++ else ++ lt_cv_sys_global_symbol_pipe= ++ fi ++done ++]) ++if test -z "$lt_cv_sys_global_symbol_pipe"; then ++ lt_cv_sys_global_symbol_to_cdecl= ++fi ++if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then ++ AC_MSG_RESULT(failed) ++else ++ AC_MSG_RESULT(ok) ++fi ++ ++# Response file support. ++if test "$lt_cv_nm_interface" = "MS dumpbin"; then ++ nm_file_list_spec='@' ++elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then ++ nm_file_list_spec='@' ++fi ++ ++_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], ++ [Take the output of nm and produce a listing of raw symbols and C names]) ++_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], ++ [Transform the output of nm in a proper C declaration]) ++_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], ++ [Transform the output of nm into a list of symbols to manually relocate]) ++_LT_DECL([global_symbol_to_c_name_address], ++ [lt_cv_sys_global_symbol_to_c_name_address], [1], ++ [Transform the output of nm in a C name address pair]) ++_LT_DECL([global_symbol_to_c_name_address_lib_prefix], ++ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], ++ [Transform the output of nm in a C name address pair when lib prefix is needed]) ++_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], ++ [The name lister interface]) ++_LT_DECL([], [nm_file_list_spec], [1], ++ [Specify filename containing input files for $NM]) ++]) # _LT_CMD_GLOBAL_SYMBOLS ++ ++ ++# _LT_COMPILER_PIC([TAGNAME]) ++# --------------------------- ++m4_defun([_LT_COMPILER_PIC], ++[m4_require([_LT_TAG_COMPILER])dnl ++_LT_TAGVAR(lt_prog_compiler_wl, $1)= ++_LT_TAGVAR(lt_prog_compiler_pic, $1)= ++_LT_TAGVAR(lt_prog_compiler_static, $1)= ++ ++m4_if([$1], [CXX], [ ++ # C++ specific cases for pic, static, wl, etc. ++ if test yes = "$GXX"; then ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the '-m68020' flag to GCC prevents building anything better, ++ # like '-m68040'. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ mingw* | cygwin* | os2* | pw32* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ case $host_os in ++ os2*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ++ ;; ++ esac ++ ;; ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ *djgpp*) ++ # DJGPP does not support shared libraries at all ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ haiku*) ++ # PIC is the default for Haiku. ++ # The "-static" flag exists, but is broken. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)= ++ ;; ++ interix[[3-9]]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ *qnx* | *nto*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ else ++ case $host_os in ++ aix[[4-9]]*) ++ # All AIX code is PIC. ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ chorus*) ++ case $cc_basename in ++ cxch68*) ++ # Green Hills C++ Compiler ++ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ++ ;; ++ esac ++ ;; ++ mingw* | cygwin* | os2* | pw32* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ ;; ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ freebsd* | dragonfly* | midnightbsd*) ++ # FreeBSD uses GNU C++ ++ ;; ++ hpux9* | hpux10* | hpux11*) ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ++ if test ia64 != "$host_cpu"; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ fi ++ ;; ++ aCC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ interix*) ++ # This is c89, which is MS Visual C++ (no shared libs) ++ # Anyone wants to do a port? ++ ;; ++ irix5* | irix6* | nonstopux*) ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ # CC pic flag -KPIC is the default. ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ case $cc_basename in ++ KCC*) ++ # KAI C++ Compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ ecpc* ) ++ # old Intel C++ for x86_64, which still supported -KPIC. ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ icpc* ) ++ # Intel C++, used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgCC* | pgcpp*) ++ # Portland Group C++ compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ cxx*) ++ # Compaq C++ ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) ++ # IBM XL 8.0, 9.0 on PPC and BlueGene ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ lynxos*) ++ ;; ++ m88k*) ++ ;; ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ netbsd*) ++ ;; ++ *qnx* | *nto*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ cxx*) ++ # Digital/Compaq C++ ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # Make sure the PIC flag is empty. It appears that all Alpha ++ # Linux and Compaq Tru64 Unix objects are PIC. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ psos*) ++ ;; ++ solaris*) ++ case $cc_basename in ++ CC* | sunCC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ lcc*) ++ # Lucid ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ ;; ++ *) ++ ;; ++ esac ++ ;; ++ vxworks*) ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++], ++[ ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ++ case $host_os in ++ aix*) ++ # All AIX code is PIC. ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ m68k) ++ # FIXME: we need at least 68020 code to build shared libraries, but ++ # adding the '-m68020' flag to GCC prevents building anything better, ++ # like '-m68040'. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ++ ;; ++ esac ++ ;; ++ ++ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) ++ # PIC is the default for these OSes. ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ # Although the cygwin gcc ignores -fPIC, still need this for old-style ++ # (--disable-auto-import) libraries ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ case $host_os in ++ os2*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ++ ;; ++ esac ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ ;; ++ ++ haiku*) ++ # PIC is the default for Haiku. ++ # The "-static" flag exists, but is broken. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)= ++ ;; ++ ++ hpux*) ++ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit ++ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag ++ # sets the default TLS model and affects inlining. ++ case $host_cpu in ++ hppa*64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ;; ++ ++ interix[[3-9]]*) ++ # Interix 3.x gcc -fpic/-fPIC options generate broken code. ++ # Instead, we relocate shared libraries at runtime. ++ ;; ++ ++ msdosdjgpp*) ++ # Just because we use GCC doesn't mean we suddenly get shared libraries ++ # on systems that don't support them. ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ enable_shared=no ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic ++ fi ++ ;; ++ ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ ;; ++ esac ++ ++ case $cc_basename in ++ nvcc*) # Cuda Compiler Driver 2.2 ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' ++ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ++ fi ++ ;; ++ esac ++ else ++ # PORTME Check for flag to pass linker flags through the system compiler. ++ case $host_os in ++ aix*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ if test ia64 = "$host_cpu"; then ++ # AIX 5 now supports IA64 processor ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ else ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' ++ fi ++ ;; ++ ++ darwin* | rhapsody*) ++ # PIC is the default on this platform ++ # Common symbols not allowed in MH_DYLIB files ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ++ case $cc_basename in ++ nagfor*) ++ # NAG Fortran compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ ++ mingw* | cygwin* | pw32* | os2* | cegcc*) ++ # This hack is so that the source file can tell whether it is being ++ # built for inclusion in a dll (and should export symbols for example). ++ m4_if([$1], [GCJ], [], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ++ case $host_os in ++ os2*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' ++ ;; ++ esac ++ ;; ++ ++ hpux9* | hpux10* | hpux11*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but ++ # not for PA HP-UX. ++ case $host_cpu in ++ hppa*64*|ia64*) ++ # +Z the default ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ++ ;; ++ esac ++ # Is there a better lt_prog_compiler_static that works with the bundled CC? ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # PIC (with -KPIC) is the default. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ case $cc_basename in ++ # old Intel for x86_64, which still supported -KPIC. ++ ecc*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ # icc used to be incompatible with GCC. ++ # ICC 10 doesn't accept -KPIC any more. ++ icc* | ifort*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ # Lahey Fortran 8.1. ++ lf95*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ++ ;; ++ nagfor*) ++ # NAG Fortran compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ tcc*) ++ # Fabrice Bellard et al's Tiny C Compiler ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) ++ # Portland Group compilers (*not* the Pentium gcc compiler, ++ # which looks to be a dead project) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ccc*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All Alpha code is PIC. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ xl* | bgxl* | bgf* | mpixl*) ++ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ++ ;; ++ *) ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) ++ # Sun Fortran 8.3 passes all unrecognized flags to the linker ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ++ ;; ++ *Sun\ F* | *Sun*Fortran*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ ;; ++ *Sun\ C*) ++ # Sun C 5.9 ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ ;; ++ *Intel*\ [[CF]]*Compiler*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ++ ;; ++ *Portland\ Group*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ newsos6) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ *nto* | *qnx*) ++ # QNX uses GNU C++, but need to define -shared option too, otherwise ++ # it will coredump. ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ # All OSF/1 code is PIC. ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ rdos*) ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ++ ;; ++ ++ solaris*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ case $cc_basename in ++ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4 | sysv4.2uw2* | sysv4.3*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ fi ++ ;; ++ ++ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ unicos*) ++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ ++ uts4*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ++ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ++ ;; ++ ++ *) ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ++ ;; ++ esac ++ fi ++]) ++case $host_os in ++ # For platforms that do not support PIC, -DPIC is meaningless: ++ *djgpp*) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ ;; ++ *) ++ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ++ ;; ++esac ++ ++AC_CACHE_CHECK([for $compiler option to produce PIC], ++ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], ++ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) ++_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) ++ ++# ++# Check to make sure the PIC flag actually works. ++# ++if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then ++ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], ++ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], ++ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], ++ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in ++ "" | " "*) ;; ++ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; ++ esac], ++ [_LT_TAGVAR(lt_prog_compiler_pic, $1)= ++ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) ++fi ++_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], ++ [Additional compiler flags for building library objects]) ++ ++_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], ++ [How to pass a linker flag through the compiler]) ++# ++# Check to make sure the static flag actually works. ++# ++wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" ++_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], ++ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), ++ $lt_tmp_static_flag, ++ [], ++ [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) ++_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], ++ [Compiler flag to prevent dynamic linking]) ++])# _LT_COMPILER_PIC ++ ++ ++# _LT_LINKER_SHLIBS([TAGNAME]) ++# ---------------------------- ++# See if the linker supports building shared libraries. ++m4_defun([_LT_LINKER_SHLIBS], ++[AC_REQUIRE([LT_PATH_LD])dnl ++AC_REQUIRE([LT_PATH_NM])dnl ++m4_require([_LT_PATH_MANIFEST_TOOL])dnl ++m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_DECL_SED])dnl ++m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl ++m4_require([_LT_TAG_COMPILER])dnl ++AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++m4_if([$1], [CXX], [ ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ++ case $host_os in ++ aix[[4-9]]*) ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to GNU nm, but means don't demangle to AIX nm. ++ # Without the "-l" option, or with the "-B" option, AIX nm treats ++ # weak defined symbols like other global defined symbols, whereas ++ # GNU nm marks them as "W". ++ # While the 'weak' keyword is ignored in the Export File, we need ++ # it in the Import File for the 'aix-soname' feature, so we have ++ # to replace the "-B" option with "-P" for AIX nm. ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' ++ else ++ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' ++ fi ++ ;; ++ pw32*) ++ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ++ ;; ++ cygwin* | mingw* | cegcc*) ++ case $cc_basename in ++ cl* | icl*) ++ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ++ ;; ++ *) ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ++ ;; ++ esac ++ ;; ++ *) ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ ;; ++ esac ++], [ ++ runpath_var= ++ _LT_TAGVAR(allow_undefined_flag, $1)= ++ _LT_TAGVAR(always_export_symbols, $1)=no ++ _LT_TAGVAR(archive_cmds, $1)= ++ _LT_TAGVAR(archive_expsym_cmds, $1)= ++ _LT_TAGVAR(compiler_needs_object, $1)=no ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(hardcode_automatic, $1)=no ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_TAGVAR(hardcode_libdir_separator, $1)= ++ _LT_TAGVAR(hardcode_minus_L, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++ _LT_TAGVAR(inherit_rpath, $1)=no ++ _LT_TAGVAR(link_all_deplibs, $1)=unknown ++ _LT_TAGVAR(module_cmds, $1)= ++ _LT_TAGVAR(module_expsym_cmds, $1)= ++ _LT_TAGVAR(old_archive_from_new_cmds, $1)= ++ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= ++ _LT_TAGVAR(thread_safe_flag_spec, $1)= ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ # include_expsyms should be a list of space-separated symbols to be *always* ++ # included in the symbol list ++ _LT_TAGVAR(include_expsyms, $1)= ++ # exclude_expsyms can be an extended regexp of symbols to exclude ++ # it will be wrapped by ' (' and ')$', so one must not match beginning or ++ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', ++ # as well as any symbol that contains 'd'. ++ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ++ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out ++ # platforms (ab)use it in PIC code, but their linkers get confused if ++ # the symbol is explicitly referenced. Since portable code cannot ++ # rely on this symbol name, it's probably fine to never include it in ++ # preloaded symbol tables. ++ # Exclude shared library initialization/finalization symbols. ++dnl Note also adjust exclude_expsyms for C++ above. ++ extract_expsyms_cmds= ++ ++ case $host_os in ++ cygwin* | mingw* | pw32* | cegcc*) ++ # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++ or Intel C++ Compiler. ++ if test yes != "$GCC"; then ++ with_gnu_ld=no ++ fi ++ ;; ++ interix*) ++ # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) ++ with_gnu_ld=yes ++ ;; ++ openbsd* | bitrig*) ++ with_gnu_ld=no ++ ;; ++ esac ++ ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ ++ # On some targets, GNU ld is compatible enough with the native linker ++ # that we're better off using the native interface for both. ++ lt_use_gnu_ld_interface=no ++ if test yes = "$with_gnu_ld"; then ++ case $host_os in ++ aix*) ++ # The AIX port of GNU ld has always aspired to compatibility ++ # with the native linker. However, as the warning in the GNU ld ++ # block says, versions before 2.19.5* couldn't really create working ++ # shared libraries, regardless of the interface used. ++ case `$LD -v 2>&1` in ++ *\ \(GNU\ Binutils\)\ 2.19.5*) ;; ++ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; ++ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; ++ *) ++ lt_use_gnu_ld_interface=yes ++ ;; ++ esac ++ ;; ++ *) ++ lt_use_gnu_ld_interface=yes ++ ;; ++ esac ++ fi ++ ++ if test yes = "$lt_use_gnu_ld_interface"; then ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ wlarc='$wl' ++ ++ # Set some defaults for GNU ld with shared library support. These ++ # are reset later if shared libraries are not supported. Putting them ++ # here allows them to be overridden if necessary. ++ runpath_var=LD_RUN_PATH ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ supports_anon_versioning=no ++ case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in ++ *GNU\ gold*) supports_anon_versioning=yes ;; ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 ++ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... ++ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... ++ *\ 2.11.*) ;; # other 2.11 versions ++ *) supports_anon_versioning=yes ;; ++ esac ++ ++ # See if GNU ld supports shared libraries. ++ case $host_os in ++ aix[[3-9]]*) ++ # On AIX/PPC, the GNU linker is very broken ++ if test ia64 != "$host_cpu"; then ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: the GNU linker, at least up to release 2.19, is reported ++*** to be unable to reliably create shared libraries on AIX. ++*** Therefore, libtool is disabling shared libraries support. If you ++*** really care for shared libraries, you may want to install binutils ++*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. ++*** You will then need to restart the configuration process. ++ ++_LT_EOF ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='' ++ ;; ++ m68k) ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=no ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ++ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file, use it as ++ # is; otherwise, prepend EXPORTS... ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ haiku*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ os2*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ shrext_cmds=.dll ++ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ prefix_cmds="$SED"~ ++ if test EXPORTS = "`$SED 1q $export_symbols`"; then ++ prefix_cmds="$prefix_cmds -e 1d"; ++ fi~ ++ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ ++ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ ;; ++ ++ interix[[3-9]]*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ ++ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) ++ tmp_diet=no ++ if test linux-dietlibc = "$host_os"; then ++ case $cc_basename in ++ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) ++ esac ++ fi ++ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ ++ && test no = "$tmp_diet" ++ then ++ tmp_addflag=' $pic_flag' ++ tmp_sharedflag='-shared' ++ case $cc_basename,$host_cpu in ++ pgcc*) # Portland Group C compiler ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ tmp_addflag=' $pic_flag' ++ ;; ++ pgf77* | pgf90* | pgf95* | pgfortran*) ++ # Portland Group f77 and f90 compilers ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ tmp_addflag=' $pic_flag -Mnomain' ;; ++ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 ++ tmp_addflag=' -i_dynamic' ;; ++ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 ++ tmp_addflag=' -i_dynamic -nofor_main' ;; ++ ifc* | ifort*) # Intel Fortran compiler ++ tmp_addflag=' -nofor_main' ;; ++ lf95*) # Lahey Fortran 8.1 ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ tmp_sharedflag='--shared' ;; ++ nagfor*) # NAGFOR 5.3 ++ tmp_sharedflag='-Wl,-shared' ;; ++ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) ++ tmp_sharedflag='-qmkshrobj' ++ tmp_addflag= ;; ++ nvcc*) # Cuda Compiler Driver 2.2 ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ _LT_TAGVAR(compiler_needs_object, $1)=yes ++ ;; ++ esac ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ C*) # Sun C 5.9 ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ _LT_TAGVAR(compiler_needs_object, $1)=yes ++ tmp_sharedflag='-G' ;; ++ *Sun\ F*) # Sun Fortran 8.3 ++ tmp_sharedflag='-G' ;; ++ esac ++ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ ++ if test yes = "$supports_anon_versioning"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' ++ fi ++ ++ case $cc_basename in ++ tcc*) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ++ ;; ++ xlf* | bgf* | bgxlf* | mpixlf*) ++ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' ++ if test yes = "$supports_anon_versioning"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ esac ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' ++ wlarc= ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ fi ++ ;; ++ ++ solaris*) ++ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: The releases 2.8.* of the GNU linker cannot reliably ++*** create shared libraries on Solaris systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.9.1 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) ++ case `$LD -v 2>&1` in ++ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ cat <<_LT_EOF 1>&2 ++ ++*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot ++*** reliably create shared libraries on SCO systems. Therefore, libtool ++*** is disabling shared libraries support. We urge you to upgrade GNU ++*** binutils to release 2.16.91.0.3 or newer. Another option is to modify ++*** your PATH or compiler configuration so that the native linker is ++*** used, and then restart. ++ ++_LT_EOF ++ ;; ++ *) ++ # For security reasons, it is highly recommended that you always ++ # use absolute paths for naming shared libraries, and exclude the ++ # DT_RUNPATH tag from executables and libraries. But doing so ++ # requires that you compile everything twice, which is a pain. ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ sunos4*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ wlarc= ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ++ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then ++ runpath_var= ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)= ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ # PORTME fill in a description of your system's linker (not GNU ld) ++ case $host_os in ++ aix3*) ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' ++ # Note: this linker hardcodes the directories in LIBPATH if there ++ # are no directories specified by -L. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then ++ # Neither direct hardcoding nor static linking is supported with a ++ # broken collect2. ++ _LT_TAGVAR(hardcode_direct, $1)=unsupported ++ fi ++ ;; ++ ++ aix[[4-9]]*) ++ if test ia64 = "$host_cpu"; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag= ++ else ++ # If we're using GNU nm, then we don't want the "-C" option. ++ # -C means demangle to GNU nm, but means don't demangle to AIX nm. ++ # Without the "-l" option, or with the "-B" option, AIX nm treats ++ # weak defined symbols like other global defined symbols, whereas ++ # GNU nm marks them as "W". ++ # While the 'weak' keyword is ignored in the Export File, we need ++ # it in the Import File for the 'aix-soname' feature, so we have ++ # to replace the "-B" option with "-P" for AIX nm. ++ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' ++ else ++ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' ++ fi ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # have runtime linking enabled, and use it for executables. ++ # For shared libraries, we enable/disable runtime linking ++ # depending on the kind of the shared library created - ++ # when "with_aix_soname,aix_use_runtimelinking" is: ++ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables ++ # "aix,yes" lib.so shared, rtl:yes, for executables ++ # lib.a static archive ++ # "both,no" lib.so.V(shr.o) shared, rtl:yes ++ # lib.a(lib.so.V) shared, rtl:no, for executables ++ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a(lib.so.V) shared, rtl:no ++ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a static archive ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) ++ for ld_flag in $LDFLAGS; do ++ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then ++ aix_use_runtimelinking=yes ++ break ++ fi ++ done ++ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # With aix-soname=svr4, we create the lib.so.V shared archives only, ++ # so we don't have lib.a shared libs to link our executables. ++ # We have to force runtime linking in this case. ++ aix_use_runtimelinking=yes ++ LDFLAGS="$LDFLAGS -Wl,-brtl" ++ fi ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_TAGVAR(archive_cmds, $1)='' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='$wl-f,' ++ case $with_aix_soname,$aix_use_runtimelinking in ++ aix,*) ;; # traditional, no import file ++ svr4,* | *,yes) # use import file ++ # The Import File defines what to hardcode. ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=no ++ ;; ++ esac ++ ++ if test yes = "$GCC"; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`$CC -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ _LT_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ ;; ++ esac ++ shared_flag='-shared' ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag="$shared_flag "'$wl-G' ++ fi ++ # Need to ensure runtime linking is disabled for the traditional ++ # shared library, or the linker may eventually find shared libraries ++ # /with/ Import File - we do not want to mix them. ++ shared_flag_aix='-shared' ++ shared_flag_svr4='-shared $wl-G' ++ else ++ # not using gcc ++ if test ia64 = "$host_cpu"; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag='$wl-G' ++ else ++ shared_flag='$wl-bM:SRE' ++ fi ++ shared_flag_aix='$wl-bM:SRE' ++ shared_flag_svr4='$wl-G' ++ fi ++ fi ++ ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to export. ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ _LT_TAGVAR(allow_undefined_flag, $1)='-berok' ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag ++ else ++ if test ia64 = "$host_cpu"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' ++ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' ++ if test yes = "$with_gnu_ld"; then ++ # We only use this code for GNU lds that support --whole-archive. ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ++ else ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' ++ # -brtl affects multiple linker settings, -berok does not and is overridden later ++ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' ++ if test svr4 != "$with_aix_soname"; then ++ # This is similar to how AIX traditionally builds its shared libraries. ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' ++ fi ++ if test aix != "$with_aix_soname"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' ++ else ++ # used by -dlpreopen to get the symbols ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' ++ fi ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' ++ fi ++ fi ++ ;; ++ ++ amigaos*) ++ case $host_cpu in ++ powerpc) ++ # see comment about AmigaOS4 .so support ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='' ++ ;; ++ m68k) ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ ;; ++ ++ bsdi[[45]]*) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ # When not using gcc, we currently assume that we are using ++ # Microsoft Visual C++ or Intel C++ Compiler. ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ case $cc_basename in ++ cl* | icl*) ++ # Native MSVC or ICC ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=.dll ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp "$export_symbols" "$output_objdir/$soname.def"; ++ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; ++ else ++ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; ++ fi~ ++ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ ++ linknames=' ++ # The linker will not automatically build a static lib if we build a DLL. ++ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ++ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' ++ # Don't use ranlib ++ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' ++ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ ++ lt_tool_outputfile="@TOOL_OUTPUT@"~ ++ case $lt_outputfile in ++ *.exe|*.EXE) ;; ++ *) ++ lt_outputfile=$lt_outputfile.exe ++ lt_tool_outputfile=$lt_tool_outputfile.exe ++ ;; ++ esac~ ++ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then ++ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; ++ $RM "$lt_outputfile.manifest"; ++ fi' ++ ;; ++ *) ++ # Assume MSVC and ICC wrapper ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=.dll ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' ++ # The linker will automatically build a .lib file if we build a DLL. ++ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' ++ # FIXME: Should let the user specify the lib program. ++ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ;; ++ esac ++ ;; ++ ++ darwin* | rhapsody*) ++ _LT_DARWIN_LINKER_FEATURES($1) ++ ;; ++ ++ dgux*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor ++ # support. Future versions do this automatically, but an explicit c++rt0.o ++ # does not break anything, and helps significantly (at the cost of a little ++ # extra space). ++ freebsd2.2*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # Unfortunately, older versions of FreeBSD 2 do not have this feature. ++ freebsd2.*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries. ++ freebsd* | dragonfly* | midnightbsd*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ hpux9*) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ ;; ++ ++ hpux10*) ++ if test yes,no = "$GCC,$with_gnu_ld"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ fi ++ ;; ++ ++ hpux11*) ++ if test yes,no = "$GCC,$with_gnu_ld"; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ else ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ m4_if($1, [], [ ++ # Older versions of the 11.00 compiler do not understand -b yet ++ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) ++ _LT_LINKER_OPTION([if $CC understands -b], ++ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], ++ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], ++ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], ++ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ++ ;; ++ esac ++ fi ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ ++ # hardcode_minus_L: Not really in the search PATH, ++ # but as the default location of the library. ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ ;; ++ esac ++ fi ++ ;; ++ ++ irix5* | irix6* | nonstopux*) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ # Try to use the -exported_symbol ld option, if it does not ++ # work, assume that -exports_file does not work either and ++ # implicitly export all symbols. ++ # This should be the same for all languages, so no per-tag cache variable. ++ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], ++ [lt_cv_irix_exported_symbol], ++ [save_LDFLAGS=$LDFLAGS ++ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" ++ AC_LINK_IFELSE( ++ [AC_LANG_SOURCE( ++ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], ++ [C++], [[int foo (void) { return 0; }]], ++ [Fortran 77], [[ ++ subroutine foo ++ end]], ++ [Fortran], [[ ++ subroutine foo ++ end]])])], ++ [lt_cv_irix_exported_symbol=yes], ++ [lt_cv_irix_exported_symbol=no]) ++ LDFLAGS=$save_LDFLAGS]) ++ if test yes = "$lt_cv_irix_exported_symbol"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' ++ fi ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)='no' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(inherit_rpath, $1)=yes ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ linux*) ++ case $cc_basename in ++ tcc*) ++ # Fabrice Bellard et al's Tiny C Compiler ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ newsos6) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *nto* | *qnx*) ++ ;; ++ ++ openbsd* | bitrig*) ++ if test -f /usr/libexec/ld.so; then ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ fi ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ os2*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ shrext_cmds=.dll ++ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ prefix_cmds="$SED"~ ++ if test EXPORTS = "`$SED 1q $export_symbols`"; then ++ prefix_cmds="$prefix_cmds -e 1d"; ++ fi~ ++ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ ++ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ ;; ++ ++ osf3*) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ else ++ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)='no' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ osf4* | osf5*) # as osf3* with the addition of -msym flag ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ else ++ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' ++ ++ # Both c and cxx compiler support -rpath directly ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)='no' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ;; ++ ++ solaris*) ++ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' ++ if test yes = "$GCC"; then ++ wlarc='$wl' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ else ++ case `$CC -V 2>&1` in ++ *"Compilers 5.0"*) ++ wlarc='' ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ++ ;; ++ *) ++ wlarc='$wl' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ++ ;; ++ esac ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands '-z linker_flag'. GCC discards it without '$wl', ++ # but is careful enough not to reorder. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ++ fi ++ ;; ++ esac ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ sunos4*) ++ if test sequent = "$host_vendor"; then ++ # Use $CC to link under sequent, because it throws in some extra .o ++ # files that make .init and .fini sections work. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' ++ fi ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4) ++ case $host_vendor in ++ sni) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ++ ;; ++ siemens) ++ ## LD is ld it makes a PLAMLIB ++ ## CC just makes a GrossModule. ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ ;; ++ motorola) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ++ ;; ++ esac ++ runpath_var='LD_RUN_PATH' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ sysv4.3*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ++ ;; ++ ++ sysv4*MP*) ++ if test -d /usr/nec; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var=LD_RUN_PATH ++ hardcode_runpath_var=yes ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ fi ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We CANNOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ if test yes = "$GCC"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ fi ++ ;; ++ ++ uts4*) ++ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ ++ *) ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ++ if test sni = "$host_vendor"; then ++ case $host in ++ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ++ ;; ++ esac ++ fi ++ fi ++]) ++AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) ++test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no ++ ++_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld ++ ++_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl ++_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl ++_LT_DECL([], [extract_expsyms_cmds], [2], ++ [The commands to extract the exported symbol list from a shared archive]) ++ ++# ++# Do we need to explicitly link libc? ++# ++case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in ++x|xyes) ++ # Assume -lc should be added ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ ++ if test yes,yes = "$GCC,$enable_shared"; then ++ case $_LT_TAGVAR(archive_cmds, $1) in ++ *'~'*) ++ # FIXME: we may have to deal with multi-command sequences. ++ ;; ++ '$CC '*) ++ # Test whether the compiler implicitly links with -lc since on some ++ # systems, -lgcc has to come before -lc. If gcc already passes -lc ++ # to ld, don't add -lc before -lgcc. ++ AC_CACHE_CHECK([whether -lc should be explicitly linked in], ++ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), ++ [$RM conftest* ++ echo "$lt_simple_compile_test_code" > conftest.$ac_ext ++ ++ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then ++ soname=conftest ++ lib=conftest ++ libobjs=conftest.$ac_objext ++ deplibs= ++ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) ++ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) ++ compiler_flags=-v ++ linker_flags=-v ++ verstring= ++ output_objdir=. ++ libname=conftest ++ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) ++ _LT_TAGVAR(allow_undefined_flag, $1)= ++ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) ++ then ++ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ else ++ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ fi ++ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag ++ else ++ cat conftest.err 1>&5 ++ fi ++ $RM conftest* ++ ]) ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ++ ;; ++ esac ++ fi ++ ;; ++esac ++ ++_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], ++ [Whether or not to add -lc for building shared libraries]) ++_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], ++ [enable_shared_with_static_runtimes], [0], ++ [Whether or not to disallow shared libs when runtime libs are static]) ++_LT_TAGDECL([], [export_dynamic_flag_spec], [1], ++ [Compiler flag to allow reflexive dlopens]) ++_LT_TAGDECL([], [whole_archive_flag_spec], [1], ++ [Compiler flag to generate shared objects directly from archives]) ++_LT_TAGDECL([], [compiler_needs_object], [1], ++ [Whether the compiler copes with passing no objects directly]) ++_LT_TAGDECL([], [old_archive_from_new_cmds], [2], ++ [Create an old-style archive from a shared archive]) ++_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], ++ [Create a temporary old-style archive to link instead of a shared archive]) ++_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) ++_LT_TAGDECL([], [archive_expsym_cmds], [2]) ++_LT_TAGDECL([], [module_cmds], [2], ++ [Commands used to build a loadable module if different from building ++ a shared archive.]) ++_LT_TAGDECL([], [module_expsym_cmds], [2]) ++_LT_TAGDECL([], [with_gnu_ld], [1], ++ [Whether we are building with GNU ld or not]) ++_LT_TAGDECL([], [allow_undefined_flag], [1], ++ [Flag that allows shared libraries with undefined symbols to be built]) ++_LT_TAGDECL([], [no_undefined_flag], [1], ++ [Flag that enforces no undefined symbols]) ++_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], ++ [Flag to hardcode $libdir into a binary during linking. ++ This must work even if $libdir does not exist]) ++_LT_TAGDECL([], [hardcode_libdir_separator], [1], ++ [Whether we need a single "-rpath" flag with a separated argument]) ++_LT_TAGDECL([], [hardcode_direct], [0], ++ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes ++ DIR into the resulting binary]) ++_LT_TAGDECL([], [hardcode_direct_absolute], [0], ++ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes ++ DIR into the resulting binary and the resulting library dependency is ++ "absolute", i.e impossible to change by setting $shlibpath_var if the ++ library is relocated]) ++_LT_TAGDECL([], [hardcode_minus_L], [0], ++ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR ++ into the resulting binary]) ++_LT_TAGDECL([], [hardcode_shlibpath_var], [0], ++ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR ++ into the resulting binary]) ++_LT_TAGDECL([], [hardcode_automatic], [0], ++ [Set to "yes" if building a shared library automatically hardcodes DIR ++ into the library and all subsequent libraries and executables linked ++ against it]) ++_LT_TAGDECL([], [inherit_rpath], [0], ++ [Set to yes if linker adds runtime paths of dependent libraries ++ to runtime path list]) ++_LT_TAGDECL([], [link_all_deplibs], [0], ++ [Whether libtool must link a program against all its dependency libraries]) ++_LT_TAGDECL([], [always_export_symbols], [0], ++ [Set to "yes" if exported symbols are required]) ++_LT_TAGDECL([], [export_symbols_cmds], [2], ++ [The commands to list exported symbols]) ++_LT_TAGDECL([], [exclude_expsyms], [1], ++ [Symbols that should not be listed in the preloaded symbols]) ++_LT_TAGDECL([], [include_expsyms], [1], ++ [Symbols that must always be exported]) ++_LT_TAGDECL([], [prelink_cmds], [2], ++ [Commands necessary for linking programs (against libraries) with templates]) ++_LT_TAGDECL([], [postlink_cmds], [2], ++ [Commands necessary for finishing linking programs]) ++_LT_TAGDECL([], [file_list_spec], [1], ++ [Specify filename containing input files]) ++dnl FIXME: Not yet implemented ++dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], ++dnl [Compiler flag to generate thread safe objects]) ++])# _LT_LINKER_SHLIBS ++ ++ ++# _LT_LANG_C_CONFIG([TAG]) ++# ------------------------ ++# Ensure that the configuration variables for a C compiler are suitably ++# defined. These variables are subsequently used by _LT_CONFIG to write ++# the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_C_CONFIG], ++[m4_require([_LT_DECL_EGREP])dnl ++lt_save_CC=$CC ++AC_LANG_PUSH(C) ++ ++# Source file extension for C test sources. ++ac_ext=c ++ ++# Object file extension for compiled C test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="int some_variable = 0;" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='int main(){return(0);}' ++ ++_LT_TAG_COMPILER ++# Save the default compiler, since it gets overwritten when the other ++# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. ++compiler_DEFAULT=$CC ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++if test -n "$compiler"; then ++ _LT_COMPILER_NO_RTTI($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ LT_SYS_DLOPEN_SELF ++ _LT_CMD_STRIPLIB ++ ++ # Report what library types will actually be built ++ AC_MSG_CHECKING([if libtool supports shared libraries]) ++ AC_MSG_RESULT([$can_build_shared]) ++ ++ AC_MSG_CHECKING([whether to build shared libraries]) ++ test no = "$can_build_shared" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test yes = "$enable_shared" && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ ++ aix[[4-9]]*) ++ if test ia64 != "$host_cpu"; then ++ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in ++ yes,aix,yes) ;; # shared object as lib.so file only ++ yes,svr4,*) ;; # shared object as lib.so archive member only ++ yes,*) enable_static=no ;; # shared object in lib.a archive as well ++ esac ++ fi ++ ;; ++ esac ++ AC_MSG_RESULT([$enable_shared]) ++ ++ AC_MSG_CHECKING([whether to build static libraries]) ++ # Make sure either enable_shared or enable_static is yes. ++ test yes = "$enable_shared" || enable_static=yes ++ AC_MSG_RESULT([$enable_static]) ++ ++ _LT_CONFIG($1) ++fi ++AC_LANG_POP ++CC=$lt_save_CC ++])# _LT_LANG_C_CONFIG ++ ++ ++# _LT_LANG_CXX_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for a C++ compiler are suitably ++# defined. These variables are subsequently used by _LT_CONFIG to write ++# the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_CXX_CONFIG], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++m4_require([_LT_DECL_EGREP])dnl ++m4_require([_LT_PATH_MANIFEST_TOOL])dnl ++if test -n "$CXX" && ( test no != "$CXX" && ++ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || ++ (test g++ != "$CXX"))); then ++ AC_PROG_CXXCPP ++else ++ _lt_caught_CXX_error=yes ++fi ++ ++AC_LANG_PUSH(C++) ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_TAGVAR(allow_undefined_flag, $1)= ++_LT_TAGVAR(always_export_symbols, $1)=no ++_LT_TAGVAR(archive_expsym_cmds, $1)= ++_LT_TAGVAR(compiler_needs_object, $1)=no ++_LT_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_TAGVAR(hardcode_direct, $1)=no ++_LT_TAGVAR(hardcode_direct_absolute, $1)=no ++_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_TAGVAR(hardcode_minus_L, $1)=no ++_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported ++_LT_TAGVAR(hardcode_automatic, $1)=no ++_LT_TAGVAR(inherit_rpath, $1)=no ++_LT_TAGVAR(module_cmds, $1)= ++_LT_TAGVAR(module_expsym_cmds, $1)= ++_LT_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++_LT_TAGVAR(no_undefined_flag, $1)= ++_LT_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for C++ test sources. ++ac_ext=cpp ++ ++# Object file extension for compiled C++ test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# No sense in running all these tests if we already determined that ++# the CXX compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test yes != "$_lt_caught_CXX_error"; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="int some_variable = 0;" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ _LT_TAG_COMPILER ++ ++ # save warnings/boilerplate of simple test code ++ _LT_COMPILER_BOILERPLATE ++ _LT_LINKER_BOILERPLATE ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_CFLAGS=$CFLAGS ++ lt_save_LD=$LD ++ lt_save_GCC=$GCC ++ GCC=$GXX ++ lt_save_with_gnu_ld=$with_gnu_ld ++ lt_save_path_LD=$lt_cv_path_LD ++ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then ++ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx ++ else ++ $as_unset lt_cv_prog_gnu_ld ++ fi ++ if test -n "${lt_cv_path_LDCXX+set}"; then ++ lt_cv_path_LD=$lt_cv_path_LDCXX ++ else ++ $as_unset lt_cv_path_LD ++ fi ++ test -z "${LDCXX+set}" || LD=$LDCXX ++ CC=${CXX-"c++"} ++ CFLAGS=$CXXFLAGS ++ compiler=$CC ++ _LT_TAGVAR(compiler, $1)=$CC ++ _LT_CC_BASENAME([$compiler]) ++ ++ if test -n "$compiler"; then ++ # We don't want -fno-exception when compiling C++ code, so set the ++ # no_builtin_flag separately ++ if test yes = "$GXX"; then ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ++ else ++ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= ++ fi ++ ++ if test yes = "$GXX"; then ++ # Set up default GNU C++ configuration ++ ++ LT_PATH_LD ++ ++ # Check if GNU C++ uses GNU ld as the underlying linker, since the ++ # archiving commands below assume that GNU ld is being used. ++ if test yes = "$with_gnu_ld"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ ++ # If archive_cmds runs LD, not CC, wlarc should be empty ++ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to ++ # investigate it a little bit more. (MM) ++ wlarc='$wl' ++ ++ # ancient GNU ld didn't support --whole-archive et. al. ++ if eval "`$CC -print-prog-name=ld` --help 2>&1" | ++ $GREP 'no-whole-archive' > /dev/null; then ++ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' ++ else ++ _LT_TAGVAR(whole_archive_flag_spec, $1)= ++ fi ++ else ++ with_gnu_ld=no ++ wlarc= ++ ++ # A generic and very simple default shared library creation ++ # command for GNU C++ for the case where it uses the native ++ # linker, instead of GNU ld. If possible, this setting should ++ # overridden to take advantage of the native linker features on ++ # the platform it is being used on. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ fi ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ ++ else ++ GXX=no ++ with_gnu_ld=no ++ wlarc= ++ fi ++ ++ # PORTME: fill in a description of your system's C++ link characteristics ++ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ case $host_os in ++ aix3*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aix[[4-9]]*) ++ if test ia64 = "$host_cpu"; then ++ # On IA64, the linker does run time linking by default, so we don't ++ # have to do anything special. ++ aix_use_runtimelinking=no ++ exp_sym_flag='-Bexport' ++ no_entry_flag= ++ else ++ aix_use_runtimelinking=no ++ ++ # Test if we are trying to use run time linking or normal ++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we ++ # have runtime linking enabled, and use it for executables. ++ # For shared libraries, we enable/disable runtime linking ++ # depending on the kind of the shared library created - ++ # when "with_aix_soname,aix_use_runtimelinking" is: ++ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables ++ # "aix,yes" lib.so shared, rtl:yes, for executables ++ # lib.a static archive ++ # "both,no" lib.so.V(shr.o) shared, rtl:yes ++ # lib.a(lib.so.V) shared, rtl:no, for executables ++ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a(lib.so.V) shared, rtl:no ++ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables ++ # lib.a static archive ++ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) ++ for ld_flag in $LDFLAGS; do ++ case $ld_flag in ++ *-brtl*) ++ aix_use_runtimelinking=yes ++ break ++ ;; ++ esac ++ done ++ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # With aix-soname=svr4, we create the lib.so.V shared archives only, ++ # so we don't have lib.a shared libs to link our executables. ++ # We have to force runtime linking in this case. ++ aix_use_runtimelinking=yes ++ LDFLAGS="$LDFLAGS -Wl,-brtl" ++ fi ++ ;; ++ esac ++ ++ exp_sym_flag='-bexport' ++ no_entry_flag='-bnoentry' ++ fi ++ ++ # When large executables or shared objects are built, AIX ld can ++ # have problems creating the table of contents. If linking a library ++ # or program results in "error TOC overflow" add -mminimal-toc to ++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not ++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. ++ ++ _LT_TAGVAR(archive_cmds, $1)='' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='$wl-f,' ++ case $with_aix_soname,$aix_use_runtimelinking in ++ aix,*) ;; # no import file ++ svr4,* | *,yes) # use import file ++ # The Import File defines what to hardcode. ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=no ++ ;; ++ esac ++ ++ if test yes = "$GXX"; then ++ case $host_os in aix4.[[012]]|aix4.[[012]].*) ++ # We only want to do this on AIX 4.2 and lower, the check ++ # below for broken collect2 doesn't work under 4.3+ ++ collect2name=`$CC -print-prog-name=collect2` ++ if test -f "$collect2name" && ++ strings "$collect2name" | $GREP resolve_lib_name >/dev/null ++ then ++ # We have reworked collect2 ++ : ++ else ++ # We have old collect2 ++ _LT_TAGVAR(hardcode_direct, $1)=unsupported ++ # It fails to find uninstalled libraries when the uninstalled ++ # path is not listed in the libpath. Setting hardcode_minus_L ++ # to unsupported forces relinking ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)= ++ fi ++ esac ++ shared_flag='-shared' ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag=$shared_flag' $wl-G' ++ fi ++ # Need to ensure runtime linking is disabled for the traditional ++ # shared library, or the linker may eventually find shared libraries ++ # /with/ Import File - we do not want to mix them. ++ shared_flag_aix='-shared' ++ shared_flag_svr4='-shared $wl-G' ++ else ++ # not using gcc ++ if test ia64 = "$host_cpu"; then ++ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release ++ # chokes on -Wl,-G. The following line is correct: ++ shared_flag='-G' ++ else ++ if test yes = "$aix_use_runtimelinking"; then ++ shared_flag='$wl-G' ++ else ++ shared_flag='$wl-bM:SRE' ++ fi ++ shared_flag_aix='$wl-bM:SRE' ++ shared_flag_svr4='$wl-G' ++ fi ++ fi ++ ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' ++ # It seems that -bexpall does not export symbols beginning with ++ # underscore (_), so it is better to generate a list of symbols to ++ # export. ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then ++ # Warning - without using the other runtime loading flags (-brtl), ++ # -berok will link without error, but may produce a broken library. ++ # The "-G" linker flag allows undefined symbols. ++ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' ++ # Determine the default libpath from the value encoded in an empty ++ # executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag ++ else ++ if test ia64 = "$host_cpu"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' ++ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" ++ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" ++ else ++ # Determine the default libpath from the value encoded in an ++ # empty executable. ++ _LT_SYS_MODULE_PATH_AIX([$1]) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" ++ # Warning - without using the other run time loading flags, ++ # -berok will link without error, but may produce a broken library. ++ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' ++ if test yes = "$with_gnu_ld"; then ++ # We only use this code for GNU lds that support --whole-archive. ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ++ else ++ # Exported symbols can be pulled into shared objects from archives ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' ++ fi ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' ++ # -brtl affects multiple linker settings, -berok does not and is overridden later ++ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' ++ if test svr4 != "$with_aix_soname"; then ++ # This is similar to how AIX traditionally builds its shared ++ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' ++ fi ++ if test aix != "$with_aix_soname"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' ++ else ++ # used by -dlpreopen to get the symbols ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' ++ fi ++ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' ++ fi ++ fi ++ ;; ++ ++ beos*) ++ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc ++ # support --undefined. This deserves some investigation. FIXME ++ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ chorus*) ++ case $cc_basename in ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ cygwin* | mingw* | pw32* | cegcc*) ++ case $GXX,$cc_basename in ++ ,cl* | no,cl* | ,icl* | no,icl*) ++ # Native MSVC or ICC ++ # hardcode_libdir_flag_spec is actually meaningless, as there is ++ # no search path for DLLs. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ # Tell ltmain to make .lib files, not .a files. ++ libext=lib ++ # Tell ltmain to make .dll files, not .so files. ++ shrext_cmds=.dll ++ # FIXME: Setting linknames here is a bad hack. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp "$export_symbols" "$output_objdir/$soname.def"; ++ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; ++ else ++ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; ++ fi~ ++ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ ++ linknames=' ++ # The linker will not automatically build a static lib if we build a DLL. ++ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ # Don't use ranlib ++ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' ++ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ ++ lt_tool_outputfile="@TOOL_OUTPUT@"~ ++ case $lt_outputfile in ++ *.exe|*.EXE) ;; ++ *) ++ lt_outputfile=$lt_outputfile.exe ++ lt_tool_outputfile=$lt_tool_outputfile.exe ++ ;; ++ esac~ ++ func_to_tool_file "$lt_outputfile"~ ++ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then ++ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; ++ $RM "$lt_outputfile.manifest"; ++ fi' ++ ;; ++ *) ++ # g++ ++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, ++ # as there is no search path for DLLs. ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ _LT_TAGVAR(always_export_symbols, $1)=no ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ ++ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ # If the export-symbols file already is a .def file, use it as ++ # is; otherwise, prepend EXPORTS... ++ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then ++ cp $export_symbols $output_objdir/$soname.def; ++ else ++ echo EXPORTS > $output_objdir/$soname.def; ++ cat $export_symbols >> $output_objdir/$soname.def; ++ fi~ ++ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ darwin* | rhapsody*) ++ _LT_DARWIN_LINKER_FEATURES($1) ++ ;; ++ ++ os2*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes ++ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported ++ shrext_cmds=.dll ++ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ ++ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ ++ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ ++ $ECHO EXPORTS >> $output_objdir/$libname.def~ ++ prefix_cmds="$SED"~ ++ if test EXPORTS = "`$SED 1q $export_symbols`"; then ++ prefix_cmds="$prefix_cmds -e 1d"; ++ fi~ ++ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ ++ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ ++ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ ++ emximp -o $lib $output_objdir/$libname.def' ++ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' ++ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ++ _LT_TAGVAR(file_list_spec, $1)='@' ++ ;; ++ ++ dgux*) ++ case $cc_basename in ++ ec++*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ghcx*) ++ # Green Hills C++ Compiler ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ freebsd2.*) ++ # C++ shared libraries reported to be fairly broken before ++ # switch to ELF ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ freebsd-elf*) ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ ;; ++ ++ freebsd* | dragonfly* | midnightbsd*) ++ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF ++ # conventions ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ ;; ++ ++ haiku*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ ++ hpux9*) ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test yes = "$GXX"; then ++ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' ++ else ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ hpux10*|hpux11*) ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ case $host_cpu in ++ hppa*64*|ia64*) ++ ;; ++ *) ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ ;; ++ esac ++ fi ++ case $host_cpu in ++ hppa*64*|ia64*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ ;; ++ *) ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, ++ # but as the default ++ # location of the library. ++ ;; ++ esac ++ ++ case $cc_basename in ++ CC*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ aCC*) ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test yes = "$GXX"; then ++ if test no = "$with_gnu_ld"; then ++ case $host_cpu in ++ hppa*64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ ia64*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ ;; ++ esac ++ fi ++ else ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ interix[[3-9]]*) ++ _LT_TAGVAR(hardcode_direct, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. ++ # Instead, shared libraries are loaded at an image base (0x10000000 by ++ # default) and relocated if they conflict, which is a slow very memory ++ # consuming and fragmenting process. To avoid this, we pick a random, ++ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link ++ # time. Moving up from 0x10000000 also allows more sbrk(2) space. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ++ ;; ++ irix5* | irix6*) ++ case $cc_basename in ++ CC*) ++ # SGI C++ ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -ar", where "CC" is the IRIX C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ++ ;; ++ *) ++ if test yes = "$GXX"; then ++ if test no = "$with_gnu_ld"; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ else ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' ++ fi ++ fi ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ;; ++ esac ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ _LT_TAGVAR(inherit_rpath, $1)=yes ++ ;; ++ ++ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -Bstatic", where "CC" is the KAI C++ compiler. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ++ ;; ++ icpc* | ecpc* ) ++ # Intel C++ ++ with_gnu_ld=yes ++ # version 8.0 and above of icpc choke on multiply defined symbols ++ # if we add $predep_objects and $postdep_objects, however 7.1 and ++ # earlier do not add the objects themselves. ++ case `$CC -V 2>&1` in ++ *"Version 7."*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 8.0 or newer ++ tmp_idyn= ++ case $host_cpu in ++ ia64*) tmp_idyn=' -i_dynamic';; ++ esac ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ++ ;; ++ pgCC* | pgcpp*) ++ # Portland Group C++ compiler ++ case `$CC -V` in ++ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) ++ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ ++ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' ++ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ ++ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ ++ $RANLIB $oldlib' ++ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ ++ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ ++ rm -rf $tpldir~ ++ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ ++ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ *) # Version 6 and above use weak symbols ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ++ ;; ++ esac ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ ;; ++ cxx*) ++ # Compaq C++ ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' ++ ++ runpath_var=LD_RUN_PATH ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ++ ;; ++ xl* | mpixl* | bgxl*) ++ # IBM XL 8.0 on PPC, with GNU ld ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' ++ if test yes = "$supports_anon_versioning"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ ++ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ ++ echo "local: *; };" >> $output_objdir/$libname.ver~ ++ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' ++ fi ++ ;; ++ *) ++ case `$CC -V 2>&1 | $SED 5q` in ++ *Sun\ C*) ++ # Sun C++ 5.9 ++ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ++ _LT_TAGVAR(compiler_needs_object, $1)=yes ++ ++ # Not sure whether something based on ++ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 ++ # would be better. ++ output_verbose_link_cmd='func_echo_all' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ esac ++ ;; ++ esac ++ ;; ++ ++ lynxos*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ m88k*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ mvs*) ++ case $cc_basename in ++ cxx*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ netbsd*) ++ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' ++ wlarc= ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ fi ++ # Workaround some broken pre-1.5 toolchains ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ++ ;; ++ ++ *nto* | *qnx*) ++ _LT_TAGVAR(ld_shlibs, $1)=yes ++ ;; ++ ++ openbsd* | bitrig*) ++ if test -f /usr/libexec/ld.so; then ++ _LT_TAGVAR(hardcode_direct, $1)=yes ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ++ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' ++ fi ++ output_verbose_link_cmd=func_echo_all ++ else ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ ++ osf3* | osf4* | osf5*) ++ case $cc_basename in ++ KCC*) ++ # Kuck and Associates, Inc. (KAI) C++ Compiler ++ ++ # KCC will only create a shared library if the output file ++ # ends with ".so" (or ".sl" for HP-UX), so rename the library ++ # to its proper name (with version) after linking. ++ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Archives containing C++ object files must be created using ++ # the KAI C++ compiler. ++ case $host in ++ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; ++ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; ++ esac ++ ;; ++ RCC*) ++ # Rational C++ 2.4.1 ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ cxx*) ++ case $host in ++ osf3*) ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ ;; ++ *) ++ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ ++ echo "-hidden">> $lib.exp~ ++ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ ++ $RM $lib.exp' ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ++ ;; ++ esac ++ ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ # ++ # There doesn't appear to be a way to prevent this compiler from ++ # explicitly linking system object files so we need to strip them ++ # from the output so that they don't get included in the library ++ # dependencies. ++ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ++ ;; ++ *) ++ if test yes,no = "$GXX,$with_gnu_ld"; then ++ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' ++ case $host in ++ osf3*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ++ ;; ++ esac ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=: ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ ++ else ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ fi ++ ;; ++ esac ++ ;; ++ ++ psos*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ sunos4*) ++ case $cc_basename in ++ CC*) ++ # Sun C++ 4.x ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ lcc*) ++ # Lucid ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ solaris*) ++ case $cc_basename in ++ CC* | sunCC*) ++ # Sun C++ 4.2, 5.x and Centerline C++ ++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes ++ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ # The compiler driver will combine and reorder linker options, ++ # but understands '-z linker_flag'. ++ # Supported since Solaris 2.6 (maybe 2.5.1?) ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ++ ;; ++ esac ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ ++ output_verbose_link_cmd='func_echo_all' ++ ++ # Archives containing C++ object files must be created using ++ # "CC -xar", where "CC" is the Sun C++ compiler. This is ++ # necessary to make sure instantiated templates are included ++ # in the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ++ ;; ++ gcx*) ++ # Green Hills C++ Compiler ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' ++ ++ # The C++ compiler must be used to create the archive. ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ++ ;; ++ *) ++ # GNU C++ compiler with Solaris linker ++ if test yes,no = "$GXX,$with_gnu_ld"; then ++ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' ++ if $CC --version | $GREP -v '^2\.7' > /dev/null; then ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ else ++ # g++ 2.7 appears to require '-G' NOT '-shared' on this ++ # platform. ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ ++ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' ++ ++ # Commands to make compiler produce verbose output that lists ++ # what "hidden" libraries, object files and flags are used when ++ # linking a shared library. ++ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' ++ fi ++ ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' ++ case $host_os in ++ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; ++ *) ++ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ++ ;; ++ esac ++ fi ++ ;; ++ esac ++ ;; ++ ++ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ sysv5* | sco3.2v5* | sco5v6*) ++ # Note: We CANNOT use -z defs as we might desire, because we do not ++ # link with -lc, and that would cause any symbols used from libc to ++ # always be unresolved, which means just about no library would ++ # ever link correctly. If we're not using GNU ld we use -z text ++ # though, which does catch some bad symbols but isn't as heavy-handed ++ # as -z defs. ++ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' ++ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' ++ _LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ++ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' ++ _LT_TAGVAR(hardcode_libdir_separator, $1)=':' ++ _LT_TAGVAR(link_all_deplibs, $1)=yes ++ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' ++ runpath_var='LD_RUN_PATH' ++ ++ case $cc_basename in ++ CC*) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ ++ '"$_LT_TAGVAR(old_archive_cmds, $1)" ++ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ ++ '"$_LT_TAGVAR(reload_cmds, $1)" ++ ;; ++ *) ++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ++ ;; ++ esac ++ ;; ++ ++ tandem*) ++ case $cc_basename in ++ NCC*) ++ # NonStop-UX NCC 3.20 ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ;; ++ ++ vxworks*) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ ++ *) ++ # FIXME: insert proper C++ library support ++ _LT_TAGVAR(ld_shlibs, $1)=no ++ ;; ++ esac ++ ++ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) ++ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no ++ ++ _LT_TAGVAR(GCC, $1)=$GXX ++ _LT_TAGVAR(LD, $1)=$LD ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ _LT_SYS_HIDDEN_LIBDEPS($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++ fi # test -n "$compiler" ++ ++ CC=$lt_save_CC ++ CFLAGS=$lt_save_CFLAGS ++ LDCXX=$LD ++ LD=$lt_save_LD ++ GCC=$lt_save_GCC ++ with_gnu_ld=$lt_save_with_gnu_ld ++ lt_cv_path_LDCXX=$lt_cv_path_LD ++ lt_cv_path_LD=$lt_save_path_LD ++ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld ++ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ++fi # test yes != "$_lt_caught_CXX_error" ++ ++AC_LANG_POP ++])# _LT_LANG_CXX_CONFIG ++ ++ ++# _LT_FUNC_STRIPNAME_CNF ++# ---------------------- ++# func_stripname_cnf prefix suffix name ++# strip PREFIX and SUFFIX off of NAME. ++# PREFIX and SUFFIX must not contain globbing or regex special ++# characters, hashes, percent signs, but SUFFIX may contain a leading ++# dot (in which case that matches only a dot). ++# ++# This function is identical to the (non-XSI) version of func_stripname, ++# except this one can be used by m4 code that may be executed by configure, ++# rather than the libtool script. ++m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl ++AC_REQUIRE([_LT_DECL_SED]) ++AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) ++func_stripname_cnf () ++{ ++ case @S|@2 in ++ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; ++ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; ++ esac ++} # func_stripname_cnf ++])# _LT_FUNC_STRIPNAME_CNF ++ ++ ++# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) ++# --------------------------------- ++# Figure out "hidden" library dependencies from verbose ++# compiler output when linking a shared library. ++# Parse the compiler output and extract the necessary ++# objects, libraries and library flags. ++m4_defun([_LT_SYS_HIDDEN_LIBDEPS], ++[m4_require([_LT_FILEUTILS_DEFAULTS])dnl ++AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl ++# Dependencies to place before and after the object being linked: ++_LT_TAGVAR(predep_objects, $1)= ++_LT_TAGVAR(postdep_objects, $1)= ++_LT_TAGVAR(predeps, $1)= ++_LT_TAGVAR(postdeps, $1)= ++_LT_TAGVAR(compiler_lib_search_path, $1)= ++ ++dnl we can't use the lt_simple_compile_test_code here, ++dnl because it contains code intended for an executable, ++dnl not a library. It's possible we should let each ++dnl tag define a new lt_????_link_test_code variable, ++dnl but it's only used here... ++m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF ++int a; ++void foo (void) { a = 0; } ++_LT_EOF ++], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF ++class Foo ++{ ++public: ++ Foo (void) { a = 0; } ++private: ++ int a; ++}; ++_LT_EOF ++], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF ++ subroutine foo ++ implicit none ++ integer*4 a ++ a=0 ++ return ++ end ++_LT_EOF ++], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF ++ subroutine foo ++ implicit none ++ integer a ++ a=0 ++ return ++ end ++_LT_EOF ++], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF ++public class foo { ++ private int a; ++ public void bar (void) { ++ a = 0; ++ } ++}; ++_LT_EOF ++], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF ++package foo ++func foo() { ++} ++_LT_EOF ++]) ++ ++_lt_libdeps_save_CFLAGS=$CFLAGS ++case "$CC $CFLAGS " in #( ++*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; ++*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; ++*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; ++esac ++ ++dnl Parse the compiler output and extract the necessary ++dnl objects, libraries and library flags. ++if AC_TRY_EVAL(ac_compile); then ++ # Parse the compiler output and extract the necessary ++ # objects, libraries and library flags. ++ ++ # Sentinel used to keep track of whether or not we are before ++ # the conftest object file. ++ pre_test_object_deps_done=no ++ ++ for p in `eval "$output_verbose_link_cmd"`; do ++ case $prev$p in ++ ++ -L* | -R* | -l*) ++ # Some compilers place space between "-{L,R}" and the path. ++ # Remove the space. ++ if test x-L = "$p" || ++ test x-R = "$p"; then ++ prev=$p ++ continue ++ fi ++ ++ # Expand the sysroot to ease extracting the directories later. ++ if test -z "$prev"; then ++ case $p in ++ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; ++ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; ++ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; ++ esac ++ fi ++ case $p in ++ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; ++ esac ++ if test no = "$pre_test_object_deps_done"; then ++ case $prev in ++ -L | -R) ++ # Internal compiler library paths should come after those ++ # provided the user. The postdeps already come after the ++ # user supplied libs so there is no need to process them. ++ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then ++ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p ++ else ++ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" ++ fi ++ ;; ++ # The "-l" case would never come before the object being ++ # linked, so don't bother handling this case. ++ esac ++ else ++ if test -z "$_LT_TAGVAR(postdeps, $1)"; then ++ _LT_TAGVAR(postdeps, $1)=$prev$p ++ else ++ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" ++ fi ++ fi ++ prev= ++ ;; ++ ++ *.lto.$objext) ;; # Ignore GCC LTO objects ++ *.$objext) ++ # This assumes that the test object file only shows up ++ # once in the compiler output. ++ if test "$p" = "conftest.$objext"; then ++ pre_test_object_deps_done=yes ++ continue ++ fi ++ ++ if test no = "$pre_test_object_deps_done"; then ++ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then ++ _LT_TAGVAR(predep_objects, $1)=$p ++ else ++ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" ++ fi ++ else ++ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then ++ _LT_TAGVAR(postdep_objects, $1)=$p ++ else ++ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" ++ fi ++ fi ++ ;; ++ ++ *) ;; # Ignore the rest. ++ ++ esac ++ done ++ ++ # Clean up. ++ rm -f a.out a.exe ++else ++ echo "libtool.m4: error: problem compiling $1 test program" ++fi ++ ++$RM -f confest.$objext ++CFLAGS=$_lt_libdeps_save_CFLAGS ++ ++# PORTME: override above test on systems where it is broken ++m4_if([$1], [CXX], ++[case $host_os in ++interix[[3-9]]*) ++ # Interix 3.5 installs completely hosed .la files for C++, so rather than ++ # hack all around it, let's just trust "g++" to DTRT. ++ _LT_TAGVAR(predep_objects,$1)= ++ _LT_TAGVAR(postdep_objects,$1)= ++ _LT_TAGVAR(postdeps,$1)= ++ ;; ++esac ++]) ++ ++case " $_LT_TAGVAR(postdeps, $1) " in ++*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; ++esac ++ _LT_TAGVAR(compiler_lib_search_dirs, $1)= ++if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then ++ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` ++fi ++_LT_TAGDECL([], [compiler_lib_search_dirs], [1], ++ [The directories searched by this compiler when creating a shared library]) ++_LT_TAGDECL([], [predep_objects], [1], ++ [Dependencies to place before and after the objects being linked to ++ create a shared library]) ++_LT_TAGDECL([], [postdep_objects], [1]) ++_LT_TAGDECL([], [predeps], [1]) ++_LT_TAGDECL([], [postdeps], [1]) ++_LT_TAGDECL([], [compiler_lib_search_path], [1], ++ [The library search path used internally by the compiler when linking ++ a shared library]) ++])# _LT_SYS_HIDDEN_LIBDEPS ++ ++ ++# _LT_LANG_F77_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for a Fortran 77 compiler are ++# suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_F77_CONFIG], ++[AC_LANG_PUSH(Fortran 77) ++if test -z "$F77" || test no = "$F77"; then ++ _lt_disable_F77=yes ++fi ++ ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_TAGVAR(allow_undefined_flag, $1)= ++_LT_TAGVAR(always_export_symbols, $1)=no ++_LT_TAGVAR(archive_expsym_cmds, $1)= ++_LT_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_TAGVAR(hardcode_direct, $1)=no ++_LT_TAGVAR(hardcode_direct_absolute, $1)=no ++_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_TAGVAR(hardcode_minus_L, $1)=no ++_LT_TAGVAR(hardcode_automatic, $1)=no ++_LT_TAGVAR(inherit_rpath, $1)=no ++_LT_TAGVAR(module_cmds, $1)= ++_LT_TAGVAR(module_expsym_cmds, $1)= ++_LT_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++_LT_TAGVAR(no_undefined_flag, $1)= ++_LT_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for f77 test sources. ++ac_ext=f ++ ++# Object file extension for compiled f77 test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# No sense in running all these tests if we already determined that ++# the F77 compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test yes != "$_lt_disable_F77"; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="\ ++ subroutine t ++ return ++ end ++" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code="\ ++ program t ++ end ++" ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ _LT_TAG_COMPILER ++ ++ # save warnings/boilerplate of simple test code ++ _LT_COMPILER_BOILERPLATE ++ _LT_LINKER_BOILERPLATE ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_GCC=$GCC ++ lt_save_CFLAGS=$CFLAGS ++ CC=${F77-"f77"} ++ CFLAGS=$FFLAGS ++ compiler=$CC ++ _LT_TAGVAR(compiler, $1)=$CC ++ _LT_CC_BASENAME([$compiler]) ++ GCC=$G77 ++ if test -n "$compiler"; then ++ AC_MSG_CHECKING([if libtool supports shared libraries]) ++ AC_MSG_RESULT([$can_build_shared]) ++ ++ AC_MSG_CHECKING([whether to build shared libraries]) ++ test no = "$can_build_shared" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test yes = "$enable_shared" && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ aix[[4-9]]*) ++ if test ia64 != "$host_cpu"; then ++ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in ++ yes,aix,yes) ;; # shared object as lib.so file only ++ yes,svr4,*) ;; # shared object as lib.so archive member only ++ yes,*) enable_static=no ;; # shared object in lib.a archive as well ++ esac ++ fi ++ ;; ++ esac ++ AC_MSG_RESULT([$enable_shared]) ++ ++ AC_MSG_CHECKING([whether to build static libraries]) ++ # Make sure either enable_shared or enable_static is yes. ++ test yes = "$enable_shared" || enable_static=yes ++ AC_MSG_RESULT([$enable_static]) ++ ++ _LT_TAGVAR(GCC, $1)=$G77 ++ _LT_TAGVAR(LD, $1)=$LD ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++ fi # test -n "$compiler" ++ ++ GCC=$lt_save_GCC ++ CC=$lt_save_CC ++ CFLAGS=$lt_save_CFLAGS ++fi # test yes != "$_lt_disable_F77" ++ ++AC_LANG_POP ++])# _LT_LANG_F77_CONFIG ++ ++ ++# _LT_LANG_FC_CONFIG([TAG]) ++# ------------------------- ++# Ensure that the configuration variables for a Fortran compiler are ++# suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_FC_CONFIG], ++[AC_LANG_PUSH(Fortran) ++ ++if test -z "$FC" || test no = "$FC"; then ++ _lt_disable_FC=yes ++fi ++ ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++_LT_TAGVAR(allow_undefined_flag, $1)= ++_LT_TAGVAR(always_export_symbols, $1)=no ++_LT_TAGVAR(archive_expsym_cmds, $1)= ++_LT_TAGVAR(export_dynamic_flag_spec, $1)= ++_LT_TAGVAR(hardcode_direct, $1)=no ++_LT_TAGVAR(hardcode_direct_absolute, $1)=no ++_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= ++_LT_TAGVAR(hardcode_libdir_separator, $1)= ++_LT_TAGVAR(hardcode_minus_L, $1)=no ++_LT_TAGVAR(hardcode_automatic, $1)=no ++_LT_TAGVAR(inherit_rpath, $1)=no ++_LT_TAGVAR(module_cmds, $1)= ++_LT_TAGVAR(module_expsym_cmds, $1)= ++_LT_TAGVAR(link_all_deplibs, $1)=unknown ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++_LT_TAGVAR(no_undefined_flag, $1)= ++_LT_TAGVAR(whole_archive_flag_spec, $1)= ++_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no ++ ++# Source file extension for fc test sources. ++ac_ext=${ac_fc_srcext-f} ++ ++# Object file extension for compiled fc test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# No sense in running all these tests if we already determined that ++# the FC compiler isn't working. Some variables (like enable_shared) ++# are currently assumed to apply to all compilers on this platform, ++# and will be corrupted by setting them based on a non-working compiler. ++if test yes != "$_lt_disable_FC"; then ++ # Code to be used in simple compile tests ++ lt_simple_compile_test_code="\ ++ subroutine t ++ return ++ end ++" ++ ++ # Code to be used in simple link tests ++ lt_simple_link_test_code="\ ++ program t ++ end ++" ++ ++ # ltmain only uses $CC for tagged configurations so make sure $CC is set. ++ _LT_TAG_COMPILER ++ ++ # save warnings/boilerplate of simple test code ++ _LT_COMPILER_BOILERPLATE ++ _LT_LINKER_BOILERPLATE ++ ++ # Allow CC to be a program name with arguments. ++ lt_save_CC=$CC ++ lt_save_GCC=$GCC ++ lt_save_CFLAGS=$CFLAGS ++ CC=${FC-"f95"} ++ CFLAGS=$FCFLAGS ++ compiler=$CC ++ GCC=$ac_cv_fc_compiler_gnu ++ ++ _LT_TAGVAR(compiler, $1)=$CC ++ _LT_CC_BASENAME([$compiler]) ++ ++ if test -n "$compiler"; then ++ AC_MSG_CHECKING([if libtool supports shared libraries]) ++ AC_MSG_RESULT([$can_build_shared]) ++ ++ AC_MSG_CHECKING([whether to build shared libraries]) ++ test no = "$can_build_shared" && enable_shared=no ++ ++ # On AIX, shared libraries and static libraries use the same namespace, and ++ # are all built from PIC. ++ case $host_os in ++ aix3*) ++ test yes = "$enable_shared" && enable_static=no ++ if test -n "$RANLIB"; then ++ archive_cmds="$archive_cmds~\$RANLIB \$lib" ++ postinstall_cmds='$RANLIB $lib' ++ fi ++ ;; ++ aix[[4-9]]*) ++ if test ia64 != "$host_cpu"; then ++ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in ++ yes,aix,yes) ;; # shared object as lib.so file only ++ yes,svr4,*) ;; # shared object as lib.so archive member only ++ yes,*) enable_static=no ;; # shared object in lib.a archive as well ++ esac ++ fi ++ ;; ++ esac ++ AC_MSG_RESULT([$enable_shared]) ++ ++ AC_MSG_CHECKING([whether to build static libraries]) ++ # Make sure either enable_shared or enable_static is yes. ++ test yes = "$enable_shared" || enable_static=yes ++ AC_MSG_RESULT([$enable_static]) ++ ++ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu ++ _LT_TAGVAR(LD, $1)=$LD ++ ++ ## CAVEAT EMPTOR: ++ ## There is no encapsulation within the following macros, do not change ++ ## the running order or otherwise move them around unless you know exactly ++ ## what you are doing... ++ _LT_SYS_HIDDEN_LIBDEPS($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_SYS_DYNAMIC_LINKER($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++ fi # test -n "$compiler" ++ ++ GCC=$lt_save_GCC ++ CC=$lt_save_CC ++ CFLAGS=$lt_save_CFLAGS ++fi # test yes != "$_lt_disable_FC" ++ ++AC_LANG_POP ++])# _LT_LANG_FC_CONFIG ++ ++ ++# _LT_LANG_GCJ_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for the GNU Java Compiler compiler ++# are suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_GCJ_CONFIG], ++[AC_REQUIRE([LT_PROG_GCJ])dnl ++AC_LANG_SAVE ++ ++# Source file extension for Java test sources. ++ac_ext=java ++ ++# Object file extension for compiled Java test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="class foo {}" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_TAG_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_CFLAGS=$CFLAGS ++lt_save_GCC=$GCC ++GCC=yes ++CC=${GCJ-"gcj"} ++CFLAGS=$GCJFLAGS ++compiler=$CC ++_LT_TAGVAR(compiler, $1)=$CC ++_LT_TAGVAR(LD, $1)=$LD ++_LT_CC_BASENAME([$compiler]) ++ ++# GCJ did not exist at the time GCC didn't implicitly link libc in. ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++ ++if test -n "$compiler"; then ++ _LT_COMPILER_NO_RTTI($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++fi ++ ++AC_LANG_RESTORE ++ ++GCC=$lt_save_GCC ++CC=$lt_save_CC ++CFLAGS=$lt_save_CFLAGS ++])# _LT_LANG_GCJ_CONFIG ++ ++ ++# _LT_LANG_GO_CONFIG([TAG]) ++# -------------------------- ++# Ensure that the configuration variables for the GNU Go compiler ++# are suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_GO_CONFIG], ++[AC_REQUIRE([LT_PROG_GO])dnl ++AC_LANG_SAVE ++ ++# Source file extension for Go test sources. ++ac_ext=go ++ ++# Object file extension for compiled Go test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code="package main; func main() { }" ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code='package main; func main() { }' ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_TAG_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_CFLAGS=$CFLAGS ++lt_save_GCC=$GCC ++GCC=yes ++CC=${GOC-"gccgo"} ++CFLAGS=$GOFLAGS ++compiler=$CC ++_LT_TAGVAR(compiler, $1)=$CC ++_LT_TAGVAR(LD, $1)=$LD ++_LT_CC_BASENAME([$compiler]) ++ ++# Go did not exist at the time GCC didn't implicitly link libc in. ++_LT_TAGVAR(archive_cmds_need_lc, $1)=no ++ ++_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds ++_LT_TAGVAR(reload_flag, $1)=$reload_flag ++_LT_TAGVAR(reload_cmds, $1)=$reload_cmds ++ ++if test -n "$compiler"; then ++ _LT_COMPILER_NO_RTTI($1) ++ _LT_COMPILER_PIC($1) ++ _LT_COMPILER_C_O($1) ++ _LT_COMPILER_FILE_LOCKS($1) ++ _LT_LINKER_SHLIBS($1) ++ _LT_LINKER_HARDCODE_LIBPATH($1) ++ ++ _LT_CONFIG($1) ++fi ++ ++AC_LANG_RESTORE ++ ++GCC=$lt_save_GCC ++CC=$lt_save_CC ++CFLAGS=$lt_save_CFLAGS ++])# _LT_LANG_GO_CONFIG ++ ++ ++# _LT_LANG_RC_CONFIG([TAG]) ++# ------------------------- ++# Ensure that the configuration variables for the Windows resource compiler ++# are suitably defined. These variables are subsequently used by _LT_CONFIG ++# to write the compiler configuration to 'libtool'. ++m4_defun([_LT_LANG_RC_CONFIG], ++[AC_REQUIRE([LT_PROG_RC])dnl ++AC_LANG_SAVE ++ ++# Source file extension for RC test sources. ++ac_ext=rc ++ ++# Object file extension for compiled RC test sources. ++objext=o ++_LT_TAGVAR(objext, $1)=$objext ++ ++# Code to be used in simple compile tests ++lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' ++ ++# Code to be used in simple link tests ++lt_simple_link_test_code=$lt_simple_compile_test_code ++ ++# ltmain only uses $CC for tagged configurations so make sure $CC is set. ++_LT_TAG_COMPILER ++ ++# save warnings/boilerplate of simple test code ++_LT_COMPILER_BOILERPLATE ++_LT_LINKER_BOILERPLATE ++ ++# Allow CC to be a program name with arguments. ++lt_save_CC=$CC ++lt_save_CFLAGS=$CFLAGS ++lt_save_GCC=$GCC ++GCC= ++CC=${RC-"windres"} ++CFLAGS= ++compiler=$CC ++_LT_TAGVAR(compiler, $1)=$CC ++_LT_CC_BASENAME([$compiler]) ++_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes ++ ++if test -n "$compiler"; then ++ : ++ _LT_CONFIG($1) ++fi ++ ++GCC=$lt_save_GCC ++AC_LANG_RESTORE ++CC=$lt_save_CC ++CFLAGS=$lt_save_CFLAGS ++])# _LT_LANG_RC_CONFIG ++ ++ ++# LT_PROG_GCJ ++# ----------- ++AC_DEFUN([LT_PROG_GCJ], ++[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], ++ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], ++ [AC_CHECK_TOOL(GCJ, gcj,) ++ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" ++ AC_SUBST(GCJFLAGS)])])[]dnl ++]) ++ ++# Old name: ++AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([LT_AC_PROG_GCJ], []) ++ ++ ++# LT_PROG_GO ++# ---------- ++AC_DEFUN([LT_PROG_GO], ++[AC_CHECK_TOOL(GOC, gccgo,) ++]) ++ ++ ++# LT_PROG_RC ++# ---------- ++AC_DEFUN([LT_PROG_RC], ++[AC_CHECK_TOOL(RC, windres,) ++]) ++ ++# Old name: ++AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([LT_AC_PROG_RC], []) ++ ++ ++# _LT_DECL_EGREP ++# -------------- ++# If we don't have a new enough Autoconf to choose the best grep ++# available, choose the one first in the user's PATH. ++m4_defun([_LT_DECL_EGREP], ++[AC_REQUIRE([AC_PROG_EGREP])dnl ++AC_REQUIRE([AC_PROG_FGREP])dnl ++test -z "$GREP" && GREP=grep ++_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) ++_LT_DECL([], [EGREP], [1], [An ERE matcher]) ++_LT_DECL([], [FGREP], [1], [A literal string matcher]) ++dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too ++AC_SUBST([GREP]) ++]) ++ ++ ++# _LT_DECL_OBJDUMP ++# -------------- ++# If we don't have a new enough Autoconf to choose the best objdump ++# available, choose the one first in the user's PATH. ++m4_defun([_LT_DECL_OBJDUMP], ++[AC_CHECK_TOOL(OBJDUMP, objdump, false) ++test -z "$OBJDUMP" && OBJDUMP=objdump ++_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) ++AC_SUBST([OBJDUMP]) ++]) ++ ++# _LT_DECL_DLLTOOL ++# ---------------- ++# Ensure DLLTOOL variable is set. ++m4_defun([_LT_DECL_DLLTOOL], ++[AC_CHECK_TOOL(DLLTOOL, dlltool, false) ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) ++AC_SUBST([DLLTOOL]) ++]) ++ ++# _LT_DECL_FILECMD ++# ---------------- ++# Check for a file(cmd) program that can be used to detect file type and magic ++m4_defun([_LT_DECL_FILECMD], ++[AC_CHECK_TOOL([FILECMD], [file], [:]) ++_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) ++])# _LD_DECL_FILECMD ++ ++# _LT_DECL_SED ++# ------------ ++# Check for a fully-functional sed program, that truncates ++# as few characters as possible. Prefer GNU sed if found. ++m4_defun([_LT_DECL_SED], ++[AC_PROG_SED ++test -z "$SED" && SED=sed ++Xsed="$SED -e 1s/^X//" ++_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) ++_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], ++ [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ++])# _LT_DECL_SED ++ ++m4_ifndef([AC_PROG_SED], [ ++# NOTE: This macro has been submitted for inclusion into # ++# GNU Autoconf as AC_PROG_SED. When it is available in # ++# a released version of Autoconf we should remove this # ++# macro and use it instead. # ++ ++m4_defun([AC_PROG_SED], ++[AC_MSG_CHECKING([for a sed that does not truncate output]) ++AC_CACHE_VAL(lt_cv_path_SED, ++[# Loop through the user's path and test for sed and gsed. ++# Then use that list of sed's as ones to test for truncation. ++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for lt_ac_prog in sed gsed; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then ++ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" ++ fi ++ done ++ done ++done ++IFS=$as_save_IFS ++lt_ac_max=0 ++lt_ac_count=0 ++# Add /usr/xpg4/bin/sed as it is typically found on Solaris ++# along with /bin/sed that truncates output. ++for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do ++ test ! -f "$lt_ac_sed" && continue ++ cat /dev/null > conftest.in ++ lt_ac_count=0 ++ echo $ECHO_N "0123456789$ECHO_C" >conftest.in ++ # Check for GNU sed and select it if it is found. ++ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then ++ lt_cv_path_SED=$lt_ac_sed ++ break ++ fi ++ while true; do ++ cat conftest.in conftest.in >conftest.tmp ++ mv conftest.tmp conftest.in ++ cp conftest.in conftest.nl ++ echo >>conftest.nl ++ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break ++ cmp -s conftest.out conftest.nl || break ++ # 10000 chars as input seems more than enough ++ test 10 -lt "$lt_ac_count" && break ++ lt_ac_count=`expr $lt_ac_count + 1` ++ if test "$lt_ac_count" -gt "$lt_ac_max"; then ++ lt_ac_max=$lt_ac_count ++ lt_cv_path_SED=$lt_ac_sed ++ fi ++ done ++done ++]) ++SED=$lt_cv_path_SED ++AC_SUBST([SED]) ++AC_MSG_RESULT([$SED]) ++])#AC_PROG_SED ++])#m4_ifndef ++ ++# Old name: ++AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([LT_AC_PROG_SED], []) ++ ++ ++# _LT_CHECK_SHELL_FEATURES ++# ------------------------ ++# Find out whether the shell is Bourne or XSI compatible, ++# or has some other useful features. ++m4_defun([_LT_CHECK_SHELL_FEATURES], ++[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then ++ lt_unset=unset ++else ++ lt_unset=false ++fi ++_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl ++ ++# test EBCDIC or ASCII ++case `echo X|tr X '\101'` in ++ A) # ASCII based system ++ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr ++ lt_SP2NL='tr \040 \012' ++ lt_NL2SP='tr \015\012 \040\040' ++ ;; ++ *) # EBCDIC based system ++ lt_SP2NL='tr \100 \n' ++ lt_NL2SP='tr \r\n \100\100' ++ ;; ++esac ++_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl ++_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ++])# _LT_CHECK_SHELL_FEATURES ++ ++ ++# _LT_PATH_CONVERSION_FUNCTIONS ++# ----------------------------- ++# Determine what file name conversion functions should be used by ++# func_to_host_file (and, implicitly, by func_to_host_path). These are needed ++# for certain cross-compile configurations and native mingw. ++m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++AC_REQUIRE([AC_CANONICAL_BUILD])dnl ++AC_MSG_CHECKING([how to convert $build file names to $host format]) ++AC_CACHE_VAL(lt_cv_to_host_file_cmd, ++[case $host in ++ *-*-mingw* ) ++ case $build in ++ *-*-mingw* ) # actually msys ++ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ++ ;; ++ *-*-cygwin* ) ++ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ++ ;; ++ * ) # otherwise, assume *nix ++ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ++ ;; ++ esac ++ ;; ++ *-*-cygwin* ) ++ case $build in ++ *-*-mingw* ) # actually msys ++ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ++ ;; ++ *-*-cygwin* ) ++ lt_cv_to_host_file_cmd=func_convert_file_noop ++ ;; ++ * ) # otherwise, assume *nix ++ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ++ ;; ++ esac ++ ;; ++ * ) # unhandled hosts (and "normal" native builds) ++ lt_cv_to_host_file_cmd=func_convert_file_noop ++ ;; ++esac ++]) ++to_host_file_cmd=$lt_cv_to_host_file_cmd ++AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) ++_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], ++ [0], [convert $build file names to $host format])dnl ++ ++AC_MSG_CHECKING([how to convert $build file names to toolchain format]) ++AC_CACHE_VAL(lt_cv_to_tool_file_cmd, ++[#assume ordinary cross tools, or native build. ++lt_cv_to_tool_file_cmd=func_convert_file_noop ++case $host in ++ *-*-mingw* ) ++ case $build in ++ *-*-mingw* ) # actually msys ++ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ++ ;; ++ esac ++ ;; ++esac ++]) ++to_tool_file_cmd=$lt_cv_to_tool_file_cmd ++AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) ++_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], ++ [0], [convert $build files to toolchain format])dnl ++])# _LT_PATH_CONVERSION_FUNCTIONS ++ ++# Helper functions for option handling. -*- Autoconf -*- ++# ++# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free ++# Software Foundation, Inc. ++# Written by Gary V. Vaughan, 2004 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# serial 8 ltoptions.m4 ++ ++# This is to help aclocal find these macros, as it can't see m4_define. ++AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) ++ ++ ++# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) ++# ------------------------------------------ ++m4_define([_LT_MANGLE_OPTION], ++[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) ++ ++ ++# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) ++# --------------------------------------- ++# Set option OPTION-NAME for macro MACRO-NAME, and if there is a ++# matching handler defined, dispatch to it. Other OPTION-NAMEs are ++# saved as a flag. ++m4_define([_LT_SET_OPTION], ++[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl ++m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), ++ _LT_MANGLE_DEFUN([$1], [$2]), ++ [m4_warning([Unknown $1 option '$2'])])[]dnl ++]) ++ ++ ++# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) ++# ------------------------------------------------------------ ++# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. ++m4_define([_LT_IF_OPTION], ++[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) ++ ++ ++# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) ++# ------------------------------------------------------- ++# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME ++# are set. ++m4_define([_LT_UNLESS_OPTIONS], ++[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), ++ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), ++ [m4_define([$0_found])])])[]dnl ++m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ++])[]dnl ++]) ++ ++ ++# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) ++# ---------------------------------------- ++# OPTION-LIST is a space-separated list of Libtool options associated ++# with MACRO-NAME. If any OPTION has a matching handler declared with ++# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about ++# the unknown option and exit. ++m4_defun([_LT_SET_OPTIONS], ++[# Set options ++m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), ++ [_LT_SET_OPTION([$1], _LT_Option)]) ++ ++m4_if([$1],[LT_INIT],[ ++ dnl ++ dnl Simply set some default values (i.e off) if boolean options were not ++ dnl specified: ++ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ++ ]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ++ ]) ++ dnl ++ dnl If no reference was made to various pairs of opposing options, then ++ dnl we run the default mode handler for the pair. For example, if neither ++ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared ++ dnl archives by default: ++ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], ++ [_LT_ENABLE_FAST_INSTALL]) ++ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], ++ [_LT_WITH_AIX_SONAME([aix])]) ++ ]) ++])# _LT_SET_OPTIONS ++ ++ ++ ++# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) ++# ----------------------------------------- ++m4_define([_LT_MANGLE_DEFUN], ++[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) ++ ++ ++# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) ++# ----------------------------------------------- ++m4_define([LT_OPTION_DEFINE], ++[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ++])# LT_OPTION_DEFINE ++ ++ ++# dlopen ++# ------ ++LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ++]) ++ ++AU_DEFUN([AC_LIBTOOL_DLOPEN], ++[_LT_SET_OPTION([LT_INIT], [dlopen]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you ++put the 'dlopen' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) ++ ++ ++# win32-dll ++# --------- ++# Declare package support for building win32 dll's. ++LT_OPTION_DEFINE([LT_INIT], [win32-dll], ++[enable_win32_dll=yes ++ ++case $host in ++*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) ++ AC_CHECK_TOOL(AS, as, false) ++ AC_CHECK_TOOL(DLLTOOL, dlltool, false) ++ AC_CHECK_TOOL(OBJDUMP, objdump, false) ++ ;; ++esac ++ ++test -z "$AS" && AS=as ++_LT_DECL([], [AS], [1], [Assembler program])dnl ++ ++test -z "$DLLTOOL" && DLLTOOL=dlltool ++_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl ++ ++test -z "$OBJDUMP" && OBJDUMP=objdump ++_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ++])# win32-dll ++ ++AU_DEFUN([AC_LIBTOOL_WIN32_DLL], ++[AC_REQUIRE([AC_CANONICAL_HOST])dnl ++_LT_SET_OPTION([LT_INIT], [win32-dll]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you ++put the 'win32-dll' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) ++ ++ ++# _LT_ENABLE_SHARED([DEFAULT]) ++# ---------------------------- ++# implement the --enable-shared flag, and supports the 'shared' and ++# 'disable-shared' LT_INIT options. ++# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. ++m4_define([_LT_ENABLE_SHARED], ++[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl ++AC_ARG_ENABLE([shared], ++ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], ++ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_shared=yes ;; ++ no) enable_shared=no ;; ++ *) ++ enable_shared=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for pkg in $enableval; do ++ IFS=$lt_save_ifs ++ if test "X$pkg" = "X$p"; then ++ enable_shared=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) ++ ++ _LT_DECL([build_libtool_libs], [enable_shared], [0], ++ [Whether or not to build shared libraries]) ++])# _LT_ENABLE_SHARED ++ ++LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) ++ ++# Old names: ++AC_DEFUN([AC_ENABLE_SHARED], ++[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ++]) ++ ++AC_DEFUN([AC_DISABLE_SHARED], ++[_LT_SET_OPTION([LT_INIT], [disable-shared]) ++]) ++ ++AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) ++AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_ENABLE_SHARED], []) ++dnl AC_DEFUN([AM_DISABLE_SHARED], []) ++ ++ ++ ++# _LT_ENABLE_STATIC([DEFAULT]) ++# ---------------------------- ++# implement the --enable-static flag, and support the 'static' and ++# 'disable-static' LT_INIT options. ++# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. ++m4_define([_LT_ENABLE_STATIC], ++[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl ++AC_ARG_ENABLE([static], ++ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], ++ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_static=yes ;; ++ no) enable_static=no ;; ++ *) ++ enable_static=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for pkg in $enableval; do ++ IFS=$lt_save_ifs ++ if test "X$pkg" = "X$p"; then ++ enable_static=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [enable_static=]_LT_ENABLE_STATIC_DEFAULT) ++ ++ _LT_DECL([build_old_libs], [enable_static], [0], ++ [Whether or not to build static libraries]) ++])# _LT_ENABLE_STATIC ++ ++LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) ++ ++# Old names: ++AC_DEFUN([AC_ENABLE_STATIC], ++[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ++]) ++ ++AC_DEFUN([AC_DISABLE_STATIC], ++[_LT_SET_OPTION([LT_INIT], [disable-static]) ++]) ++ ++AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) ++AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AM_ENABLE_STATIC], []) ++dnl AC_DEFUN([AM_DISABLE_STATIC], []) ++ ++ ++ ++# _LT_ENABLE_FAST_INSTALL([DEFAULT]) ++# ---------------------------------- ++# implement the --enable-fast-install flag, and support the 'fast-install' ++# and 'disable-fast-install' LT_INIT options. ++# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. ++m4_define([_LT_ENABLE_FAST_INSTALL], ++[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl ++AC_ARG_ENABLE([fast-install], ++ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], ++ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], ++ [p=${PACKAGE-default} ++ case $enableval in ++ yes) enable_fast_install=yes ;; ++ no) enable_fast_install=no ;; ++ *) ++ enable_fast_install=no ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for pkg in $enableval; do ++ IFS=$lt_save_ifs ++ if test "X$pkg" = "X$p"; then ++ enable_fast_install=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) ++ ++_LT_DECL([fast_install], [enable_fast_install], [0], ++ [Whether or not to optimize for fast installation])dnl ++])# _LT_ENABLE_FAST_INSTALL ++ ++LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) ++ ++# Old names: ++AU_DEFUN([AC_ENABLE_FAST_INSTALL], ++[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you put ++the 'fast-install' option into LT_INIT's first parameter.]) ++]) ++ ++AU_DEFUN([AC_DISABLE_FAST_INSTALL], ++[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you put ++the 'disable-fast-install' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) ++dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) ++ ++ ++# _LT_WITH_AIX_SONAME([DEFAULT]) ++# ---------------------------------- ++# implement the --with-aix-soname flag, and support the `aix-soname=aix' ++# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT ++# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. ++m4_define([_LT_WITH_AIX_SONAME], ++[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl ++shared_archive_member_spec= ++case $host,$enable_shared in ++power*-*-aix[[5-9]]*,yes) ++ AC_MSG_CHECKING([which variant of shared library versioning to provide]) ++ AC_ARG_WITH([aix-soname], ++ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], ++ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], ++ [case $withval in ++ aix|svr4|both) ++ ;; ++ *) ++ AC_MSG_ERROR([Unknown argument to --with-aix-soname]) ++ ;; ++ esac ++ lt_cv_with_aix_soname=$with_aix_soname], ++ [AC_CACHE_VAL([lt_cv_with_aix_soname], ++ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) ++ with_aix_soname=$lt_cv_with_aix_soname]) ++ AC_MSG_RESULT([$with_aix_soname]) ++ if test aix != "$with_aix_soname"; then ++ # For the AIX way of multilib, we name the shared archive member ++ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', ++ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. ++ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, ++ # the AIX toolchain works better with OBJECT_MODE set (default 32). ++ if test 64 = "${OBJECT_MODE-32}"; then ++ shared_archive_member_spec=shr_64 ++ else ++ shared_archive_member_spec=shr ++ fi ++ fi ++ ;; ++*) ++ with_aix_soname=aix ++ ;; ++esac ++ ++_LT_DECL([], [shared_archive_member_spec], [0], ++ [Shared archive member basename, for filename based shared library versioning on AIX])dnl ++])# _LT_WITH_AIX_SONAME ++ ++LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) ++LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) ++LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) ++ ++ ++# _LT_WITH_PIC([MODE]) ++# -------------------- ++# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' ++# LT_INIT options. ++# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. ++m4_define([_LT_WITH_PIC], ++[AC_ARG_WITH([pic], ++ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], ++ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], ++ [lt_p=${PACKAGE-default} ++ case $withval in ++ yes|no) pic_mode=$withval ;; ++ *) ++ pic_mode=default ++ # Look at the argument we got. We use all the common list separators. ++ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, ++ for lt_pkg in $withval; do ++ IFS=$lt_save_ifs ++ if test "X$lt_pkg" = "X$lt_p"; then ++ pic_mode=yes ++ fi ++ done ++ IFS=$lt_save_ifs ++ ;; ++ esac], ++ [pic_mode=m4_default([$1], [default])]) ++ ++_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ++])# _LT_WITH_PIC ++ ++LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) ++LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) ++ ++# Old name: ++AU_DEFUN([AC_LIBTOOL_PICMODE], ++[_LT_SET_OPTION([LT_INIT], [pic-only]) ++AC_DIAGNOSE([obsolete], ++[$0: Remove this warning and the call to _LT_SET_OPTION when you ++put the 'pic-only' option into LT_INIT's first parameter.]) ++]) ++ ++dnl aclocal-1.4 backwards compatibility: ++dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ++ ++ ++m4_define([_LTDL_MODE], []) ++LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], ++ [m4_define([_LTDL_MODE], [nonrecursive])]) ++LT_OPTION_DEFINE([LTDL_INIT], [recursive], ++ [m4_define([_LTDL_MODE], [recursive])]) ++LT_OPTION_DEFINE([LTDL_INIT], [subproject], ++ [m4_define([_LTDL_MODE], [subproject])]) ++ ++m4_define([_LTDL_TYPE], []) ++LT_OPTION_DEFINE([LTDL_INIT], [installable], ++ [m4_define([_LTDL_TYPE], [installable])]) ++LT_OPTION_DEFINE([LTDL_INIT], [convenience], ++ [m4_define([_LTDL_TYPE], [convenience])]) ++ ++# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- ++# ++# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software ++# Foundation, Inc. ++# Written by Gary V. Vaughan, 2004 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# serial 6 ltsugar.m4 ++ ++# This is to help aclocal find these macros, as it can't see m4_define. ++AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) ++ ++ ++# lt_join(SEP, ARG1, [ARG2...]) ++# ----------------------------- ++# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their ++# associated separator. ++# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier ++# versions in m4sugar had bugs. ++m4_define([lt_join], ++[m4_if([$#], [1], [], ++ [$#], [2], [[$2]], ++ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) ++m4_define([_lt_join], ++[m4_if([$#$2], [2], [], ++ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) ++ ++ ++# lt_car(LIST) ++# lt_cdr(LIST) ++# ------------ ++# Manipulate m4 lists. ++# These macros are necessary as long as will still need to support ++# Autoconf-2.59, which quotes differently. ++m4_define([lt_car], [[$1]]) ++m4_define([lt_cdr], ++[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], ++ [$#], 1, [], ++ [m4_dquote(m4_shift($@))])]) ++m4_define([lt_unquote], $1) ++ ++ ++# lt_append(MACRO-NAME, STRING, [SEPARATOR]) ++# ------------------------------------------ ++# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. ++# Note that neither SEPARATOR nor STRING are expanded; they are appended ++# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). ++# No SEPARATOR is output if MACRO-NAME was previously undefined (different ++# than defined and empty). ++# ++# This macro is needed until we can rely on Autoconf 2.62, since earlier ++# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. ++m4_define([lt_append], ++[m4_define([$1], ++ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) ++ ++ ++ ++# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) ++# ---------------------------------------------------------- ++# Produce a SEP delimited list of all paired combinations of elements of ++# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list ++# has the form PREFIXmINFIXSUFFIXn. ++# Needed until we can rely on m4_combine added in Autoconf 2.62. ++m4_define([lt_combine], ++[m4_if(m4_eval([$# > 3]), [1], ++ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl ++[[m4_foreach([_Lt_prefix], [$2], ++ [m4_foreach([_Lt_suffix], ++ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, ++ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) ++ ++ ++# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) ++# ----------------------------------------------------------------------- ++# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited ++# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. ++m4_define([lt_if_append_uniq], ++[m4_ifdef([$1], ++ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], ++ [lt_append([$1], [$2], [$3])$4], ++ [$5])], ++ [lt_append([$1], [$2], [$3])$4])]) ++ ++ ++# lt_dict_add(DICT, KEY, VALUE) ++# ----------------------------- ++m4_define([lt_dict_add], ++[m4_define([$1($2)], [$3])]) ++ ++ ++# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) ++# -------------------------------------------- ++m4_define([lt_dict_add_subkey], ++[m4_define([$1($2:$3)], [$4])]) ++ ++ ++# lt_dict_fetch(DICT, KEY, [SUBKEY]) ++# ---------------------------------- ++m4_define([lt_dict_fetch], ++[m4_ifval([$3], ++ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), ++ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) ++ ++ ++# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) ++# ----------------------------------------------------------------- ++m4_define([lt_if_dict_fetch], ++[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], ++ [$5], ++ [$6])]) ++ ++ ++# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) ++# -------------------------------------------------------------- ++m4_define([lt_dict_filter], ++[m4_if([$5], [], [], ++ [lt_join(m4_quote(m4_default([$4], [[, ]])), ++ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), ++ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ++]) ++ ++# ltversion.m4 -- version numbers -*- Autoconf -*- ++# ++# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation, ++# Inc. ++# Written by Scott James Remnant, 2004 ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# @configure_input@ ++ ++# serial 4249 ltversion.m4 ++# This file is part of GNU Libtool ++ ++m4_define([LT_PACKAGE_VERSION], [2.4.7.4-1ec8f-dirty]) ++m4_define([LT_PACKAGE_REVISION], [2.4.7.4]) ++ ++AC_DEFUN([LTVERSION_VERSION], ++[macro_version='2.4.7.4-1ec8f-dirty' ++macro_revision='2.4.7.4' ++_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) ++_LT_DECL(, macro_revision, 0) ++]) ++ ++# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- ++# ++# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free ++# Software Foundation, Inc. ++# Written by Scott James Remnant, 2004. ++# ++# This file is free software; the Free Software Foundation gives ++# unlimited permission to copy and/or distribute it, with or without ++# modifications, as long as this notice is preserved. ++ ++# serial 5 lt~obsolete.m4 ++ ++# These exist entirely to fool aclocal when bootstrapping libtool. ++# ++# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), ++# which have later been changed to m4_define as they aren't part of the ++# exported API, or moved to Autoconf or Automake where they belong. ++# ++# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN ++# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us ++# using a macro with the same name in our local m4/libtool.m4 it'll ++# pull the old libtool.m4 in (it doesn't see our shiny new m4_define ++# and doesn't know about Autoconf macros at all.) ++# ++# So we provide this file, which has a silly filename so it's always ++# included after everything else. This provides aclocal with the ++# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything ++# because those macros already exist, or will be overwritten later. ++# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. ++# ++# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. ++# Yes, that means every name once taken will need to remain here until ++# we give up compatibility with versions before 1.7, at which point ++# we need to keep only those names which we still refer to. ++ ++# This is to help aclocal find these macros, as it can't see m4_define. ++AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) ++ ++m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) ++m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) ++m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) ++m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) ++m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) ++m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) ++m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) ++m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) ++m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) ++m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) ++m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) ++m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) ++m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) ++m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) ++m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) ++m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) ++m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) ++m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) ++m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) ++m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) ++m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) ++m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) ++m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) ++m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) ++m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) ++m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) ++m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) ++m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) ++m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) ++m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) ++m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) ++m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) ++m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) ++m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) ++m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) ++m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) ++m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) ++m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) ++m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) ++m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) ++m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) ++m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) ++m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) ++m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) ++m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) ++m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) ++m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) ++m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) ++m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) ++m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) ++m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) ++m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) ++m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) ++ ++# nls.m4 serial 6 (gettext-0.20.2) ++dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016, 2019-2022 Free ++dnl Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++dnl ++dnl This file can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Lesser General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Lesser General Public License, and the rest of the GNU ++dnl gettext package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. ++dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. ++ ++AC_PREREQ([2.50]) ++ ++AC_DEFUN([AM_NLS], ++[ ++ AC_MSG_CHECKING([whether NLS is requested]) ++ dnl Default is enabled NLS ++ AC_ARG_ENABLE([nls], ++ [ --disable-nls do not use Native Language Support], ++ USE_NLS=$enableval, USE_NLS=yes) ++ AC_MSG_RESULT([$USE_NLS]) ++ AC_SUBST([USE_NLS]) ++]) ++ ++# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- ++# serial 11 (pkg-config-0.29.1) ++ ++dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. ++dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> ++dnl ++dnl This program is free software; you can redistribute it and/or modify ++dnl it under the terms of the GNU General Public License as published by ++dnl the Free Software Foundation; either version 2 of the License, or ++dnl (at your option) any later version. ++dnl ++dnl This program is distributed in the hope that it will be useful, but ++dnl WITHOUT ANY WARRANTY; without even the implied warranty of ++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++dnl General Public License for more details. ++dnl ++dnl You should have received a copy of the GNU General Public License ++dnl along with this program; if not, write to the Free Software ++dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ++dnl 02111-1307, USA. ++dnl ++dnl As a special exception to the GNU General Public License, if you ++dnl distribute this file as part of a program that contains a ++dnl configuration script generated by Autoconf, you may include it under ++dnl the same distribution terms that you use for the rest of that ++dnl program. ++ ++dnl PKG_PREREQ(MIN-VERSION) ++dnl ----------------------- ++dnl Since: 0.29 ++dnl ++dnl Verify that the version of the pkg-config macros are at least ++dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's ++dnl installed version of pkg-config, this checks the developer's version ++dnl of pkg.m4 when generating configure. ++dnl ++dnl To ensure that this macro is defined, also add: ++dnl m4_ifndef([PKG_PREREQ], ++dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) ++dnl ++dnl See the "Since" comment for each macro you use to see what version ++dnl of the macros you require. ++m4_defun([PKG_PREREQ], ++[m4_define([PKG_MACROS_VERSION], [0.29.1]) ++m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, ++ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ++])dnl PKG_PREREQ ++ ++dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) ++dnl ---------------------------------- ++dnl Since: 0.16 ++dnl ++dnl Search for the pkg-config tool and set the PKG_CONFIG variable to ++dnl first found in the path. Checks that the version of pkg-config found ++dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is ++dnl used since that's the first version where most current features of ++dnl pkg-config existed. ++AC_DEFUN([PKG_PROG_PKG_CONFIG], ++[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) ++m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) ++m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) ++AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) ++AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) ++AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) ++ ++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then ++ AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) ++fi ++if test -n "$PKG_CONFIG"; then ++ _pkg_min_version=m4_default([$1], [0.9.0]) ++ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) ++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then ++ AC_MSG_RESULT([yes]) ++ else ++ AC_MSG_RESULT([no]) ++ PKG_CONFIG="" ++ fi ++fi[]dnl ++])dnl PKG_PROG_PKG_CONFIG ++ ++dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------------------------------- ++dnl Since: 0.18 ++dnl ++dnl Check to see whether a particular set of modules exists. Similar to ++dnl PKG_CHECK_MODULES(), but does not set variables or print errors. ++dnl ++dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++dnl only at the first occurence in configure.ac, so if the first place ++dnl it's called might be skipped (such as if it is within an "if", you ++dnl have to call PKG_CHECK_EXISTS manually ++AC_DEFUN([PKG_CHECK_EXISTS], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++if test -n "$PKG_CONFIG" && \ ++ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then ++ m4_default([$2], [:]) ++m4_ifvaln([$3], [else ++ $3])dnl ++fi]) ++ ++dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) ++dnl --------------------------------------------- ++dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting ++dnl pkg_failed based on the result. ++m4_define([_PKG_CONFIG], ++[if test -n "$$1"; then ++ pkg_cv_[]$1="$$1" ++ elif test -n "$PKG_CONFIG"; then ++ PKG_CHECK_EXISTS([$3], ++ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ], ++ [pkg_failed=yes]) ++ else ++ pkg_failed=untried ++fi[]dnl ++])dnl _PKG_CONFIG ++ ++dnl _PKG_SHORT_ERRORS_SUPPORTED ++dnl --------------------------- ++dnl Internal check to see if pkg-config supports short errors. ++AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) ++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then ++ _pkg_short_errors_supported=yes ++else ++ _pkg_short_errors_supported=no ++fi[]dnl ++])dnl _PKG_SHORT_ERRORS_SUPPORTED ++ ++ ++dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++dnl [ACTION-IF-NOT-FOUND]) ++dnl -------------------------------------------------------------- ++dnl Since: 0.4.0 ++dnl ++dnl Note that if there is a possibility the first call to ++dnl PKG_CHECK_MODULES might not happen, you should be sure to include an ++dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac ++AC_DEFUN([PKG_CHECK_MODULES], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl ++AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl ++ ++pkg_failed=no ++AC_MSG_CHECKING([for $1]) ++ ++_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) ++_PKG_CONFIG([$1][_LIBS], [libs], [$2]) ++ ++m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS ++and $1[]_LIBS to avoid the need to call pkg-config. ++See the pkg-config man page for more details.]) ++ ++if test $pkg_failed = yes; then ++ AC_MSG_RESULT([no]) ++ _PKG_SHORT_ERRORS_SUPPORTED ++ if test $_pkg_short_errors_supported = yes; then ++ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` ++ else ++ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ++ ++ m4_default([$4], [AC_MSG_ERROR( ++[Package requirements ($2) were not met: ++ ++$$1_PKG_ERRORS ++ ++Consider adjusting the PKG_CONFIG_PATH environment variable if you ++installed software in a non-standard prefix. ++ ++_PKG_TEXT])[]dnl ++ ]) ++elif test $pkg_failed = untried; then ++ AC_MSG_RESULT([no]) ++ m4_default([$4], [AC_MSG_FAILURE( ++[The pkg-config script could not be found or is too old. Make sure it ++is in your PATH or set the PKG_CONFIG environment variable to the full ++path to pkg-config. ++ ++_PKG_TEXT ++ ++To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl ++ ]) ++else ++ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS ++ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS ++ AC_MSG_RESULT([yes]) ++ $3 ++fi[]dnl ++])dnl PKG_CHECK_MODULES ++ ++ ++dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], ++dnl [ACTION-IF-NOT-FOUND]) ++dnl --------------------------------------------------------------------- ++dnl Since: 0.29 ++dnl ++dnl Checks for existence of MODULES and gathers its build flags with ++dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags ++dnl and VARIABLE-PREFIX_LIBS from --libs. ++dnl ++dnl Note that if there is a possibility the first call to ++dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to ++dnl include an explicit call to PKG_PROG_PKG_CONFIG in your ++dnl configure.ac. ++AC_DEFUN([PKG_CHECK_MODULES_STATIC], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++_save_PKG_CONFIG=$PKG_CONFIG ++PKG_CONFIG="$PKG_CONFIG --static" ++PKG_CHECK_MODULES($@) ++PKG_CONFIG=$_save_PKG_CONFIG[]dnl ++])dnl PKG_CHECK_MODULES_STATIC ++ ++ ++dnl PKG_INSTALLDIR([DIRECTORY]) ++dnl ------------------------- ++dnl Since: 0.27 ++dnl ++dnl Substitutes the variable pkgconfigdir as the location where a module ++dnl should install pkg-config .pc files. By default the directory is ++dnl $libdir/pkgconfig, but the default can be changed by passing ++dnl DIRECTORY. The user can override through the --with-pkgconfigdir ++dnl parameter. ++AC_DEFUN([PKG_INSTALLDIR], ++[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) ++m4_pushdef([pkg_description], ++ [pkg-config installation directory @<:@]pkg_default[@:>@]) ++AC_ARG_WITH([pkgconfigdir], ++ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, ++ [with_pkgconfigdir=]pkg_default) ++AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) ++m4_popdef([pkg_default]) ++m4_popdef([pkg_description]) ++])dnl PKG_INSTALLDIR ++ ++ ++dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) ++dnl -------------------------------- ++dnl Since: 0.27 ++dnl ++dnl Substitutes the variable noarch_pkgconfigdir as the location where a ++dnl module should install arch-independent pkg-config .pc files. By ++dnl default the directory is $datadir/pkgconfig, but the default can be ++dnl changed by passing DIRECTORY. The user can override through the ++dnl --with-noarch-pkgconfigdir parameter. ++AC_DEFUN([PKG_NOARCH_INSTALLDIR], ++[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) ++m4_pushdef([pkg_description], ++ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) ++AC_ARG_WITH([noarch-pkgconfigdir], ++ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, ++ [with_noarch_pkgconfigdir=]pkg_default) ++AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) ++m4_popdef([pkg_default]) ++m4_popdef([pkg_description]) ++])dnl PKG_NOARCH_INSTALLDIR ++ ++ ++dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, ++dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) ++dnl ------------------------------------------- ++dnl Since: 0.28 ++dnl ++dnl Retrieves the value of the pkg-config variable for the given module. ++AC_DEFUN([PKG_CHECK_VAR], ++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl ++AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl ++ ++_PKG_CONFIG([$1], [variable="][$3]["], [$2]) ++AS_VAR_COPY([$1], [pkg_cv_][$1]) ++ ++AS_VAR_IF([$1], [""], [$5], [$4])dnl ++])dnl PKG_CHECK_VAR ++ ++dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES, ++dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND], ++dnl [DESCRIPTION], [DEFAULT]) ++dnl ------------------------------------------ ++dnl ++dnl Prepare a "--with-" configure option using the lowercase ++dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and ++dnl PKG_CHECK_MODULES in a single macro. ++AC_DEFUN([PKG_WITH_MODULES], ++[ ++m4_pushdef([with_arg], m4_tolower([$1])) ++ ++m4_pushdef([description], ++ [m4_default([$5], [build with ]with_arg[ support])]) ++ ++m4_pushdef([def_arg], [m4_default([$6], [auto])]) ++m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes]) ++m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no]) ++ ++m4_case(def_arg, ++ [yes],[m4_pushdef([with_without], [--without-]with_arg)], ++ [m4_pushdef([with_without],[--with-]with_arg)]) ++ ++AC_ARG_WITH(with_arg, ++ AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),, ++ [AS_TR_SH([with_]with_arg)=def_arg]) ++ ++AS_CASE([$AS_TR_SH([with_]with_arg)], ++ [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)], ++ [auto],[PKG_CHECK_MODULES([$1],[$2], ++ [m4_n([def_action_if_found]) $3], ++ [m4_n([def_action_if_not_found]) $4])]) ++ ++m4_popdef([with_arg]) ++m4_popdef([description]) ++m4_popdef([def_arg]) ++ ++])dnl PKG_WITH_MODULES ++ ++dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES, ++dnl [DESCRIPTION], [DEFAULT]) ++dnl ----------------------------------------------- ++dnl ++dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES ++dnl check._[VARIABLE-PREFIX] is exported as make variable. ++AC_DEFUN([PKG_HAVE_WITH_MODULES], ++[ ++PKG_WITH_MODULES([$1],[$2],,,[$3],[$4]) ++ ++AM_CONDITIONAL([HAVE_][$1], ++ [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"]) ++])dnl PKG_HAVE_WITH_MODULES ++ ++dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES, ++dnl [DESCRIPTION], [DEFAULT]) ++dnl ------------------------------------------------------ ++dnl ++dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after ++dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make ++dnl and preprocessor variable. ++AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES], ++[ ++PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4]) ++ ++AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], ++ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ++])dnl PKG_HAVE_DEFINE_WITH_MODULES ++ ++# po.m4 serial 32 (gettext-0.21.1) ++dnl Copyright (C) 1995-2014, 2016, 2018-2022 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++dnl ++dnl This file can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Lesser General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Lesser General Public License, and the rest of the GNU ++dnl gettext package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. ++dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. ++ ++AC_PREREQ([2.60]) ++ ++dnl Checks for all prerequisites of the po subdirectory. ++AC_DEFUN([AM_PO_SUBDIRS], ++[ ++ AC_REQUIRE([AC_PROG_MAKE_SET])dnl ++ AC_REQUIRE([AC_PROG_INSTALL])dnl ++ AC_REQUIRE([AC_PROG_MKDIR_P])dnl ++ AC_REQUIRE([AC_PROG_SED])dnl ++ AC_REQUIRE([AM_NLS])dnl ++ ++ dnl Release version of the gettext macros. This is used to ensure that ++ dnl the gettext macros and po/Makefile.in.in are in sync. ++ AC_SUBST([GETTEXT_MACRO_VERSION], [0.20]) ++ ++ dnl Perform the following tests also if --disable-nls has been given, ++ dnl because they are needed for "make dist" to work. ++ ++ dnl Search for GNU msgfmt in the PATH. ++ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. ++ dnl The second test excludes FreeBSD msgfmt. ++ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, ++ [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && ++ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], ++ :) ++ AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) ++ ++ dnl Test whether it is GNU msgfmt >= 0.15. ++changequote(,)dnl ++ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in ++ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; ++ *) GMSGFMT_015=$GMSGFMT ;; ++ esac ++changequote([,])dnl ++ AC_SUBST([GMSGFMT_015]) ++ ++ dnl Search for GNU xgettext 0.12 or newer in the PATH. ++ dnl The first test excludes Solaris xgettext and early GNU xgettext versions. ++ dnl The second test excludes FreeBSD xgettext. ++ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, ++ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && ++ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], ++ :) ++ dnl Remove leftover from FreeBSD xgettext call. ++ rm -f messages.po ++ ++ dnl Test whether it is GNU xgettext >= 0.15. ++changequote(,)dnl ++ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in ++ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; ++ *) XGETTEXT_015=$XGETTEXT ;; ++ esac ++changequote([,])dnl ++ AC_SUBST([XGETTEXT_015]) ++ ++ dnl Search for GNU msgmerge 0.11 or newer in the PATH. ++ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, ++ [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) ++ ++ dnl Test whether it is GNU msgmerge >= 0.20. ++ if LC_ALL=C $MSGMERGE --help | grep ' --for-msgfmt ' >/dev/null; then ++ MSGMERGE_FOR_MSGFMT_OPTION='--for-msgfmt' ++ else ++ dnl Test whether it is GNU msgmerge >= 0.12. ++ if LC_ALL=C $MSGMERGE --help | grep ' --no-fuzzy-matching ' >/dev/null; then ++ MSGMERGE_FOR_MSGFMT_OPTION='--no-fuzzy-matching --no-location --quiet' ++ else ++ dnl With these old versions, $(MSGMERGE) $(MSGMERGE_FOR_MSGFMT_OPTION) is ++ dnl slow. But this is not a big problem, as such old gettext versions are ++ dnl hardly in use any more. ++ MSGMERGE_FOR_MSGFMT_OPTION='--no-location --quiet' ++ fi ++ fi ++ AC_SUBST([MSGMERGE_FOR_MSGFMT_OPTION]) ++ ++ dnl Support for AM_XGETTEXT_OPTION. ++ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= ++ AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) ++ ++ AC_CONFIG_COMMANDS([po-directories], [[ ++ for ac_file in $CONFIG_FILES; do ++ # Support "outfile[:infile[:infile...]]" ++ case "$ac_file" in ++ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; ++ esac ++ # PO directories have a Makefile.in generated from Makefile.in.in. ++ case "$ac_file" in */Makefile.in) ++ # Adjust a relative srcdir. ++ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ++ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` ++ # In autoconf-2.13 it is called $ac_given_srcdir. ++ # In autoconf-2.50 it is called $srcdir. ++ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" ++ case "$ac_given_srcdir" in ++ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; ++ /*) top_srcdir="$ac_given_srcdir" ;; ++ *) top_srcdir="$ac_dots$ac_given_srcdir" ;; ++ esac ++ # Treat a directory as a PO directory if and only if it has a ++ # POTFILES.in file. This allows packages to have multiple PO ++ # directories under different names or in different locations. ++ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then ++ rm -f "$ac_dir/POTFILES" ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" ++ gt_tab=`printf '\t'` ++ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" ++ POMAKEFILEDEPS="POTFILES.in" ++ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend ++ # on $ac_dir but don't depend on user-specified configuration ++ # parameters. ++ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then ++ # The LINGUAS file contains the set of available languages. ++ if test -n "$OBSOLETE_ALL_LINGUAS"; then ++ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" ++ fi ++ ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` ++ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" ++ else ++ # The set of available languages was given in configure.in. ++ ALL_LINGUAS=$OBSOLETE_ALL_LINGUAS ++ fi ++ # Compute POFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) ++ # Compute UPDATEPOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) ++ # Compute DUMMYPOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) ++ # Compute GMOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) ++ case "$ac_given_srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++ esac ++ POFILES= ++ UPDATEPOFILES= ++ DUMMYPOFILES= ++ GMOFILES= ++ for lang in $ALL_LINGUAS; do ++ POFILES="$POFILES $srcdirpre$lang.po" ++ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" ++ DUMMYPOFILES="$DUMMYPOFILES $lang.nop" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ done ++ # CATALOGS depends on both $ac_dir and the user's LINGUAS ++ # environment variable. ++ INST_LINGUAS= ++ if test -n "$ALL_LINGUAS"; then ++ for presentlang in $ALL_LINGUAS; do ++ useit=no ++ if test "%UNSET%" != "$LINGUAS"; then ++ desiredlanguages="$LINGUAS" ++ else ++ desiredlanguages="$ALL_LINGUAS" ++ fi ++ for desiredlang in $desiredlanguages; do ++ # Use the presentlang catalog if desiredlang is ++ # a. equal to presentlang, or ++ # b. a variant of presentlang (because in this case, ++ # presentlang can be used as a fallback for messages ++ # which are not translated in the desiredlang catalog). ++ case "$desiredlang" in ++ "$presentlang" | "$presentlang"_* | "$presentlang".* | "$presentlang"@*) ++ useit=yes ++ ;; ++ esac ++ done ++ if test $useit = yes; then ++ INST_LINGUAS="$INST_LINGUAS $presentlang" ++ fi ++ done ++ fi ++ CATALOGS= ++ if test -n "$INST_LINGUAS"; then ++ for lang in $INST_LINGUAS; do ++ CATALOGS="$CATALOGS $lang.gmo" ++ done ++ fi ++ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" ++ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" ++ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do ++ if test -f "$f"; then ++ case "$f" in ++ *.orig | *.bak | *~) ;; ++ *) cat "$f" >> "$ac_dir/Makefile" ;; ++ esac ++ fi ++ done ++ fi ++ ;; ++ esac ++ done]], ++ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute ++ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. ++ OBSOLETE_ALL_LINGUAS="$ALL_LINGUAS" ++ # Capture the value of LINGUAS because we need it to compute CATALOGS. ++ LINGUAS="${LINGUAS-%UNSET%}" ++ ]) ++]) ++ ++dnl Postprocesses a Makefile in a directory containing PO files. ++AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], ++[ ++ # When this code is run, in config.status, two variables have already been ++ # set: ++ # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, ++ # - LINGUAS is the value of the environment variable LINGUAS at configure ++ # time. ++ ++changequote(,)dnl ++ # Adjust a relative srcdir. ++ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ++ ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` ++ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` ++ # In autoconf-2.13 it is called $ac_given_srcdir. ++ # In autoconf-2.50 it is called $srcdir. ++ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" ++ case "$ac_given_srcdir" in ++ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; ++ /*) top_srcdir="$ac_given_srcdir" ;; ++ *) top_srcdir="$ac_dots$ac_given_srcdir" ;; ++ esac ++ ++ # Find a way to echo strings without interpreting backslash. ++ if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then ++ gt_echo='echo' ++ else ++ if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then ++ gt_echo='printf %s\n' ++ else ++ echo_func () { ++ cat <<EOT ++$* ++EOT ++ } ++ gt_echo='echo_func' ++ fi ++ fi ++ ++ # A sed script that extracts the value of VARIABLE from a Makefile. ++ tab=`printf '\t'` ++ sed_x_variable=' ++# Test if the hold space is empty. ++x ++s/P/P/ ++x ++ta ++# Yes it was empty. Look if we have the expected variable definition. ++/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=/{ ++ # Seen the first line of the variable definition. ++ s/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=// ++ ba ++} ++bd ++:a ++# Here we are processing a line from the variable definition. ++# Remove comment, more precisely replace it with a space. ++s/#.*$/ / ++# See if the line ends in a backslash. ++tb ++:b ++s/\\$// ++# Print the line, without the trailing backslash. ++p ++tc ++# There was no trailing backslash. The end of the variable definition is ++# reached. Clear the hold space. ++s/^.*$// ++x ++bd ++:c ++# A trailing backslash means that the variable definition continues in the ++# next line. Put a nonempty string into the hold space to indicate this. ++s/^.*$/P/ ++x ++:d ++' ++changequote([,])dnl ++ ++ # Set POTFILES to the value of the Makefile variable POTFILES. ++ sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'` ++ POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"` ++ # Compute POTFILES_DEPS as ++ # $(foreach file, $(POTFILES), $(top_srcdir)/$(file)) ++ POTFILES_DEPS= ++ for file in $POTFILES; do ++ POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file" ++ done ++ POMAKEFILEDEPS="" ++ ++ if test -n "$OBSOLETE_ALL_LINGUAS"; then ++ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" ++ fi ++ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then ++ # The LINGUAS file contains the set of available languages. ++ ALL_LINGUAS=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` ++ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" ++ else ++ # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS. ++ sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'` ++ ALL_LINGUAS=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"` ++ fi ++ # Compute POFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) ++ # Compute UPDATEPOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) ++ # Compute DUMMYPOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) ++ # Compute GMOFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) ++ # Compute PROPERTIESFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).properties) ++ # Compute CLASSFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(DOMAIN)_$(lang).class) ++ # Compute QMFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm) ++ # Compute MSGFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg) ++ # Compute RESOURCESDLLFILES ++ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll) ++ case "$ac_given_srcdir" in ++ .) srcdirpre= ;; ++ *) srcdirpre='$(srcdir)/' ;; ++ esac ++ POFILES= ++ UPDATEPOFILES= ++ DUMMYPOFILES= ++ GMOFILES= ++ PROPERTIESFILES= ++ CLASSFILES= ++ QMFILES= ++ MSGFILES= ++ RESOURCESDLLFILES= ++ for lang in $ALL_LINGUAS; do ++ POFILES="$POFILES $srcdirpre$lang.po" ++ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" ++ DUMMYPOFILES="$DUMMYPOFILES $lang.nop" ++ GMOFILES="$GMOFILES $srcdirpre$lang.gmo" ++ PROPERTIESFILES="$PROPERTIESFILES \$(srcdir)/\$(DOMAIN)_$lang.properties" ++ CLASSFILES="$CLASSFILES \$(srcdir)/\$(DOMAIN)_$lang.class" ++ QMFILES="$QMFILES $srcdirpre$lang.qm" ++ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` ++ MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg" ++ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` ++ RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll" ++ done ++ # CATALOGS depends on both $ac_dir and the user's LINGUAS ++ # environment variable. ++ INST_LINGUAS= ++ if test -n "$ALL_LINGUAS"; then ++ for presentlang in $ALL_LINGUAS; do ++ useit=no ++ if test "%UNSET%" != "$LINGUAS"; then ++ desiredlanguages="$LINGUAS" ++ else ++ desiredlanguages="$ALL_LINGUAS" ++ fi ++ for desiredlang in $desiredlanguages; do ++ # Use the presentlang catalog if desiredlang is ++ # a. equal to presentlang, or ++ # b. a variant of presentlang (because in this case, ++ # presentlang can be used as a fallback for messages ++ # which are not translated in the desiredlang catalog). ++ case "$desiredlang" in ++ "$presentlang" | "$presentlang"_* | "$presentlang".* | "$presentlang"@*) ++ useit=yes ++ ;; ++ esac ++ done ++ if test $useit = yes; then ++ INST_LINGUAS="$INST_LINGUAS $presentlang" ++ fi ++ done ++ fi ++ CATALOGS= ++ JAVACATALOGS= ++ QTCATALOGS= ++ TCLCATALOGS= ++ CSHARPCATALOGS= ++ if test -n "$INST_LINGUAS"; then ++ for lang in $INST_LINGUAS; do ++ CATALOGS="$CATALOGS $lang.gmo" ++ JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties" ++ QTCATALOGS="$QTCATALOGS $lang.qm" ++ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` ++ TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg" ++ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` ++ CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll" ++ done ++ fi ++ ++ sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp" ++ tab=`printf '\t'` ++ if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then ++ # Add dependencies that cannot be formulated as a simple suffix rule. ++ for lang in $ALL_LINGUAS; do ++ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` ++ cat >> "$ac_file.tmp" <<EOF ++$frobbedlang.msg: $lang.po ++${tab}@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \ ++${tab}\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } ++EOF ++ done ++ fi ++ if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then ++ # Add dependencies that cannot be formulated as a simple suffix rule. ++ for lang in $ALL_LINGUAS; do ++ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` ++ cat >> "$ac_file.tmp" <<EOF ++$frobbedlang/\$(DOMAIN).resources.dll: $lang.po ++${tab}@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \ ++${tab}\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } ++EOF ++ done ++ fi ++ if test -n "$POMAKEFILEDEPS"; then ++ cat >> "$ac_file.tmp" <<EOF ++Makefile: $POMAKEFILEDEPS ++EOF ++ fi ++ mv "$ac_file.tmp" "$ac_file" ++]) ++ ++dnl Initializes the accumulator used by AM_XGETTEXT_OPTION. ++AC_DEFUN([AM_XGETTEXT_OPTION_INIT], ++[ ++ XGETTEXT_EXTRA_OPTIONS= ++]) ++ ++dnl Registers an option to be passed to xgettext in the po subdirectory. ++AC_DEFUN([AM_XGETTEXT_OPTION], ++[ ++ AC_REQUIRE([AM_XGETTEXT_OPTION_INIT]) ++ XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1" ++]) ++ ++# progtest.m4 serial 9 (gettext-0.21.1) ++dnl Copyright (C) 1996-2003, 2005, 2008-2022 Free Software Foundation, Inc. ++dnl This file is free software; the Free Software Foundation ++dnl gives unlimited permission to copy and/or distribute it, ++dnl with or without modifications, as long as this notice is preserved. ++dnl ++dnl This file can be used in projects which are not available under ++dnl the GNU General Public License or the GNU Lesser General Public ++dnl License but which still want to provide support for the GNU gettext ++dnl functionality. ++dnl Please note that the actual code of the GNU gettext library is covered ++dnl by the GNU Lesser General Public License, and the rest of the GNU ++dnl gettext package is covered by the GNU General Public License. ++dnl They are *not* in the public domain. ++ ++dnl Authors: ++dnl Ulrich Drepper <drepper@cygnus.com>, 1996. ++ ++AC_PREREQ([2.53]) ++ ++# Search path for a program which passes the given test. ++ ++dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, ++dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) ++AC_DEFUN([AM_PATH_PROG_WITH_TEST], ++[ ++# Prepare PATH_SEPARATOR. ++# The user is always right. ++if test "${PATH_SEPARATOR+set}" != set; then ++ # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which ++ # contains only /bin. Note that ksh looks also at the FPATH variable, ++ # so we have to set that as well for the test. ++ PATH_SEPARATOR=: ++ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ ++ && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ ++ || PATH_SEPARATOR=';' ++ } ++fi ++ ++# Find out how to test for executable files. Don't use a zero-byte file, ++# as systems may use methods other than mode bits to determine executability. ++cat >conf$$.file <<_ASEOF ++#! /bin/sh ++exit 0 ++_ASEOF ++chmod +x conf$$.file ++if test -x conf$$.file >/dev/null 2>&1; then ++ ac_executable_p="test -x" ++else ++ ac_executable_p="test -f" ++fi ++rm -f conf$$.file ++ ++# Extract the first word of "$2", so it can be a program name with args. ++set dummy $2; ac_word=[$]2 ++AC_MSG_CHECKING([for $ac_word]) ++AC_CACHE_VAL([ac_cv_path_$1], ++[case "[$]$1" in ++ [[\\/]]* | ?:[[\\/]]*) ++ ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ++ ;; ++ *) ++ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR ++ for ac_dir in m4_if([$5], , $PATH, [$5]); do ++ IFS="$ac_save_IFS" ++ test -z "$ac_dir" && ac_dir=. ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then ++ echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD ++ if [$3]; then ++ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" ++ break 2 ++ fi ++ fi ++ done ++ done ++ IFS="$ac_save_IFS" ++dnl If no 4th arg is given, leave the cache variable unset, ++dnl so AC_PATH_PROGS will keep looking. ++m4_if([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ++])dnl ++ ;; ++esac])dnl ++$1="$ac_cv_path_$1" ++if test m4_if([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then ++ AC_MSG_RESULT([$][$1]) ++else ++ AC_MSG_RESULT([no]) ++fi ++AC_SUBST([$1])dnl ++]) ++ ++# Copyright (C) 2002-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -32,10 +10016,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) + # generated from the m4 files accompanying Automake X.Y. + # (This private macro should not be called outside this file.) + AC_DEFUN([AM_AUTOMAKE_VERSION], +-[am__api_version='1.15' ++[am__api_version='1.16' + dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to + dnl require some minimum version. Point them to the right macro. +-m4_if([$1], [1.15.1], [], ++m4_if([$1], [1.16.5], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl + ]) + +@@ -51,14 +10035,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) + # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. + # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. + AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +-[AM_AUTOMAKE_VERSION([1.15.1])dnl ++[AM_AUTOMAKE_VERSION([1.16.5])dnl + m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl + _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + + # AM_AUX_DIR_EXPAND -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -110,7 +10094,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` + + # AM_CONDITIONAL -*- Autoconf -*- + +-# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# Copyright (C) 1997-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -141,7 +10125,7 @@ AC_CONFIG_COMMANDS_PRE( + Usually this means the macro was only invoked conditionally.]]) + fi])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -332,13 +10316,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl + + # Generate code to set up dependency tracking. -*- Autoconf -*- + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, + # with or without modifications, as long as this notice is preserved. + +- + # _AM_OUTPUT_DEPENDENCY_COMMANDS + # ------------------------------ + AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +@@ -346,49 +10329,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. +- case $CONFIG_FILES in +- *\'*) eval set x "$CONFIG_FILES" ;; +- *) set x $CONFIG_FILES ;; +- esac ++ # TODO: see whether this extra hack can be removed once we start ++ # requiring Autoconf 2.70 or later. ++ AS_CASE([$CONFIG_FILES], ++ [*\'*], [eval set x "$CONFIG_FILES"], ++ [*], [set x $CONFIG_FILES]) + shift +- for mf ++ # Used to flag and report bootstrapping failures. ++ am_rc=0 ++ for am_mf + do + # Strip MF so we end up with the name of the file. +- mf=`echo "$mf" | sed -e 's/:.*$//'` +- # Check whether this is an Automake generated Makefile or not. +- # We used to match only the files named 'Makefile.in', but +- # some people rename them; so instead we look at the file content. +- # Grep'ing the first line is not enough: some people post-process +- # each Makefile.in and add a new line on top of each file to say so. +- # Grep'ing the whole file is not good either: AIX grep has a line ++ am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` ++ # Check whether this is an Automake generated Makefile which includes ++ # dependency-tracking related rules and includes. ++ # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. +- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then +- dirpart=`AS_DIRNAME("$mf")` +- else +- continue +- fi +- # Extract the definition of DEPDIR, am__include, and am__quote +- # from the Makefile without running 'make'. +- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` +- test -z "$DEPDIR" && continue +- am__include=`sed -n 's/^am__include = //p' < "$mf"` +- test -z "$am__include" && continue +- am__quote=`sed -n 's/^am__quote = //p' < "$mf"` +- # Find all dependency output files, they are included files with +- # $(DEPDIR) in their names. We invoke sed twice because it is the +- # simplest approach to changing $(DEPDIR) to its actual value in the +- # expansion. +- for file in `sed -n " +- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ +- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do +- # Make sure the directory exists. +- test -f "$dirpart/$file" && continue +- fdir=`AS_DIRNAME(["$file"])` +- AS_MKDIR_P([$dirpart/$fdir]) +- # echo "creating $dirpart/$file" +- echo '# dummy' > "$dirpart/$file" +- done ++ sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ ++ || continue ++ am_dirpart=`AS_DIRNAME(["$am_mf"])` ++ am_filepart=`AS_BASENAME(["$am_mf"])` ++ AM_RUN_LOG([cd "$am_dirpart" \ ++ && sed -e '/# am--include-marker/d' "$am_filepart" \ ++ | $MAKE -f - am--depfiles]) || am_rc=$? + done ++ if test $am_rc -ne 0; then ++ AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments ++ for automatic dependency tracking. If GNU make was not used, consider ++ re-running the configure script with MAKE="gmake" (or whatever is ++ necessary). You can also try re-running configure with the ++ '--disable-dependency-tracking' option to at least be able to build ++ the package (albeit without support for automatic dependency tracking).]) ++ fi ++ AS_UNSET([am_dirpart]) ++ AS_UNSET([am_filepart]) ++ AS_UNSET([am_mf]) ++ AS_UNSET([am_rc]) ++ rm -f conftest-deps.mk + } + ])# _AM_OUTPUT_DEPENDENCY_COMMANDS + +@@ -397,18 +10374,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], + # ----------------------------- + # This macro should only be invoked once -- use via AC_REQUIRE. + # +-# This code is only required when automatic dependency tracking +-# is enabled. FIXME. This creates each '.P' file that we will +-# need in order to bootstrap the dependency handling code. ++# This code is only required when automatic dependency tracking is enabled. ++# This creates each '.Po' and '.Plo' makefile fragment that we'll need in ++# order to bootstrap the dependency handling code. + AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], + [AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], +- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +-]) ++ [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + + # Do all the work for Automake. -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -436,6 +10412,10 @@ m4_defn([AC_PROG_CC]) + # release and drop the old call support. + AC_DEFUN([AM_INIT_AUTOMAKE], + [AC_PREREQ([2.65])dnl ++m4_ifdef([_$0_ALREADY_INIT], ++ [m4_fatal([$0 expanded multiple times ++]m4_defn([_$0_ALREADY_INIT]))], ++ [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl + dnl Autoconf wants to disallow AM_ names. We explicitly allow + dnl the ones we care about. + m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +@@ -472,7 +10452,7 @@ m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + [_AM_SET_OPTIONS([$1])dnl + dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. + m4_if( +- m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), ++ m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl +@@ -495,8 +10475,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl + AC_REQUIRE([AC_PROG_MKDIR_P])dnl + # For better backward compatibility. To be removed once Automake 1.9.x + # dies out for good. For more background, see: +-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> ++# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> ++# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> + AC_SUBST([mkdir_p], ['$(MKDIR_P)']) + # We need awk for the "check" target (and possibly the TAP driver). The + # system "awk" is bad on some platforms. +@@ -524,6 +10504,20 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl + ]) ++# Variables for tags utilities; see am/tags.am ++if test -z "$CTAGS"; then ++ CTAGS=ctags ++fi ++AC_SUBST([CTAGS]) ++if test -z "$ETAGS"; then ++ ETAGS=etags ++fi ++AC_SUBST([ETAGS]) ++if test -z "$CSCOPE"; then ++ CSCOPE=cscope ++fi ++AC_SUBST([CSCOPE]) ++ + AC_REQUIRE([AM_SILENT_RULES])dnl + dnl The testsuite driver may need to know about EXEEXT, so add the + dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +@@ -563,7 +10557,7 @@ END + Aborting the configuration process, to ensure you take notice of the issue. + + You can download and install GNU coreutils to get an 'rm' implementation +-that behaves properly: <http://www.gnu.org/software/coreutils/>. ++that behaves properly: <https://www.gnu.org/software/coreutils/>. + + If you want to complete the configuration process using your problematic + 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +@@ -605,7 +10599,7 @@ for _am_header in $config_headers :; do + done + echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -626,7 +10620,26 @@ if test x"${install_sh+set}" != xset; then + fi + AC_SUBST([install_sh])]) + +-# Copyright (C) 1998-2017 Free Software Foundation, Inc. ++# Copyright (C) 2003-2021 Free Software Foundation, Inc. ++# ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# Check whether the underlying file-system supports filenames ++# with a leading dot. For instance MS-DOS doesn't. ++AC_DEFUN([AM_SET_LEADING_DOT], ++[rm -rf .tst 2>/dev/null ++mkdir .tst 2>/dev/null ++if test -d .tst; then ++ am__leading_dot=. ++else ++ am__leading_dot=_ ++fi ++rmdir .tst 2>/dev/null ++AC_SUBST([am__leading_dot])]) ++ ++# Copyright (C) 1998-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -647,7 +10660,7 @@ fi]) + # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- + # From Jim Meyering + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -682,7 +10695,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + + # Check to see how 'make' treats includes. -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -690,49 +10703,42 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + + # AM_MAKE_INCLUDE() + # ----------------- +-# Check to see how make treats includes. ++# Check whether make has an 'include' directive that can support all ++# the idioms we need for our automatic dependency tracking code. + AC_DEFUN([AM_MAKE_INCLUDE], +-[am_make=${MAKE-make} +-cat > confinc << 'END' ++[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) ++cat > confinc.mk << 'END' + am__doit: +- @echo this is the am__doit target ++ @echo this is the am__doit target >confinc.out + .PHONY: am__doit + END +-# If we don't find an include directive, just comment out the code. +-AC_MSG_CHECKING([for style of include used by $am_make]) + am__include="#" + am__quote= +-_am_result=none +-# First try GNU make style include. +-echo "include confinc" > confmf +-# Ignore all kinds of additional output from 'make'. +-case `$am_make -s -f confmf 2> /dev/null` in #( +-*the\ am__doit\ target*) +- am__include=include +- am__quote= +- _am_result=GNU +- ;; +-esac +-# Now try BSD make style include. +-if test "$am__include" = "#"; then +- echo '.include "confinc"' > confmf +- case `$am_make -s -f confmf 2> /dev/null` in #( +- *the\ am__doit\ target*) +- am__include=.include +- am__quote="\"" +- _am_result=BSD +- ;; +- esac +-fi +-AC_SUBST([am__include]) +-AC_SUBST([am__quote]) +-AC_MSG_RESULT([$_am_result]) +-rm -f confinc confmf +-]) ++# BSD make does it like this. ++echo '.include "confinc.mk" # ignored' > confmf.BSD ++# Other make implementations (GNU, Solaris 10, AIX) do it like this. ++echo 'include confinc.mk # ignored' > confmf.GNU ++_am_result=no ++for s in GNU BSD; do ++ AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) ++ AS_CASE([$?:`cat confinc.out 2>/dev/null`], ++ ['0:this is the am__doit target'], ++ [AS_CASE([$s], ++ [BSD], [am__include='.include' am__quote='"'], ++ [am__include='include' am__quote=''])]) ++ if test "$am__include" != "#"; then ++ _am_result="yes ($s style)" ++ break ++ fi ++done ++rm -f confinc.* confmf.* ++AC_MSG_RESULT([${_am_result}]) ++AC_SUBST([am__include])]) ++AC_SUBST([am__quote])]) + + # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +-# Copyright (C) 1997-2017 Free Software Foundation, Inc. ++# Copyright (C) 1997-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -753,12 +10759,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN], + [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl + AC_REQUIRE_AUX_FILE([missing])dnl + if test x"${MISSING+set}" != xset; then +- case $am_aux_dir in +- *\ * | *\ *) +- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; +- *) +- MISSING="\${SHELL} $am_aux_dir/missing" ;; +- esac ++ MISSING="\${SHELL} '$am_aux_dir/missing'" + fi + # Use eval to expand $SHELL + if eval "$MISSING --is-lightweight"; then +@@ -771,7 +10772,7 @@ fi + + # Helper functions for option handling. -*- Autoconf -*- + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -800,7 +10801,7 @@ AC_DEFUN([_AM_SET_OPTIONS], + AC_DEFUN([_AM_IF_OPTION], + [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +-# Copyright (C) 1999-2017 Free Software Foundation, Inc. ++# Copyright (C) 1999-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -847,7 +10848,7 @@ AC_LANG_POP([C])]) + # For backward compatibility. + AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -866,7 +10867,7 @@ AC_DEFUN([AM_RUN_LOG], + + # Check to make sure that the build environment is sane. -*- Autoconf -*- + +-# Copyright (C) 1996-2017 Free Software Foundation, Inc. ++# Copyright (C) 1996-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -947,7 +10948,7 @@ AC_CONFIG_COMMANDS_PRE( + rm -f conftest.file + ]) + +-# Copyright (C) 2009-2017 Free Software Foundation, Inc. ++# Copyright (C) 2009-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1007,7 +11008,7 @@ AC_SUBST([AM_BACKSLASH])dnl + _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl + ]) + +-# Copyright (C) 2001-2017 Free Software Foundation, Inc. ++# Copyright (C) 2001-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1035,7 +11036,7 @@ fi + INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +-# Copyright (C) 2006-2017 Free Software Foundation, Inc. ++# Copyright (C) 2006-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1054,7 +11055,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + + # Check how to create a tarball. -*- Autoconf -*- + +-# Copyright (C) 2004-2017 Free Software Foundation, Inc. ++# Copyright (C) 2004-2021 Free Software Foundation, Inc. + # + # This file is free software; the Free Software Foundation + # gives unlimited permission to copy and/or distribute it, +@@ -1185,27 +11186,3 @@ AC_SUBST([am__tar]) + AC_SUBST([am__untar]) + ]) # _AM_PROG_TAR + +-m4_include([../bfd/acinclude.m4]) +-m4_include([../bfd/warning.m4]) +-m4_include([../config/acx.m4]) +-m4_include([../config/bfd64.m4]) +-m4_include([../config/depstand.m4]) +-m4_include([../config/enable.m4]) +-m4_include([../config/gettext-sister.m4]) +-m4_include([../config/jobserver.m4]) +-m4_include([../config/largefile.m4]) +-m4_include([../config/lcmessage.m4]) +-m4_include([../config/lead-dot.m4]) +-m4_include([../config/nls.m4]) +-m4_include([../config/override.m4]) +-m4_include([../config/pkg.m4]) +-m4_include([../config/plugins.m4]) +-m4_include([../config/po.m4]) +-m4_include([../config/progtest.m4]) +-m4_include([../config/zlib.m4]) +-m4_include([../config/zstd.m4]) +-m4_include([../libtool.m4]) +-m4_include([../ltoptions.m4]) +-m4_include([../ltsugar.m4]) +-m4_include([../ltversion.m4]) +-m4_include([../lt~obsolete.m4]) +diff --git a/ld/configure.tgt b/ld/configure.tgt +index de04a44b..baceb2cc 100644 +--- a/ld/configure.tgt ++++ b/ld/configure.tgt +@@ -81,6 +81,15 @@ fi + # Please try to keep this table more or less in alphabetic order - it + # makes it much easier to lookup a specific archictecture. + case "${targ}" in ++i[3-7]86-*-sb*) ++ targ_emul=elf_i386_sb ++ targ_extra_emuls=elf_i386 ++# targ64_extra_emuls="elf_x86_64_sb_x86_64" ++ ;; ++#x86_64-*-sb*) ++# targ_emul=elf_x86_64_sb ++# targ_extra_emuls="elf_i386_sb elf_x86_64 elf_i386" ++# ;; + aarch64_be-*-elf) targ_emul=aarch64elfb + targ_extra_emuls="aarch64elf aarch64elf32 aarch64elf32b armelfb armelf" + ;; +diff --git a/ld/emulparams/elf_i386_sb.sh b/ld/emulparams/elf_i386_sb.sh +new file mode 100644 +index 00000000..06482257 +--- /dev/null ++++ b/ld/emulparams/elf_i386_sb.sh +@@ -0,0 +1,2 @@ ++source_sh ${srcdir}/emulparams/elf_i386.sh ++TEXT_START_ADDR=0x08000000 +diff --git a/ld/emulparams/elf_x86_64_sb.sh b/ld/emulparams/elf_x86_64_sb.sh +new file mode 100644 +index 00000000..59e7df71 +--- /dev/null ++++ b/ld/emulparams/elf_x86_64_sb.sh +@@ -0,0 +1 @@ ++source_sh ${srcdir}/emulparams/elf_x86_64.sh +diff --git a/ld/emulparams/elf_x86_64_sb_x86_64.sh b/ld/emulparams/elf_x86_64_sb_x86_64.sh +new file mode 100644 +index 00000000..59e7df71 +--- /dev/null ++++ b/ld/emulparams/elf_x86_64_sb_x86_64.sh +@@ -0,0 +1 @@ ++source_sh ${srcdir}/emulparams/elf_x86_64.sh diff --git a/toolchain/build-binutils.sh b/toolchain/build-binutils.sh new file mode 100755 index 0000000..12bcde9 --- /dev/null +++ b/toolchain/build-binutils.sh @@ -0,0 +1,13 @@ +#!/bin/sh +./download-binutils.sh +tar -xf binutils*.tar.xz +cd ./binutils-*/ +patch -f -p1 -i ../binutils-2.40.diff +cd .. +mkdir bin +#PREFIX="/home/anton/prj/osdev/sysroot" +PREFIX="$(pwd)/bin" +mkdir build-binutils +cd build-binutils +../binutils*/configure --target=i686-sb --prefix="$PREFIX" --with-sysroot="/home/anton/prj/osdev/sysroot" --disable-werror +make -j8 && make install diff --git a/toolchain/build-gcc.sh b/toolchain/build-gcc.sh new file mode 100755 index 0000000..c9af8a1 --- /dev/null +++ b/toolchain/build-gcc.sh @@ -0,0 +1,13 @@ +#!/bin/sh +./download-gcc.sh +tar -xf gcc-*.tar.xz +cd ./gcc-*/ +patch -f -p1 -i ../gcc-13.1.0.diff +cd .. +mkdir bin +PREFIX=$(pwd)"/bin" +#PREFIX="/home/anton/prj/osdev/sysroot" +mkdir build-gcc +cd build-gcc +../gcc-*/configure --target=i686-sb --prefix="$PREFIX" --with-gmp --with-mpfr --with-sysroot="/home/anton/prj/osdev/sysroot" --enable-languages=c,c++ +make -j6 all-gcc all-target-libgcc && make install-gcc install-target-libgcc diff --git a/toolchain/download-binutils.sh b/toolchain/download-binutils.sh new file mode 100755 index 0000000..4a72cf9 --- /dev/null +++ b/toolchain/download-binutils.sh @@ -0,0 +1,2 @@ +#!/bin/sh +BIN="binutils-2.40.tar.xz" URL="https://ftp.gnu.org/gnu/binutils" ./download.sh diff --git a/toolchain/download-gcc.sh b/toolchain/download-gcc.sh new file mode 100755 index 0000000..a7e2c94 --- /dev/null +++ b/toolchain/download-gcc.sh @@ -0,0 +1,2 @@ +#!/bin/sh +BIN="gcc-13.1.0.tar.xz" URL="https://ftp.gnu.org/gnu/gcc/gcc-13.1.0" ./download.sh diff --git a/toolchain/download.sh b/toolchain/download.sh new file mode 100755 index 0000000..770e812 --- /dev/null +++ b/toolchain/download.sh @@ -0,0 +1,9 @@ +#!/bin/sh +[ -f "$BIN.sig" ] && gpg --verify $BIN.sig $BIN && exit 0 +[ -f "$BIN.sig" ] || wget "$URL/$BIN.sig" +[ -f "$BIN" ] && gpg --verify $BIN.sig $BIN && exit 0 +wget "$URL/$BIN" +gpg --verify $BIN.sig $BIN && exit 0 +rm $BIN +echo "Signature failed" +exit 1 diff --git a/toolchain/gcc-13.1.0.diff b/toolchain/gcc-13.1.0.diff new file mode 100644 index 0000000..eb15a77 --- /dev/null +++ b/toolchain/gcc-13.1.0.diff @@ -0,0 +1,142 @@ +diff --git a/config.sub b/config.sub +index 38f3d037a..44169ef44 100755 +--- a/config.sub ++++ b/config.sub +@@ -1749,7 +1749,7 @@ case $os in + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ +- | fiwix* ) ++ | fiwix* | sb*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) +diff --git a/fixincludes/mkfixinc.sh b/fixincludes/mkfixinc.sh +index df90720b7..fdd219967 100755 +--- a/fixincludes/mkfixinc.sh ++++ b/fixincludes/mkfixinc.sh +@@ -11,6 +11,8 @@ target=fixinc.sh + + # Check for special fix rules for particular targets + case $machine in ++ *-sb* | \ ++ *-*-sb* | \ + i?86-*-cygwin* | \ + i?86-*-mingw32* | \ + x86_64-*-mingw32* | \ +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 6fd159448..c4c05ce9e 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -690,6 +690,12 @@ x86_cpus="generic intel" + + # Common parts for widely ported systems. + case ${target} in ++*-*-sb*) ++ gas=yes ++ gnu_ld=yes ++ default_use_cxa_atexit=yes ++ use_gcc_stdint=provide ++ ;; + *-*-darwin*) + tmake_file="t-darwin " + tm_file="${tm_file} darwin.h" +@@ -1126,6 +1132,9 @@ case ${target} in + esac + + case ${target} in ++#i[34567]86-*-sb*) # UNSURE ++# tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h sb.h" ++# ;; + aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) + tm_file="${tm_file} elfos.h newlib-stdint.h" + tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-elf-raw.h" +@@ -2327,6 +2336,10 @@ m68k-*-elf* | fido-*-elf*) + ;; + esac + ;; ++#AAAAAAAAAAAAAAAAAAA ++i[34567]86-*-sb*) # UNSURE ++ tm_file="${tm_file} i386/unix.h i386/att.h elfos.h glibc-stdint.h i386/i386elf.h sb.h" ++ ;; + m68k*-*-netbsdelf*) + default_m68k_cpu=68020 + default_cf_cpu=5475 +diff --git a/gcc/config/sb.h b/gcc/config/sb.h +new file mode 100644 +index 000000000..b721cb53f +--- /dev/null ++++ b/gcc/config/sb.h +@@ -0,0 +1,28 @@ ++/* Useful if you wish to make target-specific GCC changes. */ ++#undef TARGET_SB ++#define TARGET_SB 1 ++ ++/* Default arguments you want when running your ++ i686-myos-gcc/x86_64-myos-gcc toolchain */ ++#undef LIB_SPEC ++#define LIB_SPEC "-lc" /* link against C standard library */ ++ ++/* Files that are linked before user code. ++ The %s tells GCC to look for these files in the library directory. */ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s" ++ ++/* Files that are linked after user code. */ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC "crtend.o%s crtn.o%s" ++ ++/* Additional predefined macros. */ ++#undef TARGET_OS_CPP_BUILTINS ++#define TARGET_OS_CPP_BUILTINS() \ ++ do { \ ++ builtin_define("__sb__"); \ ++ builtin_define("__unix__"); \ ++ builtin_assert("system=sb"); \ ++ builtin_assert("system=unix"); \ ++ builtin_assert("system=posix"); \ ++ } while (0); +diff --git a/libgcc/config.host b/libgcc/config.host +index b9975de90..da9323956 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -220,6 +220,10 @@ esac + + # Common parts for widely ported systems. + case ${host} in ++#i[34567]86-*-sb*) ++# extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" ++# tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" ++# ;; + *-*-darwin*) + asm_hidden_op=.private_extern + tmake_file="$tmake_file t-darwin ${cpu_type}/t-darwin t-libgcc-pic" +@@ -1503,6 +1507,10 @@ am33_2.0-*-linux*) + m32c-*-elf*) + tmake_file="$tmake_file m32c/t-m32c" + ;; ++i[34567]86-*-sb*) ++ extra_parts="$extra_parts crti.o crtbegin.o crtend.o crtn.o" ++ tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic" ++ ;; + nvptx-*) + tmake_file="$tmake_file nvptx/t-nvptx" + extra_parts="crt0.o" +diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4 +index b3269cb88..8c0bc1e6f 100644 +--- a/libstdc++-v3/crossconfig.m4 ++++ b/libstdc++-v3/crossconfig.m4 +@@ -8,7 +8,12 @@ case "${host}" in + arm*-*-symbianelf*) + # This is a freestanding configuration; there is nothing to do here. + ;; +- ++ *-sb*) ++ GLIBCXX_CHECK_COMPILER_FEATURES ++ GLIBCXX_CHECK_LINKER_FEATURES ++ GLIBCXX_CHECK_MATH_SUPPORT ++ GLIBCXX_CHECK_STDLIB_SUPPORT ++ ;; + avr*-*-*) + AC_DEFINE(HAVE_ACOSF) + AC_DEFINE(HAVE_ASINF) diff --git a/toolchain/get-keys.sh b/toolchain/get-keys.sh new file mode 100755 index 0000000..0210b8f --- /dev/null +++ b/toolchain/get-keys.sh @@ -0,0 +1,3 @@ +#!/bin/sh +gpg --recv-key 3A24BC1E8FB409FA9F14371813FCEF89DD9E3C4F +gpg --recv-key D3A93CAD751C2AF4F8C7AD516C35B99309B5FA62 diff --git a/userland/ante/Makefile b/userland/ante/Makefile new file mode 100644 index 0000000..412b302 --- /dev/null +++ b/userland/ante/Makefile @@ -0,0 +1,15 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -O2 -Wall -Wextra -pedantic -static +LIB=-L../libgui -lgui -lgcc +INC=-I../libgui/ +BINS=ante +all: $(BINS) + +ante.o: ante.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +ante: ante.o + $(CC) $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/ante/ante.c b/userland/ante/ante.c new file mode 100644 index 0000000..753e7f2 --- /dev/null +++ b/userland/ante/ante.c @@ -0,0 +1,296 @@ +#include <assert.h> +#include <fcntl.h> +#include <libgui.h> +#include <poll.h> +#include <pty.h> +#include <socket.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define BACKGROUND_COLOR 0x000000 + +int file_fd; +char *file_buffer; +uint64_t file_buffer_size; +uint64_t file_size = 0; +uint64_t file_real_position = 0; +GUI_Window *global_w; + +typedef enum { + NORMAL, + INSERT, + COMMAND, +} editor_mode_t; + +editor_mode_t current_mode = NORMAL; +uint32_t cursor_pos_x = 0; +uint64_t cursor_pos_y = 0; +void draw_file(void); +void write_file(void); + +int clamp(int *x, int *y) { + int clamped = 0; + if (*x < 0) { + *x = 0; + clamped = 1; + } + if (*y < 0) { + *y = 0; + clamped = 1; + } + if (*x + 8 > global_w->sx) { + *x = (global_w->sx - 8) / 8; + clamped = 1; + } + if (*y + 8 > global_w->sy) { + *y = (global_w->sy - 8) / 8; + clamped = 1; + } + return clamped; +} + +void insert_char(int pos, char c) { + if (0 == file_size) { + file_size++; + file_buffer[0] = c; + return; + } + + // Shift the buffer at 'pos' to the right by one. + memmove(file_buffer + pos + 1, file_buffer + pos, file_size - pos); + + file_buffer[pos] = c; + file_size++; +} + +void delete_char(int pos, int *deleted_newline) { + if (0 == pos) { + return; + } + // Delete the characther at 'pos'. This makes sense if 'pos' is + // at the end of the file and as a result the shift operation done + // later in the function is not overwritting the characther. + if ('\n' == file_buffer[pos - 1]) + *deleted_newline = 1; + file_buffer[pos - 1] = 0; + + // Shift the buffer at 'pos' to the left by one + memmove(file_buffer + pos - 1, file_buffer + pos, file_size - pos); + file_size--; +} + +uint64_t cursor_to_real(int x, int y, int *is_valid) { + *is_valid = 0; + if (clamp(&x, &y)) + return file_real_position; + if (0 == file_size) { + if (0 == x && 0 == y) { + *is_valid = 1; + return 0; + } + return 0; + } + uint64_t p = 0; + int cx = 0; + int cy = 0; + for (; p < file_size; p++) { + if (cx == x && cy == y) { + *is_valid = 1; + break; + } + if ('\n' == file_buffer[p]) { + cx = 0; + cy++; + continue; + } + cx++; + } + if (*is_valid) + return p; + else + return file_real_position; +} + +void key_event(char c) { + int x = 0; + int y = 0; + if (COMMAND == current_mode) { + if ('w' == c) { + printf("wrote to file\n"); + write_file(); + current_mode = NORMAL; + return; + } + if ('q' == c) { + close(file_fd); + close(global_w->ws_socket); + current_mode = NORMAL; + exit(0); + return; + } + return; + } else if (NORMAL == current_mode) { + switch (c) { + case 'j': + y++; + break; + case 'k': + y--; + break; + case 'l': + x++; + break; + case 'h': + x--; + break; + case 'c': + printf("entering command mode\n"); + current_mode = COMMAND; + return; + break; + case 'i': + current_mode = INSERT; + return; + break; + default: + return; + } + } else { + if ('\x1B' == c) { + current_mode = NORMAL; + return; + } + if ('\b' == c) { + int deleted_newline = 0; + delete_char(file_real_position, &deleted_newline); + if (deleted_newline) { + y--; + } else { + x--; + } + GUI_ClearScreen(global_w, BACKGROUND_COLOR); + } else { + insert_char(file_real_position, c); + printf("inserting char: %c\n", c); + if ('\n' == c) { + cursor_pos_x = 0; + y++; + } else { + x++; + } + GUI_ClearScreen(global_w, BACKGROUND_COLOR); + } + } + + int is_valid_position = 0; + file_real_position = + cursor_to_real(cursor_pos_x + x, cursor_pos_y + y, &is_valid_position); + if (!is_valid_position) { + return; + } + GUI_OverwriteFont(global_w, cursor_pos_x * 8, cursor_pos_y * 8, + BACKGROUND_COLOR); + draw_file(); + cursor_pos_x += x; + cursor_pos_y += y; + GUI_OverwriteFont(global_w, cursor_pos_x * 8, cursor_pos_y * 8, 0xFFFFFF); + + GUI_UpdateWindow(global_w); +} + +void draw_file(void) { + assert(file_buffer); + uint32_t screen_pos_x = 0; + uint64_t screen_pos_y = 0; + for (uint64_t i = 0; i < file_size; i++) { + char c = file_buffer[i]; + if ('\n' == c) { + screen_pos_x = 0; + screen_pos_y += 8; + continue; + } + GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); + screen_pos_x += 8; + } +} + +void write_file(void) { + assert(file_buffer); + pwrite(file_fd, file_buffer, file_size, 0); +} + +int open_file(const char *file) { + file_fd = open(file, O_RDWR, O_CREAT); + printf("file_fd: %d\n", file_fd); + if (0 > file_fd) { + perror("open"); + return 0; + } + + file_buffer_size = 0x1000; + file_buffer = malloc(file_buffer_size); + uint64_t index = 0; + assert(file_buffer); + for (;;) { + char buffer[4096]; + int rc = read(file_fd, buffer, 4096); + if (-1 == rc) { + perror("read"); + assert(0); + } + + if (0 == rc) + break; + + file_size += rc; + if (file_size > file_buffer_size) { + file_buffer_size = file_size; + file_buffer = realloc(file_buffer, file_buffer_size); + assert(file_buffer); + } + + for (int i = 0; i < rc; i++, index++) { + file_buffer[index] = buffer[i]; + } + } + return 1; +} + +void run() { + struct pollfd fds[1]; + fds[0].fd = global_w->ws_socket; + fds[0].events = POLLIN; + fds[0].revents = 0; + for (;; fds[0].revents = 0) { + poll(fds, 1, 0); + if (fds[0].revents & POLLIN) { + WS_EVENT e; + int rc; + if (0 >= (rc = read(global_w->ws_socket, &e, sizeof(e)))) + continue; + if (0 == e.c) + continue; + key_event(e.c); + } + } +} + +int main(int argc, char **argv) { + if (argc < 2) { + printf("File has to be specified.\n"); + return 1; + } + global_w = GUI_CreateWindow(10, 10, 150 * 4, 150 * 4); + assert(global_w); + GUI_ClearScreen(global_w, BACKGROUND_COLOR); + GUI_UpdateWindow(global_w); + + assert(open_file(argv[1])); + draw_file(); + run(); + return 0; +} diff --git a/userland/cat/Makefile b/userland/cat/Makefile new file mode 100644 index 0000000..b45fae9 --- /dev/null +++ b/userland/cat/Makefile @@ -0,0 +1,10 @@ +CC="/home/anton/opt/cross/bin/i686-elf-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough +BINS=cat +all: $(BINS) + +cat.o: cat.c + $(CC) $(CFLAGS) -L../libc/ -lc -c cat.c -I../libc/ + +cat: cat.o + $(CC) -shared -o cat -ffreestanding -nostdlib $(CFLAGS) cat.o -L../libc/ -lc -lgcc #-L../libc/c.a diff --git a/userland/cat/cat b/userland/cat/cat Binary files differnew file mode 100755 index 0000000..2ba0c4d --- /dev/null +++ b/userland/cat/cat diff --git a/userland/cat/cat.c b/userland/cat/cat.c new file mode 100644 index 0000000..b143581 --- /dev/null +++ b/userland/cat/cat.c @@ -0,0 +1,24 @@ +#include <fcntl.h> +#include <stdio.h> +#include <dirent.h> + +int main(int argc, char **argv) { + DIR *d = opendir("/"); + struct dirent *de = readdir(d); + printf("x : %x\n", de->d_name[0]); + for (;;) + ; + /* + int fd = 0; + if (argc < 2) + goto read_stdin; + for (int i = 1; i < argc; i++) { + if ((fd = open(argv[i], O_RDONLY, 0)) == -1) { + return 1; + } + read_stdin: + for (char c[4096], int rc; (rc = read(fd, c, 4096) > 0);) + write(1, c, rc); + }*/ + return 0; +} diff --git a/userland/init/Makefile b/userland/init/Makefile new file mode 100644 index 0000000..932fcd3 --- /dev/null +++ b/userland/init/Makefile @@ -0,0 +1,10 @@ +CC="/home/anton/opt/cross/bin/i686-elf-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough +BINS=init +all: $(BINS) + +init.o: init.c + $(CC) $(CFLAGS) -I../libc/ -L../libc/ -lc -c init.c + +init: init.o + $(CC) -shared -o init -ffreestanding -nostdlib $(CFLAGS) init.o -L../libc/ -lc -lgcc #-L../libc/c.a diff --git a/userland/init/crt0_old.c b/userland/init/crt0_old.c new file mode 100644 index 0000000..7d1e977 --- /dev/null +++ b/userland/init/crt0_old.c @@ -0,0 +1,12 @@ +#include <stdint.h> +int main(int argc, char **argv); +//int main(); + +void _start(int a, int b, int argc, char** argv) +{ + (void)a; + kprintf("argc : %x\n", &argc); + kprintf("argv : %x\n", &argv); + for(;;); +// main(argc, t); +} diff --git a/userland/init/init b/userland/init/init Binary files differnew file mode 100755 index 0000000..3ae9020 --- /dev/null +++ b/userland/init/init diff --git a/userland/init/init.c b/userland/init/init.c new file mode 100644 index 0000000..78c4420 --- /dev/null +++ b/userland/init/init.c @@ -0,0 +1,15 @@ +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> + +int main(void) { + if (fork()) + for (;;) + wait(NULL); + + char *a[] = {NULL}; + execv("/term", a); + return 1; +} diff --git a/userland/json/Makefile b/userland/json/Makefile new file mode 100644 index 0000000..9fcb567 --- /dev/null +++ b/userland/json/Makefile @@ -0,0 +1,18 @@ +#CC="/home/anton/opt/cross/bin/i686-elf-gcc" +#AR="/home/anton/opt/cross/bin/i686-elf-ar" +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +AR="/home/anton/prj/osdev/sysroot/bin/i686-sb-ar" +CFLAGS = -O0 -Wall -Wextra -pedantic -Wimplicit-fallthrough -static -Wno-undef +BINS=libjson.a +all: $(BINS) +LIBS=-L./hashmap -lhashmap +OBJ=json.o + +json.o: json.c + $(CC) $(CFLAGS) $(LIBS) -c json.c + +libjson.a: $(OBJ) + $(AR) rcs libjson.a $^ + +clean: + rm libjson.a json.o diff --git a/userland/json/hashmap b/userland/json/hashmap new file mode 160000 +Subproject 07dfe3b606e0d82b2e181b27344b5e4ce8849f3 diff --git a/userland/json/json.c b/userland/json/json.c new file mode 100644 index 0000000..6449193 --- /dev/null +++ b/userland/json/json.c @@ -0,0 +1,360 @@ +// +// Copyright (C) 2022 by Anton Kling <anton@kling.gg> +// +// SPDX-License-Identifier: BSD-2-Clause +// +#include "hashmap/hashmap.h" +#include <assert.h> +#include <math.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +typedef enum JSON_TYPE { + NONE, + STRING, + NUMBER, + OBJECT, + ARRAY, // FIXME + BOOL, + JSON_NULL, +} JSON_TYPE; + +typedef struct JSON_ENTRY { + char *name; + JSON_TYPE type; + void *value; +} JSON_ENTRY; + +typedef struct JSON_OBJECT { + size_t size; + JSON_ENTRY *entries; + HashMap *hash_indexes; +} JSON_OBJECT; + +typedef struct JSON_CTX { + JSON_ENTRY global_object; +} JSON_CTX; + +void JSON_Init(JSON_CTX *ctx) { + ctx->global_object.name = NULL; + ctx->global_object.type = OBJECT; + ctx->global_object.value = malloc(sizeof(JSON_OBJECT)); + JSON_OBJECT *obj = ctx->global_object.value; + obj->size = 0; + obj->entries = NULL; +} + +const char *skip_whitespace(const char *str) { + for (; *str; str++) + switch (*str) { + case ' ': + case '\t': + case '\n': + case '\r': + break; + default: + goto _exit; + } +_exit: + return str; +} + +char to_lower(char c) { + if (c <= 'Z') + return c | 32; + return c; +} + +int low_strequ(const char *s1, const char *s2, size_t l) { + for (; 0 < l; l--, s2++, s1++) { + if (to_lower(*s2) != to_lower(*s1)) + return 0; + } + return 1; +} + +const char *find_name(const char *json, char *name_buffer, size_t buffer_len, + size_t *name_length, int *rc) { + *rc = 0; + json = skip_whitespace(json); + if ('"' != *json) + return json; + + // This *can* be the name + json++; + const char *tmp = json; + for (; *tmp && '"' != *tmp; tmp++) + ; + if (!(*tmp && ':' == *(tmp + 1))) { + // Invalid name + // FIXME: Do something better than this. + assert(0); + } + // The name was found. + *rc = 1; + size_t str_len; + if (tmp == json) + str_len = 0; + else + str_len = (tmp - json - 1); + if (str_len + 1 > buffer_len) { + // JSON string is too long for the buffer + // FIXME: Do something better than this. + assert(0); + } + memcpy(name_buffer, json, str_len + 1); + name_buffer[str_len + 1] = '\0'; + *name_length = str_len; + return tmp + 2; +} + +const char *find_entry(const char *json, char *name_buffer, size_t buffer_len, + size_t *name_length, JSON_TYPE *entry_type, int *rc) { + *rc = 0; + json = skip_whitespace(json); + json = find_name(json, name_buffer, 4096, name_length, rc); + json = skip_whitespace(json); + switch (*json) { + case '{': + *entry_type = OBJECT; + break; + case '"': + *entry_type = STRING; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *entry_type = NUMBER; + break; + case '[': + *entry_type = ARRAY; + break; + case 'T': + case 'F': + case 't': + case 'f': + *entry_type = BOOL; + break; + case 'N': + case 'n': + *entry_type = JSON_NULL; + break; + case '}': + *rc = 2; + break; + default: + *entry_type = NONE; + break; + } + return json; +} + +const char *extract_int(const char *json, uint32_t **value, int *rc) { + *value = malloc(sizeof(uint32_t)); + *rc = 0; + json = skip_whitespace(json); + // FIXME: Do some checking to determine that this is a int. + **value = 0; + for (; *json && ',' != *json && '}' != *json;) { + **value *= 10; + **value += (uint32_t)(*json - '0'); + json++; + json = skip_whitespace(json); + } + if ('\0' != *json) + *rc = 1; + return json; +} + +const char *extract_string(const char *json, char **value, int *rc) { + *value = malloc(4096); + *rc = 0; + int escape = 0; + json++; + char *tmp = *value; + for (; *json; json++) { + if ('"' == *json && !escape) + break; + escape = 0; + + if ('\\' == *json && !escape) { + escape = 1; + continue; + } + *tmp = *json; + tmp++; + } + *tmp = '\0'; + if ('\0' != *json) + *rc = 1; + return json; +} + +const char *extract_bool(const char *json, uint8_t **value, int *rc) { + *value = malloc(sizeof(uint8_t)); + *rc = 0; + if (low_strequ(json, "true", 3)) { + **value = 1; + json += 4; + *rc = 1; + return json; + } else if (low_strequ(json, "false", 4)) { + **value = 0; + json += 5; + *rc = 1; + return json; + } + return json; +} + +const char *extract_null(const char *json, uint8_t **value, int *rc) { + *value = malloc(sizeof(uint8_t)); + *rc = 0; + + if (low_strequ(json, "null", 3)) { + **value = 0; + json += 4; + *rc = 1; + return json; + } + return json; +} + +void hashmap_free_value(char *key, void *value) { + (void)key; + free(value); +} + +JSON_ENTRY *JSON_at(JSON_ENTRY *entry, size_t i); + +void JSON_Parse(JSON_CTX *ctx, const char *json) { + int rc; + char name_buffer[4096]; + size_t name_length; + JSON_TYPE entry_type; + JSON_OBJECT *object_stack[64]; + memset(object_stack, 0, sizeof(JSON_OBJECT *[64])); + size_t parent_num = 0; + object_stack[parent_num] = ctx->global_object.value; + object_stack[parent_num]->size = 0; + + for (;; json++) { + json = find_entry(json, name_buffer, 4096, &name_length, &entry_type, &rc); + if ('\0' == *json) + return; + + if (2 == rc) { + if (0 == parent_num) + return; + parent_num--; + json++; + json = skip_whitespace(json); + if (',' == *json) + json++; + continue; + } + + if (NULL == object_stack[parent_num]->entries) { + object_stack[parent_num]->entries = malloc(sizeof(JSON_ENTRY[30])); + object_stack[parent_num]->size = 0; + object_stack[parent_num]->hash_indexes = hashmap_create(30); + } + + size_t entry_num = object_stack[parent_num]->size; + object_stack[parent_num]->size++; + + if (NULL == object_stack[parent_num]->entries) { + void *rc = object_stack[parent_num]->entries = + malloc(sizeof(JSON_ENTRY[30])); + object_stack[parent_num]->entries = rc; + object_stack[parent_num]->size = 0; + object_stack[parent_num]->hash_indexes = hashmap_create(30); + } + JSON_ENTRY *entry = &object_stack[parent_num]->entries[entry_num]; + if (1 == rc) { + name_length++; + entry->name = malloc(name_length + 2); + memcpy(entry->name, name_buffer, name_length); + entry->name[name_length] = '\0'; + size_t *b = malloc(sizeof(size_t)); + *b = entry_num; + hashmap_add_entry(object_stack[parent_num]->hash_indexes, entry->name, b, + hashmap_free_value, 1); + } else { + entry->name = NULL; + } + entry->type = entry_type; + if (OBJECT == entry_type) { + entry->value = malloc(sizeof(JSON_OBJECT)); + parent_num++; + object_stack[parent_num] = entry->value; + object_stack[parent_num]->entries = NULL; + continue; + } else if (NUMBER == entry_type) { + json = extract_int(json, (uint32_t **)&entry->value, &rc); + } else if (STRING == entry_type) { + json = extract_string(json, (char **)&entry->value, &rc); + } else if (BOOL == entry_type) { + json = extract_bool(json, (uint8_t **)&entry->value, &rc); + } else if (JSON_NULL == entry_type) { + json = extract_null(json, (uint8_t **)&entry->value, &rc); + } + json++; + } +} + +JSON_ENTRY *JSON_at(JSON_ENTRY *entry, size_t i) { + if (OBJECT != entry->type) + return NULL; + return &((JSON_OBJECT *)(entry->value))->entries[i]; +} + +JSON_ENTRY *JSON_search_name(JSON_ENTRY *entry, char *name) { + if (OBJECT != entry->type) + return NULL; + size_t *i = + hashmap_get_entry(((JSON_OBJECT *)(entry->value))->hash_indexes, name); + if (!i) + return NULL; + return JSON_at(entry, *i); +} + +void write_entry_content(int fd, size_t indent, JSON_ENTRY *entry) { +#define PLACE_TABS \ + { \ + for (size_t i = 0; i < indent; i++) \ + dprintf(fd, "\t"); \ + } + PLACE_TABS + if (entry->name) + dprintf(fd, "\"%s\": ", entry->name); + if (OBJECT == entry->type) { + JSON_OBJECT *object = entry->value; + dprintf(fd, "{\n"); + for (size_t i = 0; i < object->size; i++) + write_entry_content(fd, indent + 1, &object->entries[i]); + PLACE_TABS + dprintf(fd, "},\n"); + } else if (NUMBER == entry->type) + dprintf(fd, "%d,\n", *(uint32_t *)entry->value); + else if (STRING == entry->type) + dprintf(fd, "\"%s\",\n", (char *)entry->value); + else if (BOOL == entry->type) + dprintf(fd, "%s,\n", ((*(uint8_t *)entry->value) ? "true" : "false")); + else if (JSON_NULL == entry->type) + dprintf(fd, "null,\n"); +} + +void JSON_extract_fd(JSON_CTX *ctx, int fd) { + JSON_ENTRY *entry = &ctx->global_object; + write_entry_content(fd, 0, &((JSON_OBJECT *)entry->value)->entries[0]); +} diff --git a/userland/json/json.h b/userland/json/json.h new file mode 100644 index 0000000..642a878 --- /dev/null +++ b/userland/json/json.h @@ -0,0 +1,39 @@ +#ifndef JSON_H +#define JSON_H +#include "hashmap/hashmap.h" +#include <stddef.h> +#include <stdint.h> + +typedef enum JSON_TYPE { + NONE, + STRING, + NUMBER, + OBJECT, + ARRAY, // FIXME + BOOL, + JSON_NULL, +} JSON_TYPE; + +typedef struct JSON_ENTRY { + char *name; + JSON_TYPE type; + void *value; +} JSON_ENTRY; + +typedef struct JSON_OBJECT { + uint64_t size; + JSON_ENTRY *entries; + HashMap *hash_indexes; +} JSON_OBJECT; + +typedef struct JSON_CTX { + JSON_ENTRY global_object; +} JSON_CTX; + +void JSON_Init(JSON_CTX *ctx); +void JSON_Parse(JSON_CTX *ctx, const char *json); +void JSON_extract_fd(JSON_CTX *ctx, int whitespace, int fd); +uint64_t JSON_extract_length(JSON_CTX *ctx, int whitespace); +JSON_ENTRY *JSON_at(JSON_ENTRY *entry, uint64_t i); +JSON_ENTRY *JSON_search_name(JSON_ENTRY *entry, char *name); +#endif diff --git a/userland/json/libjson.a b/userland/json/libjson.a Binary files differnew file mode 100644 index 0000000..ca66650 --- /dev/null +++ b/userland/json/libjson.a diff --git a/userland/libc/Makefile b/userland/libc/Makefile new file mode 100644 index 0000000..98d81d4 --- /dev/null +++ b/userland/libc/Makefile @@ -0,0 +1,26 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +AR="/home/anton/prj/osdev/sysroot/bin/i686-sb-ar" +AS="/home/anton/prj/osdev/sysroot/bin/i686-sb-as" +#CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -I./include/ -static -fsanitize=shift,signed-integer-overflow,bounds +CFLAGS = -ggdb -ffreestanding -O2 -Wall -pedantic -Wimplicit-fallthrough -I./include/ -static +#BINS=c.a libc.o crt0.o malloc.o pty.o mmap.o +OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/stdout.o stdio/stderr.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o +#OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/stdout.o stdio/stderr.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o +all: libc.a + +%.o: %.c + $(CC) $(CFLAGS) -O0 -I. -o $@ -c $< -lgcc + +%.o: %.s + $(AS) $< -o $@ + +libc.a: $(OBJ) + $(AR) rcs libc.a $(OBJ) + +install: + cp crt0.o /home/anton/prj/osdev/sysroot/lib/ + cp libc.a /home/anton/prj/osdev/sysroot/lib/ + cp -r include /home/anton/prj/osdev/sysroot/usr/ + +clean: + rm libc.a *.o */*.o */*/*.o diff --git a/userland/libc/arpa/inet.h b/userland/libc/arpa/inet.h new file mode 100644 index 0000000..7a033f2 --- /dev/null +++ b/userland/libc/arpa/inet.h @@ -0,0 +1,4 @@ +#include <stdint.h> + +uint32_t htonl(uint32_t hostlong); +uint16_t htons(uint16_t hostlong); diff --git a/userland/libc/arpa/inet/htonl.c b/userland/libc/arpa/inet/htonl.c new file mode 100644 index 0000000..4b66747 --- /dev/null +++ b/userland/libc/arpa/inet/htonl.c @@ -0,0 +1,11 @@ +#include <arpa/inet.h> +#include <endian.h> +#include <stdint.h> + +uint32_t htonl(uint32_t hostlong) { +#if BYTE_ORDER == LITTLE_ENDIAN + hostlong = (uint32_t)(htons(hostlong >> 16)) | + (uint32_t)(htons(hostlong & 0xFFFF) << 16); +#endif + return hostlong; +} diff --git a/userland/libc/arpa/inet/htons.c b/userland/libc/arpa/inet/htons.c new file mode 100644 index 0000000..798a64a --- /dev/null +++ b/userland/libc/arpa/inet/htons.c @@ -0,0 +1,10 @@ +#include <arpa/inet.h> +#include <endian.h> +#include <stdint.h> + +uint16_t htons(uint16_t hostlong) { +#if BYTE_ORDER == LITTLE_ENDIAN + hostlong = ((hostlong & 0xFF00) >> 8) | ((hostlong & 0x00FF) << 8); +#endif + return hostlong; +} diff --git a/userland/libc/assert.c b/userland/libc/assert.c new file mode 100644 index 0000000..4082f64 --- /dev/null +++ b/userland/libc/assert.c @@ -0,0 +1,9 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +void aFailed(char *f, int l) { + printf("Assert failed\n"); + printf("%s : %d\n", f, l); + exit(1); +} diff --git a/userland/libc/assert.h b/userland/libc/assert.h new file mode 100644 index 0000000..a009e5f --- /dev/null +++ b/userland/libc/assert.h @@ -0,0 +1,10 @@ +#ifndef ASSERT_H +#define ASSERT_H + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } +void aFailed(char *f, int l); +#endif diff --git a/userland/libc/crt0.s b/userland/libc/crt0.s new file mode 100644 index 0000000..05144d4 --- /dev/null +++ b/userland/libc/crt0.s @@ -0,0 +1,13 @@ +.global _start +.extern main +_start: + call main + mov %eax, %ebx + mov $8, %eax + int $0x80 +l: + nop + nop + nop + nop + jmp l diff --git a/userland/libc/ctype.h b/userland/libc/ctype.h new file mode 100644 index 0000000..5be4a89 --- /dev/null +++ b/userland/libc/ctype.h @@ -0,0 +1,12 @@ +#ifndef CTYPE_H +#define CTYPE_H + +int isspace(int c); +int isascii(int c); +int toupper(int c); +int tolower(int c); +int isdigit(int c); +int isalpha(int c); +int isxdigit(int c); +int ispunct(int c); +#endif diff --git a/userland/libc/ctype/isalnum.c b/userland/libc/ctype/isalnum.c new file mode 100644 index 0000000..870728d --- /dev/null +++ b/userland/libc/ctype/isalnum.c @@ -0,0 +1,6 @@ +#include <ctype.h> + +// This is probably the most useless libc function I have seen so far. +int isalnum(int c) { + return isalpha(c) || isdigit(c); +} diff --git a/userland/libc/ctype/isalpha.c b/userland/libc/ctype/isalpha.c new file mode 100644 index 0000000..130f493 --- /dev/null +++ b/userland/libc/ctype/isalpha.c @@ -0,0 +1,4 @@ +#include <ctype.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isalpha.html +int isalpha(int c) { return (('A' <= toupper(c)) && ('Z' >= toupper(c))); } diff --git a/userland/libc/ctype/isascii.c b/userland/libc/ctype/isascii.c new file mode 100644 index 0000000..660c8bb --- /dev/null +++ b/userland/libc/ctype/isascii.c @@ -0,0 +1,4 @@ +#include <ctype.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isascii.html +int isascii(int c) { return (c < 128); } diff --git a/userland/libc/ctype/isdigit.c b/userland/libc/ctype/isdigit.c new file mode 100644 index 0000000..790b9f1 --- /dev/null +++ b/userland/libc/ctype/isdigit.c @@ -0,0 +1,6 @@ +#include <ctype.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isdigit.html +int isdigit(int c) { + return ('0' <= c && c <= '9'); +} diff --git a/userland/libc/ctype/isprint.c b/userland/libc/ctype/isprint.c new file mode 100644 index 0000000..e6a3d0e --- /dev/null +++ b/userland/libc/ctype/isprint.c @@ -0,0 +1,3 @@ +#include <ctype.h> + +int isprint(int c) { return c > 0x20 && 0x7F != c; } diff --git a/userland/libc/ctype/ispunct.c b/userland/libc/ctype/ispunct.c new file mode 100644 index 0000000..18dc7d8 --- /dev/null +++ b/userland/libc/ctype/ispunct.c @@ -0,0 +1,6 @@ +#include <ctype.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/ispunct.html +int ispunct(int c) { + return (c == '.'); +} diff --git a/userland/libc/ctype/isxdigit.c b/userland/libc/ctype/isxdigit.c new file mode 100644 index 0000000..c843725 --- /dev/null +++ b/userland/libc/ctype/isxdigit.c @@ -0,0 +1,6 @@ +#include <ctype.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/isxdigit.html +int isxdigit(int c) { + return isdigit(c) || ('A' >= toupper(c) && 'Z' <= toupper(c)); +} diff --git a/userland/libc/ctype/tolower.c b/userland/libc/ctype/tolower.c new file mode 100644 index 0000000..f1bb163 --- /dev/null +++ b/userland/libc/ctype/tolower.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int tolower(int c) { + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + return c; +} diff --git a/userland/libc/ctype/toupper.c b/userland/libc/ctype/toupper.c new file mode 100644 index 0000000..0f33886 --- /dev/null +++ b/userland/libc/ctype/toupper.c @@ -0,0 +1,7 @@ +#include <ctype.h> + +int toupper(int c) { + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + return c; +} diff --git a/userland/libc/dirent.h b/userland/libc/dirent.h new file mode 100644 index 0000000..f190a7c --- /dev/null +++ b/userland/libc/dirent.h @@ -0,0 +1,28 @@ +#ifndef DIRENT_H +#define DIRENT_H +#include <fcntl.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> + +struct dirent { + ino_t d_ino; // File serial number. + char d_name[PATH_MAX]; // Filename string of entry. +}; + +typedef struct { + int fd; + struct dirent internal_direntry; + int dir_num; +} DIR; + +DIR *opendir(const char *dirname); +struct dirent *readdir(DIR *dir); +int closedir(DIR *dirp); +int alphasort(const struct dirent **d1, const struct dirent **d2); +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); +#endif diff --git a/userland/libc/dirent/alphasort.c b/userland/libc/dirent/alphasort.c new file mode 100644 index 0000000..43a4b5f --- /dev/null +++ b/userland/libc/dirent/alphasort.c @@ -0,0 +1,7 @@ +#include <dirent.h> + +int alphasort(const struct dirent **d1, const struct dirent **d2) { + // TODO: Actually sort it + *d2 = *d1; + return 0; +} diff --git a/userland/libc/dirent/closedir.c b/userland/libc/dirent/closedir.c new file mode 100644 index 0000000..e216d7c --- /dev/null +++ b/userland/libc/dirent/closedir.c @@ -0,0 +1,7 @@ +#include <dirent.h> + +int closedir(DIR *dir) { + close(dir->fd); + free(dir); + return 0; +} diff --git a/userland/libc/dirent/opendir.c b/userland/libc/dirent/opendir.c new file mode 100644 index 0000000..7bfa562 --- /dev/null +++ b/userland/libc/dirent/opendir.c @@ -0,0 +1,11 @@ +#include <dirent.h> + +DIR *opendir(const char *dirname) { + int fd = open(dirname, O_RDONLY, 0); + if (-1 == fd) + return NULL; + DIR *rc = malloc(sizeof(DIR)); + rc->fd = fd; + rc->dir_num = 0; + return rc; +} diff --git a/userland/libc/dirent/readdir.c b/userland/libc/dirent/readdir.c new file mode 100644 index 0000000..88aff48 --- /dev/null +++ b/userland/libc/dirent/readdir.c @@ -0,0 +1,14 @@ +#include <dirent.h> + +struct dirent *readdir(DIR *dir) { + size_t offset = dir->dir_num * sizeof(struct dirent); + int rc; + if (-1 == (rc = pread(dir->fd, &dir->internal_direntry, sizeof(struct dirent), + offset))) + return NULL; + if (rc < sizeof(struct dirent)) + return NULL; + + dir->dir_num++; + return &(dir->internal_direntry); +} diff --git a/userland/libc/dirent/scandir.c b/userland/libc/dirent/scandir.c new file mode 100644 index 0000000..1520140 --- /dev/null +++ b/userland/libc/dirent/scandir.c @@ -0,0 +1,43 @@ +#include <dirent.h> +#include <stdlib.h> +#include <string.h> + +int nop_sel(const struct dirent *unused) { + (void)unused; + return 1; +} + +int nop_compar(const struct dirent **d1, const struct dirent **d2) { + *d2 = *d1; + return 0; +} + +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)) { + if (!sel) + sel = nop_sel; + + if (!compar) + compar = nop_compar; + + DIR *d = opendir(dir); + struct dirent **list = NULL; + struct dirent *e; + int rc = 0; + for (; (e = readdir(d));) { + if (!sel(e)) + continue; + struct dirent *p = malloc(sizeof(struct dirent)); + memcpy(p, e, sizeof(struct dirent)); + list = realloc(list, (rc + 1) * sizeof(struct dirent *)); + list[rc] = p; + rc++; + } + // struct dirent **new_list; + // compar((const struct dirent **)list, (const struct dirent **)new_list); + // *namelist = new_list; + *namelist = list; + // closedir(d); + return rc; +} diff --git a/userland/libc/endian.h b/userland/libc/endian.h new file mode 100644 index 0000000..f265a67 --- /dev/null +++ b/userland/libc/endian.h @@ -0,0 +1,2 @@ +#define LITTLE_ENDIAN 0 +#define BYTE_ORDER LITTLE_ENDIAN diff --git a/userland/libc/errno.h b/userland/libc/errno.h new file mode 100644 index 0000000..ec9a25e --- /dev/null +++ b/userland/libc/errno.h @@ -0,0 +1,87 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. + +extern int errno; +#endif diff --git a/userland/libc/fcntl.h b/userland/libc/fcntl.h new file mode 100644 index 0000000..4c1eb9c --- /dev/null +++ b/userland/libc/fcntl.h @@ -0,0 +1,10 @@ +// FIXME: Is there some standard value for this? +#define O_NONBLOCK (1 << 0) +#define O_READ (1 << 1) +#define O_WRITE (1 << 2) +#define O_CREAT (1 << 3) +#define O_RDONLY O_READ +#define O_WRONLY O_WRITE +#define O_RDWR (O_WRITE | O_READ) + +int open(const char *file, int flags, int mode); diff --git a/userland/libc/include/arpa/inet.h b/userland/libc/include/arpa/inet.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/arpa/inet.h diff --git a/userland/libc/include/assert.h b/userland/libc/include/assert.h new file mode 100644 index 0000000..a009e5f --- /dev/null +++ b/userland/libc/include/assert.h @@ -0,0 +1,10 @@ +#ifndef ASSERT_H +#define ASSERT_H + +#define assert(expr) \ + { \ + if (!(expr)) \ + aFailed(__FILE__, __LINE__); \ + } +void aFailed(char *f, int l); +#endif diff --git a/userland/libc/include/byteswap.h b/userland/libc/include/byteswap.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/byteswap.h diff --git a/userland/libc/include/ctype.h b/userland/libc/include/ctype.h new file mode 100644 index 0000000..7c8c311 --- /dev/null +++ b/userland/libc/include/ctype.h @@ -0,0 +1,14 @@ +#ifndef CTYPE_H +#define CTYPE_H + +int isspace(int c); +int isascii(int c); +int toupper(int c); +int tolower(int c); +int isdigit(int c); +int isalpha(int c); +int isxdigit(int c); +int ispunct(int c); +int isalnum(int c); +int isprint(int c); +#endif diff --git a/userland/libc/include/dirent.h b/userland/libc/include/dirent.h new file mode 100644 index 0000000..f190a7c --- /dev/null +++ b/userland/libc/include/dirent.h @@ -0,0 +1,28 @@ +#ifndef DIRENT_H +#define DIRENT_H +#include <fcntl.h> +#include <limits.h> +#include <stddef.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> + +struct dirent { + ino_t d_ino; // File serial number. + char d_name[PATH_MAX]; // Filename string of entry. +}; + +typedef struct { + int fd; + struct dirent internal_direntry; + int dir_num; +} DIR; + +DIR *opendir(const char *dirname); +struct dirent *readdir(DIR *dir); +int closedir(DIR *dirp); +int alphasort(const struct dirent **d1, const struct dirent **d2); +int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, const struct dirent **)); +#endif diff --git a/userland/libc/include/endian.h b/userland/libc/include/endian.h new file mode 100644 index 0000000..f265a67 --- /dev/null +++ b/userland/libc/include/endian.h @@ -0,0 +1,2 @@ +#define LITTLE_ENDIAN 0 +#define BYTE_ORDER LITTLE_ENDIAN diff --git a/userland/libc/include/err.h b/userland/libc/include/err.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/err.h diff --git a/userland/libc/include/errno.h b/userland/libc/include/errno.h new file mode 100644 index 0000000..ec9a25e --- /dev/null +++ b/userland/libc/include/errno.h @@ -0,0 +1,87 @@ +#ifndef ERRNO_H +#define ERRNO_H +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +#define E2BIG 1 // Argument list too long. +#define EACCES 2 // Permission denied. +#define EADDRINUSE 3 // Address in use. +#define EADDRNOTAVAIL 4 // Address not available. +#define EAFNOSUPPORT 5 // Address family not supported. +#define EAGAIN 6 // Resource unavailable, try again. +#define EALREADY 7 // Connection already in progress. +#define EBADF 8 // Bad file descriptor. +#define EBADMSG 9 // Bad message. +#define EBUSY 10 // Device or resource busy. +#define ECANCELED 11 // Operation canceled. +#define ECHILD 12 // No child processes. +#define ECONNABORTED 13 // Connection aborted. +#define ECONNREFUSED 14 // Connection refused. +#define ECONNRESET 15 // Connection reset. +#define EDEADLK 16 // Resource deadlock would occur. +#define EDESTADDRREQ 17 // Destination address required. +#define EDOM 18 // Mathematics argument out of domain of function. +#define EDQUOT 19 // Reserved. +#define EEXIST 20 // File exists. +#define EFAULT 21 // Bad address. +#define EFBIG 22 // File too large. +#define EHOSTUNREACH 23 // Host is unreachable. +#define EIDRM 24 // Identifier removed. +#define EILSEQ 25 // Illegal byte sequence. +#define EINPROGRESS 26 // Operation in progress. +#define EINTR 27 // Interrupted function. +#define EINVAL 28 // Invalid argument. +#define EIO 29 // I/O error. +#define EISCONN 30 // Socket is connected. +#define EISDIR 31 // Is a directory. +#define ELOOP 32 // Too many levels of symbolic links. +#define EMFILE 33 // File descriptor value too large. +#define EMLINK 34 // Too many links. +#define EMSGSIZE 35 // Message too large. +#define EMULTIHOP 36 // Reserved. +#define ENAMETOOLONG 37 // Filename too long. +#define ENETDOWN 38 // Network is down. +#define ENETRESET 39 // Connection aborted by network. +#define ENETUNREACH 40 // Network unreachable. +#define ENFILE 41 // Too many files open in system. +#define ENOBUFS 42 // No buffer space available. +#define ENODATA 43 // No message is available on the STREAM head read queue. +#define ENODEV 44 // No such device. +#define ENOENT 45 // No such file or directory. +#define ENOEXEC 46 // Executable file format error. +#define ENOLCK 47 // No locks available. +#define ENOLINK 48 // Reserved. +#define ENOMEM 49 // Not enough space. +#define ENOMSG 50 // No message of the desired type. +#define ENOPROTOOPT 51 // Protocol not available. +#define ENOSPC 52 // No space left on device. +#define ENOSR 53 // No STREAM resources. +#define ENOSTR 54 // Not a STREAM. +#define ENOSYS 55 // Functionality not supported. +#define ENOTCONN 56 // The socket is not connected. +#define ENOTDIR 57 // Not a directory or a symbolic link to a directory. +#define ENOTEMPTY 58 // Directory not empty. +#define ENOTRECOVERABLE 59 // State not recoverable. +#define ENOTSOCK 60 // Not a socket. +#define ENOTSUP 61 // Not supported (may be the same value as. +#define ENOTTY 62 // Inappropriate I/O control operation. +#define ENXIO 63 // No such device or address. +#define EOPNOTSUPP ENOTSUP // Operation not supported on socket. +#define EOVERFLOW 65 // Value too large to be stored in data type. +#define EOWNERDEAD 66 // Previous owner died. +#define EPERM 67 // Operation not permitted. +#define EPIPE 68 // Broken pipe. +#define EPROTO 69 // Protocol error. +#define EPROTONOSUPPORT 70 // Protocol not supported. +#define EPROTOTYPE 71 // Protocol wrong type for socket. +#define ERANGE 72 // Result too large. +#define EROFS 73 // Read-only file system. +#define ESPIPE 74 // Invalid seek. +#define ESRCH 75 // No such process. +#define ESTALE 76 // Reserved. +#define ETIME 77 // Stream ioctl() timeout. +#define ETIMEDOUT 78 // Connection timed out. +#define ETXTBSY 79 // Text file busy. +#define EWOULDBLOCK EAGAIN // Operation would block. +#define EXDEV 81 // Cross-device link. + +extern int errno; +#endif diff --git a/userland/libc/include/fcntl.h b/userland/libc/include/fcntl.h new file mode 100644 index 0000000..7f0906d --- /dev/null +++ b/userland/libc/include/fcntl.h @@ -0,0 +1,12 @@ +// FIXME: Is there some standard value for this? +#define O_NONBLOCK (1 << 0) +#define O_READ (1 << 1) +#define O_WRITE (1 << 2) +#define O_CREAT (1 << 3) +#define O_TRUNC (1 << 4) + +#define O_RDONLY O_READ +#define O_WRONLY O_WRITE +#define O_RDWR (O_WRITE | O_READ) + +int open(const char *file, int flags, int mode); diff --git a/userland/libc/include/fnmatch.h b/userland/libc/include/fnmatch.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/fnmatch.h diff --git a/userland/libc/include/glob.h b/userland/libc/include/glob.h new file mode 100644 index 0000000..f9e9c57 --- /dev/null +++ b/userland/libc/include/glob.h @@ -0,0 +1,10 @@ +#ifndef GLOB_H +#define GLOB_H +#include <stddef.h> + +typedef struct { + size_t gl_pathc; // Count of paths matched by pattern. + char **gl_pathv; // Pointer to a list of matched pathnames + size_t gl_offs; // Slots to reserve at the beginning of gl_pathv. +} glob_t; +#endif diff --git a/userland/libc/include/grp.h b/userland/libc/include/grp.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/grp.h diff --git a/userland/libc/include/input.h b/userland/libc/include/input.h new file mode 100644 index 0000000..a6602f5 --- /dev/null +++ b/userland/libc/include/input.h @@ -0,0 +1,9 @@ +#ifndef INPUT_H +#define INPUT_H +#include <stdint.h> + +struct input_event { + uint16_t key; + uint8_t status; +}; +#endif diff --git a/userland/libc/include/inttypes.h b/userland/libc/include/inttypes.h new file mode 100644 index 0000000..adde7c8 --- /dev/null +++ b/userland/libc/include/inttypes.h @@ -0,0 +1,19 @@ +#include <stdint.h> + +// FIXME: These are not correct +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 "d" +#define PRIu8 "d" +#define PRIu16 "d" +#define PRIu32 "d" +#define PRIu64 "d" +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 "x" +#define PRIX8 "x" +#define PRIX16 "x" +#define PRIX32 "x" +#define PRIX64 "x" diff --git a/userland/libc/include/langinfo.h b/userland/libc/include/langinfo.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/langinfo.h diff --git a/userland/libc/include/libgen.h b/userland/libc/include/libgen.h new file mode 100644 index 0000000..16dc3ed --- /dev/null +++ b/userland/libc/include/libgen.h @@ -0,0 +1,6 @@ +#ifndef LIBGEN_H +#define LIBGEN_H + +char *basename(char *path); +char *dirname(char *path); +#endif diff --git a/userland/libc/include/limits.h b/userland/libc/include/limits.h new file mode 100644 index 0000000..6d0abe0 --- /dev/null +++ b/userland/libc/include/limits.h @@ -0,0 +1,4 @@ +#define PATH_MAX 256 +#define FILENAME_MAX PATH_MAX +#define ULONG_MAX 0xFFFFFFFFUL +#define LONG_MAX 2147483647 diff --git a/userland/libc/include/locale.h b/userland/libc/include/locale.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/locale.h diff --git a/userland/libc/include/math.h b/userland/libc/include/math.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/math.h diff --git a/userland/libc/include/net/if.h b/userland/libc/include/net/if.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/net/if.h diff --git a/userland/libc/include/netdb.h b/userland/libc/include/netdb.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/netdb.h diff --git a/userland/libc/include/netinet/in.h b/userland/libc/include/netinet/in.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/netinet/in.h diff --git a/userland/libc/include/netinet/tcp.h b/userland/libc/include/netinet/tcp.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/netinet/tcp.h diff --git a/userland/libc/include/paths.h b/userland/libc/include/paths.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/paths.h diff --git a/userland/libc/include/poll.h b/userland/libc/include/poll.h new file mode 100644 index 0000000..e3c6d8d --- /dev/null +++ b/userland/libc/include/poll.h @@ -0,0 +1,17 @@ +#ifndef POLL_H +#define POLL_H +#include <stddef.h> + +#define POLLIN (1 << 0) +#define POLLPRI (1 << 1) +#define POLLOUT (1 << 2) +#define POLLHUP (1 << 3) + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll(struct pollfd *fds, size_t nfds, int timeout); +#endif diff --git a/userland/libc/include/pty.h b/userland/libc/include/pty.h new file mode 100644 index 0000000..b8ce978 --- /dev/null +++ b/userland/libc/include/pty.h @@ -0,0 +1,6 @@ +#ifndef PTY_H +#define PTY_H +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp); +#endif diff --git a/userland/libc/include/pwd.h b/userland/libc/include/pwd.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/pwd.h diff --git a/userland/libc/include/regex.h b/userland/libc/include/regex.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/regex.h diff --git a/userland/libc/include/sched.h b/userland/libc/include/sched.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sched.h diff --git a/userland/libc/include/setjmp.h b/userland/libc/include/setjmp.h new file mode 100644 index 0000000..ea15cf3 --- /dev/null +++ b/userland/libc/include/setjmp.h @@ -0,0 +1,14 @@ +#ifndef SETJMP_H +#define SETJMP_H +typedef unsigned long __jmp_buf[6]; +typedef struct __jmp_buf_tag { + __jmp_buf __jb; + unsigned long __fl; + unsigned long __ss[128/sizeof(long)]; +} jmp_buf[1]; +typedef jmp_buf sigjmp_buf; + +void _longjmp(jmp_buf, int); +void longjmp(jmp_buf, int); +void siglongjmp(sigjmp_buf, int); +#endif diff --git a/userland/libc/include/signal.h b/userland/libc/include/signal.h new file mode 100644 index 0000000..2e6566d --- /dev/null +++ b/userland/libc/include/signal.h @@ -0,0 +1,9 @@ +#ifndef SIGNAL_H +#define SIGNAL_H +#define SIGHUP 0 +#define SIGINT 1 +#define SIGWINCH 2 +#define SIGQUIT 3 +#define SIG_IGN 4 +typedef int sig_atomic_t; +#endif // SIGNAL_H diff --git a/userland/libc/include/socket.h b/userland/libc/include/socket.h new file mode 100644 index 0000000..5e86b45 --- /dev/null +++ b/userland/libc/include/socket.h @@ -0,0 +1,41 @@ +#include <stddef.h> +#include <stdint.h> + +#define AF_UNIX 0 +#define AF_LOCAL AF_UNIX + +#define INADDR_ANY 0 + +typedef struct { + int domain; + int type; + int protocol; + + // UNIX socket + char *path; + int incoming_fd; +} SOCKET; + +typedef struct { + char *path; + SOCKET *s; +} OPEN_UNIX_SOCKET; + +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; +typedef unsigned int sa_family_t; +typedef uint32_t socklen_t; + +struct sockaddr { + sa_family_t sa_family; /* Address family */ + char *sa_data; /* Socket address */ +}; + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char *sun_path; /* Socket pathname */ +}; + +int socket(int domain, int type, int protocol); +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/userland/libc/include/stdio.h b/userland/libc/include/stdio.h new file mode 100644 index 0000000..014e2ac --- /dev/null +++ b/userland/libc/include/stdio.h @@ -0,0 +1,116 @@ +#ifndef STDIO_H +#define STDIO_H +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> + +// FIXME: Most of these should probably not be here. But I am too lazy +// to fix it right now. This is futures mees problem to deal wth. + +#define EOF (-1) + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define BUFSIZ 4096 + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/setvbuf.html +#define _IOFBF 1 // shall cause input/output to be fully buffered. +#define _IOLBF 2 // shall cause input/output to be line buffered. +#define _IONBF 3 // shall cause input/output to be unbuffered. + +typedef long fpos_t; + +typedef struct __IO_FILE FILE; +struct __IO_FILE { + size_t (*write)(FILE *, const unsigned char *, size_t); + size_t (*read)(FILE *, unsigned char *, size_t); + int (*seek)(FILE *, long, int); + long offset_in_file; + int buffered_char; + int has_buffered_char; + int fd; + uint8_t is_eof; + uint8_t has_error; + uint64_t file_size; + void *cookie; +}; + +size_t write_fd(FILE *f, const unsigned char *s, size_t l); +size_t read_fd(FILE *f, unsigned char *s, size_t l); +int seek_fd(FILE *stream, long offset, int whence); + +typedef struct { + int fd; +} FILE_FD_COOKIE; + +extern FILE __stdin_FILE; +extern FILE __stdout_FILE; +extern FILE __stderr_FILE; + +#define stdin (&__stdin_FILE) +#define stdout (&__stdout_FILE) +//#define stderr (&__stderr_FILE) +#define stderr (&__stdout_FILE) + +typedef int mode_t; + +void perror(const char *s); + +int putchar(int c); +int puts(const char *s); +int brk(void *addr); +void *sbrk(intptr_t increment); +int write(int fd, const char *buf, size_t count); +int pwrite(int fd, const char *buf, size_t count, size_t offset); +int printf(const char *format, ...); +int pread(int fd, void *buf, size_t count, size_t offset); +int read(int fd, void *buf, size_t count); +int fork(void); +int memcmp(const void *s1, const void *s2, size_t n); +int wait(int *stat_loc); +void exit(int status); +void *memcpy(void *dest, const void *src, uint32_t n); +int shm_open(const char *name, int oflag, mode_t mode); +int dprintf(int fd, const char *format, ...); +int vdprintf(int fd, const char *format, va_list ap); +int vprintf(const char *format, va_list ap); +int snprintf(char *str, size_t size, const char *format, ...); +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +int vfprintf(FILE *f, const char *fmt, va_list ap); +int fgetc(FILE *stream); +int getchar(void); +#define getc(_a) fgetc(_a) +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); +FILE *fopen(const char *pathname, const char *mode); +int fclose(FILE *stream); +int fseek(FILE *stream, long offset, int whence); +int fprintf(FILE *f, const char *fmt, ...); +int atoi(const char *str); +long strtol(const char *nptr, char **endptr, int base); +char *strchr(const char *s, int c); +char *strcat(char *s1, const char *s2); +char *fgets(char *s, int n, FILE *stream); +FILE *tmpfile(void); +int feof(FILE *stream); +int fscanf(FILE *stream, const char *format, ...); +int ungetc(int c, FILE *stream); +long ftell(FILE *stream); +int fputc(int c, FILE *stream); +int remove(const char *path); +int ferror(FILE *stream); +int fputs(const char *s, FILE *stream); +int fflush(FILE *stream); +int setvbuf(FILE *stream, char *restrict buf, int type, size_t size); +int fileno(FILE *stream); +int putc(int c, FILE *stream); +int vsprintf(char *str, const char *format, va_list ap); +int sprintf(char *str, const char *format, ...); +FILE *open_memstream(char **bufp, size_t *sizep); +int fsetpos(FILE *stream, const fpos_t *pos); +int fgetpos(FILE *restrict stream, fpos_t *restrict pos); +char *tmpnam(char *s); +int rename(const char *old, const char *new); +#endif diff --git a/userland/libc/include/stdlib.h b/userland/libc/include/stdlib.h new file mode 100644 index 0000000..c88f2f3 --- /dev/null +++ b/userland/libc/include/stdlib.h @@ -0,0 +1,32 @@ +#ifndef STDLIB_H +#define STDLIB_H +#include <limits.h> +#include <stddef.h> +#define RAND_MAX (UINT32_MAX) +#define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 + +typedef size_t size_t; // only for 32 bit + +void *malloc(size_t s); +void *calloc(size_t nelem, size_t elsize); +void *realloc(void *ptr, size_t size); +void free(void *p); +char *getenv(const char *name); +int rand(void); +void srand(unsigned int seed); +unsigned long strtoul(const char *restrict str, char **restrict endptr, + int base); +long strtol(const char *str, char **restrict endptr, int base); +void abort(void); +int abs(int i); +void qsort(void *base, size_t nel, size_t width, + int (*compar)(const void *, const void *)); +int atexit(void (*func)(void)); +int mkstemp(char *template); +long double strtold(const char *restrict nptr, char **restrict endptr); +int system(const char *command); +double atof(const char *str); +double strtod(const char *restrict nptr, char **restrict endptr); +int atoi(const char *str); +#endif diff --git a/userland/libc/include/string.h b/userland/libc/include/string.h new file mode 100644 index 0000000..0c61efa --- /dev/null +++ b/userland/libc/include/string.h @@ -0,0 +1,29 @@ +#ifndef STRING_H +#define STRING_H +#include <stddef.h> +#include <stdint.h> + +char *strerror(int errnum); +void *memset(void *s, int c, size_t n); +void *memcpy(void *dest, const void *src, uint32_t n); +int strcmp(const char *s1, const char *s2); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *s); +size_t strnlen(const char *s, size_t maxlen); +int sscanf(const char *s, const char *restrict format, ...); +char *strrchr(const char *s, int c); +int strncmp(const char *s1, const char *s2, size_t n); +char *strncpy(char *s1, const char *s2, size_t n); +size_t *strlcpy(char *s1, const char *s2, size_t n); +size_t strcspn(const char *s1, const char *s2); +char *strpbrk(const char *s1, const char *s2); +size_t strspn(const char *s1, const char *s2); +void *memmove(void *s1, const void *s2, size_t n); +char *strdup(const char *s); +char *strndup(const char *s, size_t size); +char *strstr(const char *s1, const char *s2); +int strncasecmp(const char *s1, const char *s2, size_t n); +int strcasecmp(const char *s1, const char *s2); +char *strtok(char *restrict s, const char *restrict sep); +char *strcat(char *restrict s1, const char *restrict s2); +#endif diff --git a/userland/libc/include/strings.h b/userland/libc/include/strings.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/strings.h diff --git a/userland/libc/include/sys/ioctl.h b/userland/libc/include/sys/ioctl.h new file mode 100644 index 0000000..a373a4b --- /dev/null +++ b/userland/libc/include/sys/ioctl.h @@ -0,0 +1,10 @@ +#ifndef IOCTL_H +#define IOCTL_H +#define TIOCGWINSZ 0 +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; +#endif // IOCTL_H diff --git a/userland/libc/include/sys/mman.h b/userland/libc/include/sys/mman.h new file mode 100644 index 0000000..7dfe29a --- /dev/null +++ b/userland/libc/include/sys/mman.h @@ -0,0 +1,15 @@ +#ifndef MMAP_H +#define MMAP_H +#include <stdint.h> +#include <stddef.h> + +#define PROT_READ (1 << 0) +#define PROT_WRITE (1 << 1) + +#define MAP_PRIVATE (1 << 0) +#define MAP_ANONYMOUS (1<< 1) +#define MAP_SHARED (1<< 2) + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset); +#endif diff --git a/userland/libc/include/sys/mount.h b/userland/libc/include/sys/mount.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/mount.h diff --git a/userland/libc/include/sys/resource.h b/userland/libc/include/sys/resource.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/resource.h diff --git a/userland/libc/include/sys/socket.h b/userland/libc/include/sys/socket.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/socket.h diff --git a/userland/libc/include/sys/stat.h b/userland/libc/include/sys/stat.h new file mode 100644 index 0000000..178d014 --- /dev/null +++ b/userland/libc/include/sys/stat.h @@ -0,0 +1,31 @@ +#ifndef STAT_H +#define STAT_H +#include <sys/types.h> +#include <time.h> + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atime; // Last data access timestamp. + struct timespec st_mtime; // Last data modification timestamp. + struct timespec st_ctime; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; +int stat(const char *path, struct stat *buf); +int mkdir(const char *path, mode_t mode); +#endif diff --git a/userland/libc/include/sys/statvfs.h b/userland/libc/include/sys/statvfs.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/statvfs.h diff --git a/userland/libc/include/sys/syscall.h b/userland/libc/include/sys/syscall.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/syscall.h diff --git a/userland/libc/include/sys/time.h b/userland/libc/include/sys/time.h new file mode 100644 index 0000000..a675d9e --- /dev/null +++ b/userland/libc/include/sys/time.h @@ -0,0 +1,41 @@ +#ifndef TIME_H +#define TIME_H +#include <stddef.h> +#include <sys/types.h> +#include <time.h> + +#define CLOCK_REALTIME 0 + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long __tm_gmtoff; + const char *__tm_zone; +}; + +typedef int clockid_t; +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; + +struct timeval { + time_t tv_sec; + suseconds_t tv_usec; +}; + +time_t time(time_t *tloc); +int clock_gettime(clockid_t clock_id, struct timespec *tp); +struct tm *localtime(const time_t *timer); +struct tm *gmtime(const time_t *timer); +size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, + const struct tm *restrict timeptr); +int gettimeofday(struct timeval *tp, void *tzp); +#endif diff --git a/userland/libc/include/sys/times.h b/userland/libc/include/sys/times.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/times.h diff --git a/userland/libc/include/sys/types.h b/userland/libc/include/sys/types.h new file mode 100644 index 0000000..48c57f9 --- /dev/null +++ b/userland/libc/include/sys/types.h @@ -0,0 +1,28 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +typedef unsigned int suseconds_t; +#endif diff --git a/userland/libc/include/sys/ucontext.h b/userland/libc/include/sys/ucontext.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/ucontext.h diff --git a/userland/libc/include/sys/un.h b/userland/libc/include/sys/un.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/un.h diff --git a/userland/libc/include/sys/utsname.h b/userland/libc/include/sys/utsname.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/utsname.h diff --git a/userland/libc/include/sys/wait.h b/userland/libc/include/sys/wait.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/sys/wait.h diff --git a/userland/libc/include/syscall.h b/userland/libc/include/syscall.h new file mode 100644 index 0000000..caa7779 --- /dev/null +++ b/userland/libc/include/syscall.h @@ -0,0 +1,150 @@ +#ifndef SYSCALL_H +#define SYSCALL_H +#include "socket.h" +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +#define SYS_OPEN 0 +#define SYS_READ 1 +#define SYS_WRITE 2 +#define SYS_PREAD 3 +#define SYS_PWRITE 4 +#define SYS_FORK 5 +#define SYS_EXEC 6 +#define SYS_GETPID 7 +#define SYS_EXIT 8 +#define SYS_WAIT 9 +#define SYS_BRK 10 +#define SYS_SBRK 11 +#define SYS_PIPE 12 +#define SYS_DUP2 13 +#define SYS_CLOSE 14 +#define SYS_OPENPTY 15 +#define SYS_POLL 16 +#define SYS_MMAP 17 +#define SYS_ACCEPT 18 +#define SYS_BIND 19 +#define SYS_SOCKET 20 +#define SYS_SHM_OPEN 21 +#define SYS_FTRUNCATE 22 +#define SYS_STAT 23 +#define SYS_MSLEEP 24 +#define SYS_UPTIME 25 + +int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi); +int s_syscall(int sys); + +extern int errno; +#define RC_ERRNO(_rc) \ + { \ + int c = _rc; \ + if (c < 0) { \ + errno = -(c); \ + return -1; \ + } \ + return c; \ + } + +typedef int mode_t; + +typedef struct SYS_OPEN_PARAMS { + const char *file; + int flags; + int mode; +} __attribute__((packed)) SYS_OPEN_PARAMS; + +typedef struct SYS_PREAD_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PREAD_PARAMS; + +typedef struct SYS_READ_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_READ_PARAMS; + +typedef struct SYS_PWRITE_PARAMS { + int fd; + const void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PWRITE_PARAMS; + +typedef struct SYS_WRITE_PARAMS { + int fd; + const void *buf; + size_t count; +} __attribute__((packed)) SYS_WRITE_PARAMS; + +typedef struct SYS_EXEC_PARAMS { + const char *path; + char **argv; +} __attribute__((packed)) SYS_EXEC_PARAMS; + +typedef struct SYS_DUP2_PARAMS { + int org_fd; + int new_fd; +} __attribute__((packed)) SYS_DUP2_PARAMS; + +typedef struct SYS_OPENPTY_PARAMS { + int *amaster; + int *aslave; + char *name; + /*const struct termios*/ void *termp; + /*const struct winsize*/ void *winp; +} __attribute__((packed)) SYS_OPENPTY_PARAMS; + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +typedef struct SYS_FTRUNCATE_PARAMS { + int fildes; + size_t length; +} __attribute__((packed)) SYS_FTRUNCATE_PARAMS; + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; +#endif diff --git a/userland/libc/include/syslog.h b/userland/libc/include/syslog.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/syslog.h diff --git a/userland/libc/include/termios.h b/userland/libc/include/termios.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/termios.h diff --git a/userland/libc/include/time.h b/userland/libc/include/time.h new file mode 100644 index 0000000..567e9ef --- /dev/null +++ b/userland/libc/include/time.h @@ -0,0 +1,35 @@ +#ifndef TIME_H +#define TIME_H +#include <sys/types.h> +#include <stddef.h> + +#define CLOCK_REALTIME 0 + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long __tm_gmtoff; + const char *__tm_zone; +}; + +typedef int clockid_t; +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; + +time_t time(time_t *tloc); +int clock_gettime(clockid_t clock_id, struct timespec *tp); +struct tm *localtime(const time_t *timer); +struct tm *gmtime(const time_t *timer); +size_t strftime(char *restrict s, size_t maxsize, + const char *restrict format, const struct tm *restrict timeptr); +char *ctime_r(const time_t *clock, char *buf); +#endif diff --git a/userland/libc/include/ubsan.h b/userland/libc/include/ubsan.h new file mode 100644 index 0000000..dac5407 --- /dev/null +++ b/userland/libc/include/ubsan.h @@ -0,0 +1,79 @@ +#include <stdint.h> + +enum { type_kind_int = 0, type_kind_float = 1, type_unknown = 0xffff }; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct source_location { + const char *file_name; + union { + unsigned long reported; + struct { + uint32_t line; + uint32_t column; + }; + }; +}; + +struct OverflowData { + struct source_location location; + struct type_descriptor *type; +}; + +struct type_mismatch_data { + struct source_location location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_v1 { + struct source_location location; + struct type_descriptor *type; + unsigned char log_alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_common { + struct source_location *location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct nonnull_arg_data { + struct source_location location; + struct source_location attr_location; + int arg_index; +}; + +struct OutOfBoundsData { + struct source_location location; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct ShiftOutOfBoundsData { + struct source_location location; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct unreachable_data { + struct source_location location; +}; + +struct invalid_value_data { + struct source_location location; + struct type_descriptor *type; +}; + +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; diff --git a/userland/libc/include/unistd.h b/userland/libc/include/unistd.h new file mode 100644 index 0000000..e43dc33 --- /dev/null +++ b/userland/libc/include/unistd.h @@ -0,0 +1,24 @@ +#ifndef UNISTD_H +#define UNISTD_H +#include <stddef.h> +#include <stdint.h> +#include <sys/types.h> + +#define STDIN_FILENO 0 + +extern int opterr, optind, optopt; +extern char *optarg; + +int close(int fildes); +int ftruncate(int fildes, uint64_t length); +int execv(char *path, char **argv); +int pipe(int fd[2]); +int dup2(int org_fd, int new_fd); +int getopt(int argc, char *const argv[], const char *optstring); +pid_t getpid(void); +int unlink(const char *path); +int execvp(const char *file, char *const argv[]); +void _exit(int status); +void msleep(uint32_t ms); // not standard +uint32_t uptime(void); // not standard +#endif diff --git a/userland/libc/include/utime.h b/userland/libc/include/utime.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/utime.h diff --git a/userland/libc/include/wchar.h b/userland/libc/include/wchar.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/wchar.h diff --git a/userland/libc/include/wctype.h b/userland/libc/include/wctype.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/include/wctype.h diff --git a/userland/libc/input.h b/userland/libc/input.h new file mode 100644 index 0000000..a6602f5 --- /dev/null +++ b/userland/libc/input.h @@ -0,0 +1,9 @@ +#ifndef INPUT_H +#define INPUT_H +#include <stdint.h> + +struct input_event { + uint16_t key; + uint8_t status; +}; +#endif diff --git a/userland/libc/inttypes.h b/userland/libc/inttypes.h new file mode 100644 index 0000000..0bf39d1 --- /dev/null +++ b/userland/libc/inttypes.h @@ -0,0 +1,5 @@ +#include <stdint.h> + +// FIXME: These are not correct +#define PRId64 "d" +#define PRId32 "d" diff --git a/userland/libc/isspace.c b/userland/libc/isspace.c new file mode 100644 index 0000000..9ba2766 --- /dev/null +++ b/userland/libc/isspace.c @@ -0,0 +1,5 @@ +#include <ctype.h> + +int isspace(int c) { + return c == ' ' || (unsigned)c-'\t' < 5; +} diff --git a/userland/libc/libc.c b/userland/libc/libc.c new file mode 100644 index 0000000..259ef0c --- /dev/null +++ b/userland/libc/libc.c @@ -0,0 +1,287 @@ +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <syscall.h> + +int errno; + +char *errno_strings[] = { + "", + "Argument list too long.", + "Permission denied.", + "Address in use.", + "Address not available.", + "Address family not supported.", + "Resource unavailable, try again (may be the same value as [EWOULDBLOCK]).", + "Connection already in progress.", + "Bad file descriptor.", + "Bad message.", + "Device or resource busy.", + "Operation canceled.", + "No child processes.", + "Connection aborted.", + "Connection refused.", + "Connection reset.", + "Resource deadlock would occur.", + "Destination address required.", + "Mathematics argument out of domain of function.", + "Reserved.", + "File exists.", + "Bad address.", + "File too large.", + "Host is unreachable.", + "Identifier removed.", + "Illegal byte sequence.", + "Operation in progress.", + "Interrupted function.", + "Invalid argument.", + "I/O error.", + "Socket is connected.", + "Is a directory.", + "Too many levels of symbolic links.", + "File descriptor value too large.", + "Too many links.", + "Message too large.", + "Reserved.", + "Filename too long.", + "Network is down.", + "Connection aborted by network.", + "Network unreachable.", + "Too many files open in system.", + "No buffer space available.", + "No message is available on the STREAM head read " + "queue. [Option End]", + "No such device.", + "No such file or directory.", + "Executable file format error.", + "No locks available.", + "Reserved.", + "Not enough space.", + "No message of the desired type.", + "Protocol not available.", + "No space left on device.", + "No STREAM resources.", + "Not a STREAM.", + "Functionality not supported.", + "The socket is not connected.", + "Not a directory or a symbolic link to a directory.", + "Directory not empty.", + "State not recoverable.", + "Not a socket.", + "Not supported (may be the same value as [EOPNOTSUPP]).", + "Inappropriate I/O control operation.", + "No such device or address.", + "Operation not supported on socket (may be the same value as [ENOTSUP]).", + "Value too large to be stored in data type.", + "Previous owner died.", + "Operation not permitted.", + "Broken pipe.", + "Protocol error.", + "Protocol not supported.", + "Protocol wrong type for socket.", + "Result too large.", + "Read-only file system.", + "Invalid seek.", + "No such process.", + "Reserved.", + "Stream ioctl() timeout. [Option End]", + "Connection timed out.", + "Text file busy.", + "Operation would block (may be the same value as [EAGAIN]).", + "Cross-device link. ", +}; + +#define ASSERT_NOT_REACHED assert(0) + +#define TAB_SIZE 8 + +// Functions preserve the registers ebx, esi, edi, ebp, and esp; while +// eax, ecx, edx are scratch registers. + +// Syscall: eax ebx ecx edx esi edi +int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi) { + asm volatile("push %edi\n" + "push %esi\n" + "push %ebx\n" + "mov 0x1C(%ebp), %edi\n" + "mov 0x18(%ebp), %esi\n" + "mov 0x14(%ebp), %edx\n" + "mov 0x10(%ebp), %ecx\n" + "mov 0xc(%ebp), %ebx\n" + "mov 0x8(%ebp), %eax\n" + "int $0x80\n" + "pop %ebx\n" + "pop %esi\n" + "pop %edi\n"); +} + +int pipe(int fd[2]) { return syscall(SYS_PIPE, fd, 0, 0, 0, 0); } + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html +char *strerror(int errnum) { + // The strerror() function shall map the error number in errnum to a + // locale-dependent error message string and shall return a pointer to it. + return errno_strings[errnum]; +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/perror.html +void perror(const char *s) { + // The perror() function shall map the error number accessed through the + // symbol errno to a language-dependent error message, which shall be written + // to the standard error stream as follows: + + // (First (if s is not a null pointer and the character pointed to + // by s is not the null byte), + if (s && *s != '\0') { + // the string pointed to by s + // followed by a <colon> and a <space>. + printf("%s: ", s); + } + + // Then an error message string followed by a <newline>. + // The contents of the error message strings shall be the same as those + // returned by strerror() with argument errno. + printf("%s\n", strerror(errno)); +} + +int open(const char *file, int flags, int mode) { + struct SYS_OPEN_PARAMS args = { + .file = file, + .flags = flags, + .mode = mode, + }; + RC_ERRNO(syscall(SYS_OPEN, &args, 0, 0, 0, 0)); +} + +int close(int fd) { return syscall(SYS_CLOSE, (void *)fd, 0, 0, 0, 0); } + +int execv(char *path, char **argv) { + struct SYS_EXEC_PARAMS args = {.path = path, .argv = argv}; + return syscall(SYS_EXEC, &args, 0, 0, 0, 0); +} +/* +int syscall(int sys, void *args) { + asm volatile("push %ebx\n" + "mov 0xc(%ebp), %ebx\n" + "mov 0x8(%ebp), %eax\n" + "int $0x80\n" + "pop %ebx\n"); +}*/ + +int s_syscall(int sys) { + asm volatile("movl %0, %%eax\n" + "int $0x80\n" ::"r"((uint32_t)sys)); +} + +int write(int fd, const char *buf, size_t count) { + /* + struct SYS_WRITE_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + };*/ + return syscall(SYS_WRITE, fd, buf, count, 0, 0); +} + +int pwrite(int fd, const char *buf, size_t count, size_t offset) { + struct SYS_PWRITE_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + .offset = offset, + }; + return syscall(SYS_PWRITE, &args, 0, 0, 0, 0); +} + +int wait(int *stat_loc) { return syscall(SYS_WAIT, stat_loc, 0, 0, 0, 0); } + +void exit(int status) { syscall(SYS_EXIT, (void *)status, 0, 0, 0, 0); } + +int pread(int fd, void *buf, size_t count, size_t offset) { + struct SYS_PREAD_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + .offset = offset, + }; + RC_ERRNO(syscall(SYS_PREAD, &args, 0, 0, 0, 0)); +} + +int read(int fd, void *buf, size_t count) { + struct SYS_READ_PARAMS args = { + .fd = fd, + .buf = buf, + .count = count, + }; + RC_ERRNO(syscall(SYS_READ, &args, 0, 0, 0, 0)); +} + +int dup2(int org_fd, int new_fd) { + struct SYS_DUP2_PARAMS args = { + .org_fd = org_fd, + .new_fd = new_fd, + }; + RC_ERRNO(syscall(SYS_DUP2, &args, 0, 0, 0, 0)); +} + +int fork(void) { return s_syscall(SYS_FORK); } + +void dputc(int fd, const char c) { pwrite(fd, &c, 1, 0); } + +int brk(void *addr) { return syscall(SYS_BRK, addr, 0, 0, 0, 0); } + +void *sbrk(intptr_t increment) { + return (void *)syscall(SYS_SBRK, (void *)increment, 0, 0, 0, 0); +} + +int poll(struct pollfd *fds, size_t nfds, int timeout) { + SYS_POLL_PARAMS args = { + .fds = fds, + .nfds = nfds, + .timeout = timeout, + }; + RC_ERRNO(syscall(SYS_POLL, &args, 0, 0, 0, 0)); +} + +int socket(int domain, int type, int protocol) { + SYS_SOCKET_PARAMS args = { + .domain = domain, + .type = type, + .protocol = protocol, + }; + RC_ERRNO(syscall(SYS_SOCKET, &args, 0, 0, 0, 0)); +} + +int accept(int socket, struct sockaddr *address, socklen_t *address_len) { + SYS_ACCEPT_PARAMS args = { + .socket = socket, + .address = address, + .address_len = address_len, + }; + RC_ERRNO(syscall(SYS_ACCEPT, &args, 0, 0, 0, 0)); +} + +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { + SYS_BIND_PARAMS args = { + .sockfd = sockfd, + .addr = addr, + .addrlen = addrlen, + }; + RC_ERRNO(syscall(SYS_BIND, &args, 0, 0, 0, 0)); +} + +int shm_open(const char *name, int oflag, mode_t mode) { + SYS_SHM_OPEN_PARAMS args = { + .name = name, + .oflag = oflag, + .mode = mode, + }; + RC_ERRNO(syscall(SYS_SHM_OPEN, &args, 0, 0, 0, 0)); +} + +int ftruncate(int fildes, uint64_t length) { + SYS_FTRUNCATE_PARAMS args = {.fildes = fildes, .length = length}; + RC_ERRNO(syscall(SYS_FTRUNCATE, &args, 0, 0, 0, 0)); +} diff --git a/userland/libc/libgen/basename.c b/userland/libc/libgen/basename.c new file mode 100644 index 0000000..a0a8adb --- /dev/null +++ b/userland/libc/libgen/basename.c @@ -0,0 +1,45 @@ +#include <libgen.h> +#include <stddef.h> + +/* +The basename() function shall take the pathname pointed to by path and +return a pointer to the final component of the pathname, deleting any +trailing '/' characters. + + +The basename() function may modify the string pointed to by path, and +may return a pointer to internal storage. The returned pointer might be +invalidated or the storage might be overwritten by a subsequent call to +basename(). The returned pointer might also be invalidated if the +calling thread is terminated. +*/ + +char *basename_empty_return_value = "."; +char *basename_slash_return_value = "/"; +char *basename(char *path) { + // If path is a null pointer or points to an empty string, basename() + // shall return a pointer to the string ".". + if (NULL == path || '\0' == *path) + return basename_empty_return_value; + + char *start = path; + // Move the string to the end + for (; *path; path++) + ; + if (start == path) + return start; + path--; + if ('/' == *path) // Trailing slash + *path = '\0'; + // Loop until next slash is found + for (; path != start && '/' != *path; path--) + ; + // If the string pointed to by path consists entirely of the '/' character, + // basename() shall return a pointer to the string "/". If the string + // pointed to by path is exactly "//", it is implementation-defined whether + //'/' or "//" is returned. + path++; + if ('\0' == *path) + return basename_slash_return_value; + return path; +} diff --git a/userland/libc/libgen/dirname.c b/userland/libc/libgen/dirname.c new file mode 100644 index 0000000..fb3c813 --- /dev/null +++ b/userland/libc/libgen/dirname.c @@ -0,0 +1,44 @@ +#include <libgen.h> + +char *dirname_empty_return_value = "."; +char *dirname_slash_return_value = "/"; +char *dirname(char *path) { + // If path is a null pointer or points to an empty string, + // dirname() shall return a pointer to the string "." + if (!path) + return dirname_empty_return_value; + if ('\0' == *path) + return dirname_empty_return_value; + + char *start = path; + for (; *path; path++) + ; + path--; + if ('/' == *path) { + if (start == path) + return path; + path--; + } + + for (; path != start && '/' != *path; path--) + ; + // If path does not contain a '/', then dirname() shall return a pointer to + // the string ".". + if ('/' != *path) + return dirname_empty_return_value; + + if (path == start) + return dirname_slash_return_value; + + *path = '\0'; + path--; + + for (; path != start && '/' != *path; path--) + ; + + if ('/' != *path) + return dirname_empty_return_value; + + path++; + return path; +} diff --git a/userland/libc/limits.h b/userland/libc/limits.h new file mode 100644 index 0000000..0c9389a --- /dev/null +++ b/userland/libc/limits.h @@ -0,0 +1,2 @@ +#define PATH_MAX 256 +#define FILENAME_MAX PATH_MAX diff --git a/userland/libc/malloc/malloc.c b/userland/libc/malloc/malloc.c new file mode 100644 index 0000000..f351291 --- /dev/null +++ b/userland/libc/malloc/malloc.c @@ -0,0 +1,232 @@ +#include <assert.h> +#include <errno.h> +#include <malloc/malloc.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#define NEW_ALLOC_SIZE 0x20000 +#define MALLOC_HEADER_MAGIC 0x1337F00D +#define MALLOC_HEADER_PAD 0x11223344 + +#define IS_FREE (1 << 0) +#define IS_FINAL (1 << 1) + +typedef struct MallocHeader { + uint32_t magic; + uint32_t size; + uint8_t flags; + struct MallocHeader *n; +} MallocHeader; + +size_t max(size_t a, size_t b) { return (a > b) ? a : b; } + +//;size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +uint64_t delta_page(uint64_t a) { return 0x1000 - (a % 0x1000); } + +MallocHeader *head = NULL; +MallocHeader *final = NULL; +uint32_t total_heap_size = 0; + +int init_heap(void) { + head = (MallocHeader *)sbrk(NEW_ALLOC_SIZE); + if ((void *)-1 == head) { + perror("sbrk"); + exit(1); + } + total_heap_size += NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->magic = MALLOC_HEADER_MAGIC; + head->size = NEW_ALLOC_SIZE - sizeof(MallocHeader); + head->flags = IS_FREE | IS_FINAL; + head->n = NULL; + final = head; + return 1; +} + +int add_heap_memory(size_t min_desired) { + min_desired += sizeof(MallocHeader) + 0x1000; + size_t allocation_size = max(min_desired, NEW_ALLOC_SIZE); + allocation_size += delta_page(allocation_size); + void *p; + if ((void *)(-1) == (p = (void *)sbrk(allocation_size))) { + perror("sbrk"); + return 0; + } + total_heap_size += allocation_size - sizeof(MallocHeader); + void *e = final; + e = (void *)((uint32_t)e + final->size); + if (p == e) { + final->size += allocation_size - sizeof(MallocHeader); + return 1; + } + MallocHeader *new_entry = p; + new_entry->magic = MALLOC_HEADER_MAGIC; + new_entry->size = allocation_size - sizeof(MallocHeader); + new_entry->flags = IS_FREE | IS_FINAL; + new_entry->n = NULL; + final->n = new_entry; + final = new_entry; + return 1; +} + +MallocHeader *next_header(MallocHeader *a) { return a->n; } + +MallocHeader *next_close_header(MallocHeader *a) { + if (!a) { + printf("next close header fail\n"); + for (;;) + ; + } + if (a->flags & IS_FINAL) + return NULL; + return next_header(a); +} + +MallocHeader *find_free_entry(uint32_t s, int align) { + // A new header is required as well as the newly allocated chunk + if (!head) + init_heap(); + MallocHeader *p = head; + for (; p; p = next_header(p)) { + if (!(p->flags & IS_FREE)) + continue; + uint64_t required_size = s; + if (align) { + void *addy = p; + addy = (void *)((uint32_t)addy + sizeof(MallocHeader)); + uint64_t d = delta_page((uint32_t)addy); + if (d < sizeof(MallocHeader) && d != 0) + continue; + required_size += d; + } + if (p->size < required_size) + continue; + return p; + } + return NULL; +} + +void merge_headers(MallocHeader *b) { + if (!(b->flags & IS_FREE)) + return; + + MallocHeader *n = next_close_header(b); + if (!n) + return; + + if (n > 0xf58c0820 - 0x8 && n < 0xf58c0820 + 0x8) { + printf("b: %x\n", b); + printf("b->n: %x\n", b->n); + asm("hlt"); + assert(0); + } + if (!(n->flags & IS_FREE)) + return; + + // Remove the next header and just increase the newly freed header + b->size += n->size; + b->flags |= n->flags & IS_FINAL; + b->n = n->n; + if (n == final) + final = b; +} + +extern int errno; +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *int_malloc(size_t s, int align) { + if (!head) + init_heap(); + size_t n = s; + MallocHeader *free_entry = find_free_entry(s, align); + if (!free_entry) { + if (!add_heap_memory(s)) { + errno = ENOMEM; + printf("ENOMEM\n"); + return NULL; + } + return int_malloc(s, align); + } + + void *rc = (void *)((uint32_t)free_entry + sizeof(MallocHeader)); + + if (align) { + uint64_t d = delta_page((uint32_t)rc); + n = d; + n -= sizeof(MallocHeader); + } + + // Create a new header + MallocHeader *new_entry = + (MallocHeader *)((uint32_t)free_entry + n + sizeof(MallocHeader)); + new_entry->magic = MALLOC_HEADER_MAGIC; + new_entry->flags = free_entry->flags; + new_entry->n = free_entry->n; + new_entry->size = free_entry->size - n - sizeof(MallocHeader); + if (free_entry == final) + final = new_entry; + merge_headers(new_entry); + + // Modify the free entry + free_entry->size = n; + free_entry->flags = 0; + free_entry->n = new_entry; + + if (align && ((uint32_t)rc % 0x1000) != 0) { + void *c = int_malloc(s, 1); + free(rc); + rc = c; + return rc; + } + return rc; +} + +void *malloc(size_t s) { return int_malloc(s + 1, 0); } + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *calloc(size_t nelem, size_t elsize) { + // The calloc() function shall allocate unused space for an array of + // nelem elements each of whose size in bytes is elsize. + size_t alloc_size = nelem * elsize; + void *rc = malloc(alloc_size); + // The space shall be initialized to all bits 0. + memset(rc, 0, alloc_size); + return rc; +} + +size_t get_mem_size(void *ptr) { + if (!ptr) + return 0; + return ((MallocHeader *)(ptr - sizeof(MallocHeader)))->size; +} + +void *realloc(void *ptr, size_t size) { + void *rc = malloc(size); + if (!rc) + return NULL; + size_t l = get_mem_size(ptr); + size_t to_copy = min(l, size); + memcpy(rc, ptr, to_copy); + free(ptr); + return rc; +} + +void free(void *p) { + if (!p) + return; + // FIXME: This assumes that p is at the start of a allocated area. + // Is this a assumption that can be made? + MallocHeader *h = (MallocHeader *)((uint32_t)p - sizeof(MallocHeader)); + if (MALLOC_HEADER_MAGIC != h->magic) { + printf("h->magic: %x\n", h->magic); + printf("&h->magic: %x\n", &(h->magic)); + assert(0); + } + if (h->flags & IS_FREE) + return; + + h->flags |= IS_FREE; + merge_headers(h); +} diff --git a/userland/libc/malloc/malloc.h b/userland/libc/malloc/malloc.h new file mode 100644 index 0000000..082d8ad --- /dev/null +++ b/userland/libc/malloc/malloc.h @@ -0,0 +1,9 @@ +#ifndef MALLOC_H +#define MALLOC_H +#include <stdint.h> +#include <stddef.h> + +void *malloc(size_t s); +void *calloc(size_t nelem, size_t elsize); +void free(void *p); +#endif diff --git a/userland/libc/malloc/oldmalloc.c b/userland/libc/malloc/oldmalloc.c new file mode 100644 index 0000000..042049d --- /dev/null +++ b/userland/libc/malloc/oldmalloc.c @@ -0,0 +1,136 @@ +#include "stdio.h" +#include "stdlib.h" +#include "../errno.h" +#include <stdint.h> +#include <stddef.h> +#include <string.h> + +#define NEW_ALLOC_SIZE 0x1000 + +#define IS_FREE (1 << 0) +#define IS_FINAL (1 << 1) + +typedef struct MallocHeader { + uint32_t size; + uint8_t flags; +} MallocHeader; + +MallocHeader *head = NULL; +MallocHeader *final = NULL; +uint32_t total_heap_size = 0; + +int init_heap(void) { + head = sbrk(NEW_ALLOC_SIZE); + if ((void *)-1 == head) { + // perror("sbrk"); + return 0; + } + total_heap_size += NEW_ALLOC_SIZE; + head->size = NEW_ALLOC_SIZE; + head->flags = IS_FREE | IS_FINAL; + final = head; + return 1; +} + +int add_heap_memory(void) { + if ((void *)-1 == sbrk(NEW_ALLOC_SIZE)) { + // perror("sbrk"); + return 0; + } + total_heap_size += NEW_ALLOC_SIZE; + final->size += NEW_ALLOC_SIZE; + return 1; +} + +MallocHeader *next_header(MallocHeader *a) { + if (a->flags & IS_FINAL) + return NULL; + return ((void *)a) + a->size; +} + +MallocHeader *find_free_entry(uint32_t s) { + // A new header is required as well as the newly allocated chunk + s += sizeof(MallocHeader); + if (!head) + init_heap(); + MallocHeader *p = head; + for (; p; p = next_header(p)) { + if (!(p->flags & IS_FREE)) + continue; + if (p->size < s) + continue; + return p; + } + return NULL; +} + +void merge_headers(MallocHeader *b) { + if (!(b->flags & IS_FREE)) + return; + + MallocHeader *n = next_header(b); + if (!n) + return; + + if (!(n->flags & IS_FREE)) + return; + + // Remove the next header and just increase the newly freed header + b->size += n->size; + b->flags |= n->flags & IS_FINAL; + if (b->flags & IS_FINAL) + final = b; +} + +extern int errno; +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *malloc(size_t s) { + if(s == 0) + s = 1; + + MallocHeader *free_entry = find_free_entry(s); + if (!free_entry) { + if (!add_heap_memory()) { + errno = ENOMEM; + return NULL; + } + return malloc(s); + } + + // Create a new header + MallocHeader *new_entry = ((void *)free_entry) + s; + new_entry->flags |= IS_FREE; + new_entry->size = free_entry->size - s - sizeof(MallocHeader); + new_entry->flags |= free_entry->flags & IS_FINAL; + if (new_entry->flags & IS_FINAL) + final = new_entry; + merge_headers(new_entry); + + // Modify the free entry + free_entry->size = s; + free_entry->flags = 0; + + return ((void *)free_entry) + sizeof(MallocHeader); +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *calloc(size_t nelem, size_t elsize) { + // The calloc() function shall allocate unused space for an array of + // nelem elements each of whose size in bytes is elsize. + size_t alloc_size = nelem*elsize; + void *rc = malloc(alloc_size); + // The space shall be initialized to all bits 0. + memset(rc, 0, alloc_size); + return rc; +} + +void free(void *p) { + // FIXME: This assumes that p is at the start of a allocated area. + // Is this a assumption that can be made? + MallocHeader *h = p - sizeof(MallocHeader); + if (h->flags & IS_FREE) + return; + + h->flags |= IS_FREE; + merge_headers(h); +} diff --git a/userland/libc/math.h b/userland/libc/math.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/math.h diff --git a/userland/libc/memset.c b/userland/libc/memset.c new file mode 100644 index 0000000..51910e9 --- /dev/null +++ b/userland/libc/memset.c @@ -0,0 +1,15 @@ +#include <stddef.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +void *memset(void *s, int c, size_t n) { + // The memset() function shall copy c (converted to an unsigned + // char) into each of the first n bytes of the object pointed to by + // s. + + unsigned char *p = s; + for (; n > 0; n--, p++) + *p = (unsigned char)c; + + // The memset() function shall return s + return s; +} diff --git a/userland/libc/mmap.c b/userland/libc/mmap.c new file mode 100644 index 0000000..06b79bd --- /dev/null +++ b/userland/libc/mmap.c @@ -0,0 +1,19 @@ +#include <syscall.h> +#include <errno.h> +#include <sys/mman.h> + +extern int errno; + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset) { + SYS_MMAP_PARAMS args = { + .addr = addr, + .length = length, + .prot = prot, + .flags = flags, + .fd = fd, + .offset = offset, + }; +// return (void*)syscall(SYS_MMAP, &args); + RC_ERRNO(syscall(SYS_MMAP, &args)); +} diff --git a/userland/libc/poll.h b/userland/libc/poll.h new file mode 100644 index 0000000..88e98b3 --- /dev/null +++ b/userland/libc/poll.h @@ -0,0 +1,16 @@ +#ifndef POLL_H +#define POLL_H +#include <stddef.h> + +#define POLLIN (1 << 0) +#define POLLPRI (1 << 1) +#define POLLOUT (1 << 2) + +struct pollfd { + int fd; + short events; + short revents; +}; + +int poll(struct pollfd *fds, size_t nfds, int timeout); +#endif diff --git a/userland/libc/pty.c b/userland/libc/pty.c new file mode 100644 index 0000000..b7ddf00 --- /dev/null +++ b/userland/libc/pty.c @@ -0,0 +1,15 @@ +#include "pty.h" +#include "syscall.h" + +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp) { + SYS_OPENPTY_PARAMS args = { + .amaster = amaster, + .aslave = aslave, + .name = name, + .termp = termp, + .winp = winp, + }; + syscall(SYS_OPENPTY, &args, 0, 0, 0, 0); +} diff --git a/userland/libc/pty.h b/userland/libc/pty.h new file mode 100644 index 0000000..b8ce978 --- /dev/null +++ b/userland/libc/pty.h @@ -0,0 +1,6 @@ +#ifndef PTY_H +#define PTY_H +int openpty(int *amaster, int *aslave, char *name, + /*const struct termios*/ void *termp, + /*const struct winsize*/ void *winp); +#endif diff --git a/userland/libc/setjmp/longjmp.s b/userland/libc/setjmp/longjmp.s new file mode 100644 index 0000000..8188f06 --- /dev/null +++ b/userland/libc/setjmp/longjmp.s @@ -0,0 +1,16 @@ +.global _longjmp +.global longjmp +.type _longjmp,@function +.type longjmp,@function +_longjmp: +longjmp: + mov 4(%esp),%edx + mov 8(%esp),%eax + cmp $1,%eax + adc $0, %al + mov (%edx),%ebx + mov 4(%edx),%esi + mov 8(%edx),%edi + mov 12(%edx),%ebp + mov 16(%edx),%esp + jmp *20(%edx) diff --git a/userland/libc/setjmp/setjmp.s b/userland/libc/setjmp/setjmp.s new file mode 100644 index 0000000..4d19cf8 --- /dev/null +++ b/userland/libc/setjmp/setjmp.s @@ -0,0 +1,23 @@ +.global ___setjmp +.hidden ___setjmp +.global __setjmp +.global _setjmp +.global setjmp +.type __setjmp,@function +.type _setjmp,@function +.type setjmp,@function +___setjmp: +__setjmp: +_setjmp: +setjmp: + mov 4(%esp), %eax + mov %ebx, (%eax) + mov %esi, 4(%eax) + mov %edi, 8(%eax) + mov %ebp, 12(%eax) + lea 4(%esp), %ecx + mov %ecx, 16(%eax) + mov (%esp), %ecx + mov %ecx, 20(%eax) + xor %eax, %eax + ret diff --git a/userland/libc/socket.h b/userland/libc/socket.h new file mode 100644 index 0000000..5e86b45 --- /dev/null +++ b/userland/libc/socket.h @@ -0,0 +1,41 @@ +#include <stddef.h> +#include <stdint.h> + +#define AF_UNIX 0 +#define AF_LOCAL AF_UNIX + +#define INADDR_ANY 0 + +typedef struct { + int domain; + int type; + int protocol; + + // UNIX socket + char *path; + int incoming_fd; +} SOCKET; + +typedef struct { + char *path; + SOCKET *s; +} OPEN_UNIX_SOCKET; + +typedef uint32_t in_addr_t; +typedef uint16_t in_port_t; +typedef unsigned int sa_family_t; +typedef uint32_t socklen_t; + +struct sockaddr { + sa_family_t sa_family; /* Address family */ + char *sa_data; /* Socket address */ +}; + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char *sun_path; /* Socket pathname */ +}; + +int socket(int domain, int type, int protocol); +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); diff --git a/userland/libc/stdio.h b/userland/libc/stdio.h new file mode 100644 index 0000000..38aaf22 --- /dev/null +++ b/userland/libc/stdio.h @@ -0,0 +1,95 @@ +#ifndef STDIO_H +#define STDIO_H +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> + +// FIXME: Most of these should probably not be here. But I am too lazy +// to fix it right now. This is futures mees problem to deal wth. + +#define EOF (-1) + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +typedef struct __IO_FILE FILE; +struct __IO_FILE { + size_t (*write)(FILE *, const unsigned char *, size_t); + size_t (*read)(FILE *, unsigned char *, size_t); + int (*seek)(FILE *, long, int); + long offset_in_file; + int buffered_char; + int has_buffered_char; + uint8_t is_eof; + uint8_t has_error; + uint64_t file_size; + void *cookie; +}; + +size_t write_fd(FILE *f, const unsigned char *s, size_t l); +size_t read_fd(FILE *f, unsigned char *s, size_t l); +int seek_fd(FILE *stream, long offset, int whence); + +typedef struct { + int fd; +} FILE_FD_COOKIE; + +extern FILE __stdin_FILE; +extern FILE __stdout_FILE; +extern FILE __stderr_FILE; + +#define stdin (&__stdin_FILE) +#define stdout (&__stdout_FILE) +//#define stderr (&__stderr_FILE) +#define stderr (&__stdout_FILE) + +typedef int mode_t; + +void perror(const char *s); + +int putchar(int c); +int puts(const char *s); +int brk(void *addr); +void *sbrk(intptr_t increment); +int write(int fd, const char *buf, size_t count); +int pwrite(int fd, const char *buf, size_t count, size_t offset); +int printf(const char *format, ...); +int pread(int fd, void *buf, size_t count, size_t offset); +int read(int fd, void *buf, size_t count); +int fork(void); +int memcmp(const void *s1, const void *s2, size_t n); +int wait(int *stat_loc); +void exit(int status); +void *memcpy(void *dest, const void *src, uint32_t n); +int shm_open(const char *name, int oflag, mode_t mode); +int dprintf(int fd, const char *format, ...); +int vdprintf(int fd, const char *format, va_list ap); +int vprintf(const char *format, va_list ap); +int snprintf(char *str, size_t size, const char *format, ...); +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +int vfprintf(FILE *f, const char *fmt, va_list ap); +int fgetc(FILE *stream); +int getchar(void); +#define getc(_a) fgetc(_a) +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); +FILE *fopen(const char *pathname, const char *mode); +int fclose(FILE *stream); +int fseek(FILE *stream, long offset, int whence); +int fprintf(FILE *f, const char *fmt, ...); +long strtol(const char *nptr, char **endptr, int base); +char *strchr(const char *s, int c); +char *strcat(char *s1, const char *s2); +char *fgets(char *s, int n, FILE *stream); +FILE *tmpfile(void); +int feof(FILE *stream); +int fscanf(FILE *stream, const char *format, ...); +int ungetc(int c, FILE *stream); +long ftell(FILE *stream); +int fputc(int c, FILE *stream); +int remove(const char *path); +int ferror(FILE *stream); +int fputs(const char *s, FILE *stream); +int fflush(FILE *stream); +#endif diff --git a/userland/libc/stdio/dprintf.c b/userland/libc/stdio/dprintf.c new file mode 100644 index 0000000..2f2aadb --- /dev/null +++ b/userland/libc/stdio/dprintf.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int dprintf(int fd, const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vdprintf(fd, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/fclose.c b/userland/libc/stdio/fclose.c new file mode 100644 index 0000000..02d93ae --- /dev/null +++ b/userland/libc/stdio/fclose.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <stdlib.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fclose.html +// FIXME: Do some actual error checking. +int fclose(FILE *stream) { + free(stream->cookie); + free(stream); + return 0; +} diff --git a/userland/libc/stdio/feof.c b/userland/libc/stdio/feof.c new file mode 100644 index 0000000..7f46301 --- /dev/null +++ b/userland/libc/stdio/feof.c @@ -0,0 +1,5 @@ +#include <stdio.h> + +int feof(FILE *stream) { + return stream->is_eof; +} diff --git a/userland/libc/stdio/ferror.c b/userland/libc/stdio/ferror.c new file mode 100644 index 0000000..8cb46cf --- /dev/null +++ b/userland/libc/stdio/ferror.c @@ -0,0 +1,5 @@ +#include <stdio.h> + +int ferror(FILE *stream) { + return stream->has_error; +} diff --git a/userland/libc/stdio/fflush.c b/userland/libc/stdio/fflush.c new file mode 100644 index 0000000..7a37c79 --- /dev/null +++ b/userland/libc/stdio/fflush.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html +int fflush(FILE *stream) { + // FIXME: Implement + return 0; +} diff --git a/userland/libc/stdio/fgetc.c b/userland/libc/stdio/fgetc.c new file mode 100644 index 0000000..c69211f --- /dev/null +++ b/userland/libc/stdio/fgetc.c @@ -0,0 +1,20 @@ +#include <assert.h> +#include <stdio.h> + +int fgetc(FILE *stream) { + if (stream->has_buffered_char) { + stream->has_buffered_char = 0; + return stream->buffered_char; + } + char c; + if (1 == fread(&c, 1, 1, stream)) + return (int)c; + // FIXME: Should use feof and ferror + if (stream->has_error) + return EOF; + if (stream->is_eof) + return EOF; + // How did we get here? + assert(0); + return EOF; +} diff --git a/userland/libc/stdio/fgetpos.c b/userland/libc/stdio/fgetpos.c new file mode 100644 index 0000000..7f34d6a --- /dev/null +++ b/userland/libc/stdio/fgetpos.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +// FIXME: Error handling +int fgetpos(FILE *restrict stream, fpos_t *restrict pos) { + *pos = (fpos_t)stream->offset_in_file; + return 0; +} diff --git a/userland/libc/stdio/fgets.c b/userland/libc/stdio/fgets.c new file mode 100644 index 0000000..8e21501 --- /dev/null +++ b/userland/libc/stdio/fgets.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +char *fgets(char *s, int n, FILE *stream) { + for (int i = 0; i < n; i++) { + char c; + fread(&c, 1, 1, stream); + if (stream->has_error) + return NULL; + if (stream->is_eof) + return NULL; + s[i] = c; + if (c == '\n') + break; + } + return s; +} diff --git a/userland/libc/stdio/fileno.c b/userland/libc/stdio/fileno.c new file mode 100644 index 0000000..246cc51 --- /dev/null +++ b/userland/libc/stdio/fileno.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <errno.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fileno.html +// The fileno() function shall return the integer file descriptor associated +// with the stream pointed to by stream. +int fileno(FILE *stream) { + if (-1 == stream->fd) { + errno = EBADF; + return -1; + } + return stream->fd; +} diff --git a/userland/libc/stdio/fopen.c b/userland/libc/stdio/fopen.c new file mode 100644 index 0000000..a29c7ef --- /dev/null +++ b/userland/libc/stdio/fopen.c @@ -0,0 +1,57 @@ +#include <fcntl.h> +#include <sys/stat.h> +#include <stdint.h> +#include <stdio.h> + +// FIXME: All modes not implemented +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html +FILE *fopen(const char *pathname, const char *mode) { + uint8_t read = 0; + uint8_t write = 0; + uint8_t append = 0; + // FIXME: Not parsed correctly + for (; *mode; mode++) { + // r or rb + // Open file for reading. + // w or wb + // Truncate to zero length or create file for writing. + // a or ab + // Append; open or create file for writing at + // end-of-file. + switch (*mode) { + case 'r': + read = 1; + break; + case 'w': + write = 1; + break; + case 'a': + append = 1; + break; + } + } + int flag = 0; + if (read) + flag |= O_READ; + if (write) + flag |= O_WRITE; + + int fd = open(pathname, flag, 0); + if (-1 == fd) + return NULL; + + struct stat s; + stat(pathname, &s); + + FILE *r = malloc(sizeof(FILE)); + r->read = read_fd; + r->write = write_fd; + r->seek = seek_fd; + r->has_error = 0; + r->is_eof = 0; + r->offset_in_file = 0; + r->file_size = s.st_size; + r->cookie = NULL; + r->fd = fd; + return r; +} diff --git a/userland/libc/stdio/fprintf.c b/userland/libc/stdio/fprintf.c new file mode 100644 index 0000000..f983065 --- /dev/null +++ b/userland/libc/stdio/fprintf.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int fprintf(FILE *f, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int rc = vfprintf(f, fmt, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/fputc.c b/userland/libc/stdio/fputc.c new file mode 100644 index 0000000..7c8fa7c --- /dev/null +++ b/userland/libc/stdio/fputc.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int fputc(int c, FILE *stream) { + if (fwrite(&c, 1, 1, stream) > 0) + return c; + return EOF; +} diff --git a/userland/libc/stdio/fputs.c b/userland/libc/stdio/fputs.c new file mode 100644 index 0000000..1b70c66 --- /dev/null +++ b/userland/libc/stdio/fputs.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int fputs(const char *s, FILE *stream) { + const char *b = s; + for (; *s; s++) + if (0 == fwrite(s, 1, 1, stream)) + return EOF; + return s - b; +} diff --git a/userland/libc/stdio/fread.c b/userland/libc/stdio/fread.c new file mode 100644 index 0000000..1a27afa --- /dev/null +++ b/userland/libc/stdio/fread.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <sys/types.h> + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { + // FIXME: Check for overflow + ssize_t bytes_to_read = nmemb * size; + size_t rc = stream->read(stream, ptr, bytes_to_read); + // On success, fread() return the number of items read + rc /= size; + return rc; +} diff --git a/userland/libc/stdio/fscanf.c b/userland/libc/stdio/fscanf.c new file mode 100644 index 0000000..785ce4b --- /dev/null +++ b/userland/libc/stdio/fscanf.c @@ -0,0 +1,7 @@ +#include <stdio.h> +#include <assert.h> + +int fscanf(FILE *stream, const char *format, ...) { + // FIXME + assert(0); +} diff --git a/userland/libc/stdio/fseek.c b/userland/libc/stdio/fseek.c new file mode 100644 index 0000000..fb891ec --- /dev/null +++ b/userland/libc/stdio/fseek.c @@ -0,0 +1,21 @@ +#include <stdio.h> +#include <assert.h> + +int fseek(FILE *stream, long offset, int whence) { + return stream->seek(stream, offset, whence); + /* + switch (whence) { + case SEEK_SET: + stream->offset_in_file = offset; + break; + case SEEK_CUR: + stream->offset_in_file += offset; + break; + case SEEK_END: + // FIXME + assert(0); + break; + } + // FIXME: Error checking + return 0;*/ +} diff --git a/userland/libc/stdio/fsetpos.c b/userland/libc/stdio/fsetpos.c new file mode 100644 index 0000000..c39c545 --- /dev/null +++ b/userland/libc/stdio/fsetpos.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +// FIXME: Error handling +int fsetpos(FILE *stream, const fpos_t *pos) { + stream->offset_in_file = (long)(*pos); + return 0; +} diff --git a/userland/libc/stdio/ftell.c b/userland/libc/stdio/ftell.c new file mode 100644 index 0000000..35076d0 --- /dev/null +++ b/userland/libc/stdio/ftell.c @@ -0,0 +1,5 @@ +#include <stdio.h> + +long ftell(FILE *stream) { + return stream->offset_in_file; +} diff --git a/userland/libc/stdio/fwrite.c b/userland/libc/stdio/fwrite.c new file mode 100644 index 0000000..552bbd6 --- /dev/null +++ b/userland/libc/stdio/fwrite.c @@ -0,0 +1,12 @@ +#include <stdio.h> +#include <sys/types.h> + +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + // FIXME: Check for overflow + ssize_t bytes_to_write = nmemb * size; + size_t rc = stream->write(stream, ptr, bytes_to_write); + // On success, fwrite() return the number of items + // written. + rc /= size; + return rc; +} diff --git a/userland/libc/stdio/getchar.c b/userland/libc/stdio/getchar.c new file mode 100644 index 0000000..dad2263 --- /dev/null +++ b/userland/libc/stdio/getchar.c @@ -0,0 +1,4 @@ +#include <stdio.h> + +// The getchar() function shall be equivalent to getc(stdin). +int getchar(void) { return fgetc(stdin); } diff --git a/userland/libc/stdio/open_memstream.c b/userland/libc/stdio/open_memstream.c new file mode 100644 index 0000000..8f359b9 --- /dev/null +++ b/userland/libc/stdio/open_memstream.c @@ -0,0 +1,108 @@ +#include <assert.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +/* +struct __IO_FILE { + size_t (*write)(FILE *, const unsigned char *, size_t); + size_t (*read)(FILE *, unsigned char *, size_t); + int (*seek)(FILE *, long, int); + long offset_in_file; + int buffered_char; + int has_buffered_char; + int fd; + uint8_t is_eof; + uint8_t has_error; + uint64_t file_size; + void *cookie; +}; +*/ + +struct Memstream { + size_t buffer_usage; + char *buffer; +}; + +#define MEMSTREAM_DEF_SIZE 4096 + +size_t memstream_write(FILE *fp, const unsigned char *buf, size_t n) { + struct Memstream *c = fp->cookie; + // FIXME: Do a reallocation + if (c->buffer_usage + n >= fp->file_size) { + n = fp->file_size - c->buffer_usage; + } + + memcpy(c->buffer + fp->offset_in_file, buf, n); + fp->offset_in_file += n; + if (fp->offset_in_file > c->buffer_usage) + c->buffer_usage = fp->offset_in_file; + return n; +} + +size_t memstream_read(FILE *fp, unsigned char *buf, size_t n) { + struct Memstream *c = fp->cookie; + size_t length_left = c->buffer_usage - fp->offset_in_file; + n = min(length_left, n); + memcpy(buf, c->buffer + fp->offset_in_file, n); + fp->offset_in_file += n; + if (0 == n) + fp->is_eof = 1; + return n; +} + +int memstream_seek(FILE *stream, long offset, int whence) { + switch (whence) { + case SEEK_SET: + stream->offset_in_file = offset; + break; + case SEEK_CUR: + stream->offset_in_file += offset; + break; + case SEEK_END: + stream->offset_in_file = stream->file_size + offset; + break; + default: + assert(0); + break; + } + // FIXME: Error checking + return 0; +} + +FILE *open_memstream(char **bufp, size_t *sizep) { + struct Memstream *c = NULL; + FILE *fp = malloc(sizeof(FILE)); + if (!fp) + return NULL; + + fp->offset_in_file = 0; + fp->buffered_char = 0; + fp->has_buffered_char = 0; + fp->seek = memstream_seek; + fp->fd = -1; + fp->is_eof = 0; + fp->has_error = 0; + fp->file_size = MEMSTREAM_DEF_SIZE; + + fp->write = memstream_write; + fp->read = memstream_read; + + c = malloc(sizeof(struct Memstream)); + if (!c) { + goto _exit_memstream_fail; + } + + fp->cookie = (void *)c; + + c->buffer = *bufp = malloc(MEMSTREAM_DEF_SIZE); + if (!bufp) { + goto _exit_memstream_fail; + } + c->buffer_usage = 0; + + return fp; +_exit_memstream_fail: + free(c); + free(fp); + return NULL; +} diff --git a/userland/libc/stdio/printf.c b/userland/libc/stdio/printf.c new file mode 100644 index 0000000..d26568a --- /dev/null +++ b/userland/libc/stdio/printf.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int printf(const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vprintf(format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/putc.c b/userland/libc/stdio/putc.c new file mode 100644 index 0000000..a468a95 --- /dev/null +++ b/userland/libc/stdio/putc.c @@ -0,0 +1,3 @@ +#include <stdio.h> + +int putc(int c, FILE *stream) { return fputc(c, stream);} diff --git a/userland/libc/stdio/putchar.c b/userland/libc/stdio/putchar.c new file mode 100644 index 0000000..3fcf7ca --- /dev/null +++ b/userland/libc/stdio/putchar.c @@ -0,0 +1,7 @@ +#include <stdio.h> +#include <unistd.h> + +int putchar(int c) { + printf("%c", (char)c); + return c; +} diff --git a/userland/libc/stdio/puts.c b/userland/libc/stdio/puts.c new file mode 100644 index 0000000..4a72e66 --- /dev/null +++ b/userland/libc/stdio/puts.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int puts(const char *s) { + int rc = printf("%s\n", s); + return rc; +} diff --git a/userland/libc/stdio/remove.c b/userland/libc/stdio/remove.c new file mode 100644 index 0000000..35b41ad --- /dev/null +++ b/userland/libc/stdio/remove.c @@ -0,0 +1,9 @@ +#include <stdio.h> +#include <errno.h> + +extern int errno; +int remove(const char *path) { + // FIXME + errno = ENAMETOOLONG; + return -1; +} diff --git a/userland/libc/stdio/rename.c b/userland/libc/stdio/rename.c new file mode 100644 index 0000000..15d4bf5 --- /dev/null +++ b/userland/libc/stdio/rename.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#include <assert.h> + +int rename(const char *old, const char *new) { + (void)old; + (void)new; + assert(0); // TODO: Implement + } diff --git a/userland/libc/stdio/setvbuf.c b/userland/libc/stdio/setvbuf.c new file mode 100644 index 0000000..7f91518 --- /dev/null +++ b/userland/libc/stdio/setvbuf.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int setvbuf(FILE *restrict stream, char *restrict buf, int type, size_t size) { + // TODO + return 0; +} diff --git a/userland/libc/stdio/snprintf.c b/userland/libc/stdio/snprintf.c new file mode 100644 index 0000000..328442a --- /dev/null +++ b/userland/libc/stdio/snprintf.c @@ -0,0 +1,42 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +struct sn_cookie { + char *s; + size_t n; +}; + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +size_t sn_write(FILE *f, const unsigned char *s, const size_t l) { + struct sn_cookie *c = f->cookie; + size_t k = MIN(l, c->n); + memcpy(c->s, s, k); + c->s += k; + c->n -= k; + *(c->s) = '\0'; + // Upon successful completion, the snprintf() function shall return the number + // of bytes that would be written to s had n been sufficiently large excluding + // the terminating null byte. + return l; +} + +int vsnprintf(char *str, size_t size, const char *format, va_list ap) { + char dummy[1]; + struct sn_cookie c = {.s = (size ? str : dummy), .n = (size ? size - 1 : 0)}; + FILE f = { + .write = sn_write, + .cookie = &c, + }; + return vfprintf(&f, format, ap); +} + +int snprintf(char *str, size_t size, const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vsnprintf(str, size, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/sprintf.c b/userland/libc/stdio/sprintf.c new file mode 100644 index 0000000..deffbbe --- /dev/null +++ b/userland/libc/stdio/sprintf.c @@ -0,0 +1,33 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +struct s_cookie { + char *s; +}; + +size_t s_write(FILE *f, const unsigned char *s, size_t l) { + struct s_cookie *c = f->cookie; + memcpy(c->s, s, l); + c->s += l; + *(c->s) = '\0'; + return l; +} + +int vsprintf(char *str, const char *format, va_list ap) { + struct s_cookie c = {.s = str}; + FILE f = { + .write = s_write, + .cookie = &c, + }; + return vfprintf(&f, format, ap); +} + +int sprintf(char *str, const char *format, ...) { + va_list ap; + va_start(ap, format); + int rc = vsprintf(str, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/stdio/stderr.c b/userland/libc/stdio/stderr.c new file mode 100644 index 0000000..76597e2 --- /dev/null +++ b/userland/libc/stdio/stderr.c @@ -0,0 +1,11 @@ +#include <stdio.h> +#include <unistd.h> + +FILE __stderr_FILE = { + .write = write_fd, + .read = read_fd, + .is_eof = 0, + .has_error = 0, + .cookie = NULL, + .fd = 2, +}; diff --git a/userland/libc/stdio/stdin.c b/userland/libc/stdio/stdin.c new file mode 100644 index 0000000..ae3ab8d --- /dev/null +++ b/userland/libc/stdio/stdin.c @@ -0,0 +1,54 @@ +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +size_t write_fd(FILE *f, const unsigned char *s, size_t l) { + int rc = pwrite(f->fd, s, l, f->offset_in_file); + if (rc == -1) { + f->has_error = 1; + return 0; + } + f->offset_in_file += rc; + return rc; +} + +size_t read_fd(FILE *f, unsigned char *s, size_t l) { + int rc = pread(f->fd, s, l, f->offset_in_file); + if (rc == 0) + f->is_eof = 1; + if (rc == -1) { + f->has_error = 1; + return 0; + } + f->offset_in_file += rc; + return rc; +} + +int seek_fd(FILE *stream, long offset, int whence) { + switch (whence) { + case SEEK_SET: + stream->offset_in_file = offset; + break; + case SEEK_CUR: + stream->offset_in_file += offset; + break; + case SEEK_END: + stream->offset_in_file = stream->file_size + offset; + break; + default: + assert(0); + break; + } + // FIXME: Error checking + return 0; +} + +FILE __stdin_FILE = { + .write = write_fd, + .read = read_fd, + .seek = NULL, + .is_eof = 0, + .has_error = 0, + .cookie = NULL, + .fd = 0, +}; diff --git a/userland/libc/stdio/stdout.c b/userland/libc/stdio/stdout.c new file mode 100644 index 0000000..7f4edf0 --- /dev/null +++ b/userland/libc/stdio/stdout.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <unistd.h> + +FILE __stdout_FILE = { + .write = write_fd, + .read = read_fd, + .is_eof = 0, + .has_error = 0, + .seek = NULL, + .cookie = NULL, + .fd = 1, +}; +FILE __stderr_FILE; diff --git a/userland/libc/stdio/tmpfile.c b/userland/libc/stdio/tmpfile.c new file mode 100644 index 0000000..cee6e0a --- /dev/null +++ b/userland/libc/stdio/tmpfile.c @@ -0,0 +1,9 @@ +#include <stdio.h> +#include <assert.h> + +FILE *tmpfile(void) { + // TODO + printf("TODO: Implement tmpfile()\n"); + assert(0); + return NULL; +} diff --git a/userland/libc/stdio/tmpnam.c b/userland/libc/stdio/tmpnam.c new file mode 100644 index 0000000..aafe67d --- /dev/null +++ b/userland/libc/stdio/tmpnam.c @@ -0,0 +1,10 @@ +#include <assert.h> +#include <stdio.h> + +char *tmpnam(char *s) { + assert(!s); + s = malloc(100); + strcpy(s, "/tmp.XXXXXX"); + mkstemp(s); + return s; +} diff --git a/userland/libc/stdio/ungetc.c b/userland/libc/stdio/ungetc.c new file mode 100644 index 0000000..8d649bc --- /dev/null +++ b/userland/libc/stdio/ungetc.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int ungetc(int c, FILE *stream) { + if (stream->has_buffered_char) + return EOF; + stream->buffered_char = c; + stream->has_buffered_char = 1; + return c; +} diff --git a/userland/libc/stdio/vdprintf.c b/userland/libc/stdio/vdprintf.c new file mode 100644 index 0000000..b3fa065 --- /dev/null +++ b/userland/libc/stdio/vdprintf.c @@ -0,0 +1,77 @@ +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +struct vd_cookie { + int fd; + char *buffer; + uint8_t buf_len; + uint8_t buf_used; + int sent_bytes; +}; + +size_t min(size_t a, size_t b) { return (a < b) ? a : b; } + +size_t vd_write(FILE *f, const unsigned char *s, size_t l) { + struct vd_cookie *c = f->cookie; + + int clear_buffer = 0; + size_t b_copy = min(l, c->buf_len - (c->buf_used)); + for (int i = 0; i < b_copy; i++) { + c->buffer[c->buf_used + i] = s[i]; + if (s[i] == '\n') + clear_buffer = 1; + } + c->buf_used += b_copy; + + if (clear_buffer) { + int rc = write(c->fd, c->buffer, c->buf_used); + c->buf_used = 0; + if (-1 == rc) { + return (size_t)-1; + } + c->sent_bytes += rc; + } + return l; +} + +int vdprintf(int fd, const char *format, va_list ap) { + FILE f = { + .write = write_fd, + .fd = fd, + }; + return vfprintf(&f, format, ap); + // return -1; + /* +char buffer[32]; +struct vd_cookie c = {.fd = fd, + .buffer = buffer, + .buf_len = 32, + .buf_used = 0, + .sent_bytes = 0}; +FILE f = { +.write = vd_write, +.cookie = &c, +}; + +// If an output error was encountered, these functions shall return a +// negative value and set errno to indicate the error. +if (-1 == vfprintf(&f, format, ap)) +return -1; + +// Upon successful completion, the dprintf(), +// fprintf(), and printf() functions shall return the number of bytes +// transmitted. + +if(0 == c.buf_used) +return c.sent_bytes; + +// First the current buffer needs to be cleared +int rc = write(fd, buffer, c.buf_used); +if (-1 == rc) { +return -1; +} +c.sent_bytes += rc; +return c.sent_bytes;*/ +} diff --git a/userland/libc/stdio/vfprintf.c b/userland/libc/stdio/vfprintf.c new file mode 100644 index 0000000..79a22fb --- /dev/null +++ b/userland/libc/stdio/vfprintf.c @@ -0,0 +1,243 @@ +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +const char HEX_SET[0x10] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + +#define FILE_WRITE(_f, _s, _l, _r) \ + { \ + size_t _rc = _f->write(_f, (const unsigned char *)_s, _l); \ + if ((size_t)-1 == _rc) \ + assert(0); \ + *(int *)(_r) += _rc; \ + } +// if ((size_t)0 == _rc) \ +// assert(0); \ + +int fprint_num(FILE *f, int n, int base, char *char_set, int prefix, + int zero_padding, int right_padding) { + int c = 0; + if (0 == n) { + zero_padding = 1; + prefix = 1; + } + char str[32]; + int i = 0; + for (; n != 0 && i < 32; i++, n /= base) + // str[i] = (n % base) + '0'; + str[i] = char_set[(n % base)]; + + char t = (zero_padding) ? '0' : ' '; + int orig_i = i; + + if (!right_padding) { + for (; prefix - orig_i > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + + for (i--; i >= 0; i--) + FILE_WRITE(f, &(str[i]), 1, &c); + + if (right_padding) { + for (; prefix - orig_i > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + return c; +} + +int fprint_int(FILE *f, int n, int prefix, int zero_padding, + int right_padding) { + return fprint_num(f, n, 10, "0123456789", prefix, zero_padding, + right_padding); +} + +int fprint_hex(FILE *f, int n, int prefix, int zero_padding, + int right_padding) { + return fprint_num(f, n, 16, "0123456789abcdef", prefix, zero_padding, + right_padding); +} + +int fprint_octal(FILE *f, int n, int prefix, int zero_padding, + int right_padding) { + return fprint_num(f, n, 8, "012345678", prefix, zero_padding, right_padding); +} + +int print_string(FILE *f, const char *s, int *rc, int prefix, int right_padding, + int precision) { + int l = strlen(s); + char t = ' '; + int c = 0; + if (!right_padding) { + if (prefix) + assert(-1 == precision); // FIXME: Is this correct? + for (; prefix - l > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + int bl = precision; + for (; *s; s++, (*rc)++) { + if (precision != -1) { + if (0 == bl) + break; + bl--; + } + int r; + FILE_WRITE(f, (const unsigned char *)s, 1, &r); + assert(r != 0); + } + if (right_padding) { + assert(-1 == precision); // FIXME: Is this correct? + for (; prefix - l > 0; prefix--) + FILE_WRITE(f, &t, 1, &c); + } + (*rc) += c; + return 0; +} + +int parse_precision(const char **fmt) { + const char *s = *fmt; + int rc = 0; + for (int i = 0;; i++, s++) { + if ('\0' == *s) + break; + const char c = *s; + if ('*' == c) { + assert(i == 0); + return -1; + } else if (!(c >= '0' && c <= '9')) { + s--; + break; + } + rc *= 10; + rc += c - '0'; + } + *fmt = s; + return rc; +} + +int vfprintf(FILE *f, const char *fmt, va_list ap) { + int rc = 0; + const char *s = fmt; + int prefix = 0; + + int zero_padding = 0; + int right_padding = 0; + + int cont = 0; + int precision = -1; + for (; *s; s++) { + if (!cont && '%' != *s) { + FILE_WRITE(f, (const unsigned char *)s, 1, &rc); + continue; + } + if (!cont) { + cont = 1; + continue; + } + + if ('\0' == *s) + break; + + switch (*s) { + case '.': + s++; + assert('\0' != *s); + precision = parse_precision(&s); + assert('\0' != *s); + if (-1 == precision) + precision = va_arg(ap, int); + cont = 1; + break; + case '0': + prefix *= 10; + if (0 == prefix) + zero_padding = 1; + cont = 1; + break; + case '-': + assert(0 == prefix); + right_padding = 1; + cont = 1; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + prefix *= 10; + prefix += (*s) - '0'; + cont = 1; + break; + case 'i': + case 'd': + if(-1 != precision) { + zero_padding = 1; + prefix = precision; + right_padding = 0; + } + rc += fprint_int(f, va_arg(ap, int), prefix, zero_padding, right_padding); + cont = 0; + break; + case 'u': + assert(-1 == precision); + rc += fprint_int(f, va_arg(ap, unsigned int), prefix, zero_padding, + right_padding); + cont = 0; + break; + case 's': { + assert(!zero_padding); // this is not supported to strings + char *a = va_arg(ap, char *); + if (!a) { + if (-1 == + print_string(f, "(NULL)", &rc, prefix, right_padding, precision)) + return -1; + cont = 0; + break; + } + if (-1 == print_string(f, a, &rc, prefix, right_padding, precision)) + return -1; + cont = 0; + break; + } + case 'p': // TODO: Print this out in a nicer way + case 'x': + assert(-1 == precision); + rc += fprint_hex(f, va_arg(ap, const uint32_t), prefix, zero_padding, + right_padding); + cont = 0; + break; + case 'o': + assert(-1 == precision); + rc += fprint_octal(f, va_arg(ap, const uint32_t), prefix, zero_padding, + right_padding); + cont = 0; + break; + case '%': { + FILE_WRITE(f, (const unsigned char *)"%", 1, &rc); + cont = 0; + break; + } + case 'c': { + char c = va_arg(ap, const int); + FILE_WRITE(f, (const unsigned char *)&c, 1, &rc); + cont = 0; + break; + } + default: + printf("got %c but that is not supported by printf\n", *s); + assert(0); + break; + } + if (!cont) { + prefix = 0; + zero_padding = right_padding = 0; + precision = -1; + } + } + return rc; +} diff --git a/userland/libc/stdio/vprintf.c b/userland/libc/stdio/vprintf.c new file mode 100644 index 0000000..8a8dc33 --- /dev/null +++ b/userland/libc/stdio/vprintf.c @@ -0,0 +1,3 @@ +#include <stdio.h> + +int vprintf(const char *format, va_list ap) { return vdprintf(1, format, ap); } diff --git a/userland/libc/stdlib.h b/userland/libc/stdlib.h new file mode 100644 index 0000000..bba5d84 --- /dev/null +++ b/userland/libc/stdlib.h @@ -0,0 +1,17 @@ +#ifndef STDLIB_H +#define STDLIB_H +#include <stddef.h> +#include <limits.h> +#define RAND_MAX (UINT32_MAX) + +void *malloc(size_t s); +void *calloc(size_t nelem, size_t elsize); +void *realloc(void *ptr, size_t size); +void free(void *p); +char *getenv(const char *name); +int rand(void); +void srand(unsigned int seed); +unsigned long strtoul(const char *restrict str, + char **restrict endptr, int base); +int atoi(const char *str); +#endif diff --git a/userland/libc/stdlib/abort.c b/userland/libc/stdlib/abort.c new file mode 100644 index 0000000..7fd747e --- /dev/null +++ b/userland/libc/stdlib/abort.c @@ -0,0 +1,10 @@ +#include <assert.h> +#include <stdlib.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/abort.html +void abort(void) { + printf("aborting!!!!\n"); + assert(0); + for (;;) + ; +} diff --git a/userland/libc/stdlib/abs.c b/userland/libc/stdlib/abs.c new file mode 100644 index 0000000..1079beb --- /dev/null +++ b/userland/libc/stdlib/abs.c @@ -0,0 +1,3 @@ +#include <stdlib.h> + +int abs(int i) { return (i < 0) ? (-i) : (i); } diff --git a/userland/libc/stdlib/atexit.c b/userland/libc/stdlib/atexit.c new file mode 100644 index 0000000..0e401ff --- /dev/null +++ b/userland/libc/stdlib/atexit.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +int atexit(void (*func)(void)) { + //TODO + return 0; +} diff --git a/userland/libc/stdlib/atof.c b/userland/libc/stdlib/atof.c new file mode 100644 index 0000000..8524f8b --- /dev/null +++ b/userland/libc/stdlib/atof.c @@ -0,0 +1,5 @@ +#include <stdlib.h> + +double atof(const char *str) { + return strtod(str,(char **)NULL); +} diff --git a/userland/libc/stdlib/atoi.c b/userland/libc/stdlib/atoi.c new file mode 100644 index 0000000..2183306 --- /dev/null +++ b/userland/libc/stdlib/atoi.c @@ -0,0 +1,4 @@ +#include <stdlib.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +int atoi(const char *str) { return (int)strtol(str, (char **)NULL, 10); } diff --git a/userland/libc/stdlib/getenv.c b/userland/libc/stdlib/getenv.c new file mode 100644 index 0000000..9a6a4e5 --- /dev/null +++ b/userland/libc/stdlib/getenv.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +char *getenv(const char *name) { + // FIXME + return NULL; +} diff --git a/userland/libc/stdlib/mkstemp.c b/userland/libc/stdlib/mkstemp.c new file mode 100644 index 0000000..1ea8790 --- /dev/null +++ b/userland/libc/stdlib/mkstemp.c @@ -0,0 +1,14 @@ +#include <fcntl.h> +#include <stdlib.h> + +char rand_char(void) { return 'A' + (rand() % 10); } + +int mkstemp(char *template) { + // FIXME: Incomplete + const char *s = template; + for (; *template; template ++) { + if ('X' == *template) + *template = rand_char(); + } + return open(s, O_RDWR, O_CREAT); +} diff --git a/userland/libc/stdlib/qsort.c b/userland/libc/stdlib/qsort.c new file mode 100644 index 0000000..3f87db5 --- /dev/null +++ b/userland/libc/stdlib/qsort.c @@ -0,0 +1,29 @@ +#include <stdlib.h> +#include <string.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/qsort.html +void qsort(void *base, size_t nel, size_t width, + int (*compar)(const void *, const void *)) { + // If the nel argument has the value zero, the comparison function pointed to + // by compar shall not be called and no rearrangement shall take place. + if (0 == nel) + return; + + // AB + // Results in negative + // BA + // Results in positive + + // Using bubblesort + unsigned char *p = base; + for (size_t i = 1; i < nel; i++) { + for (size_t j = 0; j < nel; j++) { + if (compar((p + i * width), (p + j * width)) < 0) { + unsigned char tmp[width]; + memcpy(tmp, (p + i * width), width); + memcpy((p + i * width), (p + j * width), width); + memcpy((p + j * width), tmp, width); + } + } + } +} diff --git a/userland/libc/stdlib/rand.c b/userland/libc/stdlib/rand.c new file mode 100644 index 0000000..e186af7 --- /dev/null +++ b/userland/libc/stdlib/rand.c @@ -0,0 +1,17 @@ +#include <stdint.h> +#include <stdlib.h> + +uint32_t xorshift(uint32_t x) { + uint32_t f = x; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + return f + x; +} + +extern uint32_t __INTERNAL_RNG_STATE; +int rand(void) { + uint32_t x = xorshift(__INTERNAL_RNG_STATE); + __INTERNAL_RNG_STATE++; + return x; +} diff --git a/userland/libc/stdlib/srand.c b/userland/libc/stdlib/srand.c new file mode 100644 index 0000000..a35185a --- /dev/null +++ b/userland/libc/stdlib/srand.c @@ -0,0 +1,8 @@ +#include <stdint.h> +#include <stdlib.h> + +uint32_t __INTERNAL_RNG_STATE; +void srand(unsigned int seed) { + __INTERNAL_RNG_STATE = seed; + __INTERNAL_RNG_STATE = rand(); // rand() used the internal rng state +} diff --git a/userland/libc/stdlib/strtod.c b/userland/libc/stdlib/strtod.c new file mode 100644 index 0000000..2c83879 --- /dev/null +++ b/userland/libc/stdlib/strtod.c @@ -0,0 +1,70 @@ +#include <ctype.h> +#include <stdlib.h> +#include <assert.h> + +int ctoi(char c) { return c - '0'; } + +double strtod(const char *restrict nptr, char **restrict endptr) { + double r = 0; + // An initial, possibly empty, sequence of white-space characters (as + // specified by isspace()) + for (; isspace(*nptr); nptr++) + ; + + // A subject sequence interpreted as a floating-point constant or representing + // infinity or NaN + + { + // The expected form of the subject sequence is an optional '+' or '-' sign + int sign = 0; + int exp_sign = 0; + if ('+' == *nptr) { + sign = 0; + nptr++; + } else if ('-' == *nptr) { + sign = 1; + nptr++; + } + + // A non-empty sequence of decimal digits optionally containing a radix + // character + double exp = 0; + for (; isdigit(*nptr); nptr++) { + r *= 10; + r += ctoi(*nptr); + } + if ('.' == *nptr) { + double div = 10; + for (; isdigit(*nptr); nptr++) { + r += ctoi(*nptr) / div; + div *= 10; + } + } + r *= (sign) ? (-1) : (1); + + // then an optional exponent part consisting of the character 'e' or + // the character 'E' + if ('e' == tolower(*nptr)) { + // optionally followed by a '+' or '-' character + if ('+' == *nptr) { + exp_sign = 0; + nptr++; + } else if ('-' == *nptr) { + exp_sign = 1; + nptr++; + } + // and then followed by one or more decimal digits + for (; isdigit(*nptr); nptr++) { + exp *= 10; + exp += ctoi(*nptr); + } + exp *= (exp_sign) ? (-1) : (1); + } + assert(0 == exp); // TODO + } + + // A final string of one or more unrecognized characters, including the + // terminating NUL character of the input string + ; + return r; +} diff --git a/userland/libc/stdlib/strtol.c b/userland/libc/stdlib/strtol.c new file mode 100644 index 0000000..7aa7760 --- /dev/null +++ b/userland/libc/stdlib/strtol.c @@ -0,0 +1,52 @@ +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <assert.h> + +extern int errno; +extern int get_value(char c, long base); + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html +long strtol(const char *str, char **restrict endptr, int base) { + long ret_value = 0; + if (endptr) + *endptr = str; + // Ignore inital white-space sequence + for (; *str && isspace(*str); str++) + ; + if (!*str) + return ret_value; + + int sign = 0; + if ('-' == *str) { + // FIXME + sign = 1; + str++; + assert(0); + } else if ('+' == *str) { + str++; + } + + if (0 == base) { + // FIXME + assert(0); + } + + if (2 <= base && 36 >= base) { + for (; *str; str++) { + ret_value *= base; + int val = get_value(*str, base); + if (ret_value > LONG_MAX - val) { + errno = ERANGE; + return 0; + } + ret_value += val; + } + } else { + errno = EINVAL; + return 0; + } + if (endptr) + *endptr = str; + return ret_value; +} diff --git a/userland/libc/stdlib/strtold.c b/userland/libc/stdlib/strtold.c new file mode 100644 index 0000000..222464e --- /dev/null +++ b/userland/libc/stdlib/strtold.c @@ -0,0 +1,9 @@ +#include <assert.h> +#include <stdlib.h> + +long double strtold(const char *restrict nptr, char **restrict endptr) { + // TODO + // I will do this some other day + assert(NULL); + return 0; +} diff --git a/userland/libc/stdlib/strtoul.c b/userland/libc/stdlib/strtoul.c new file mode 100644 index 0000000..4d9a51d --- /dev/null +++ b/userland/libc/stdlib/strtoul.c @@ -0,0 +1,72 @@ +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <limits.h> + +extern int errno; +int get_value(char c, long base) { + int r; + if (c >= '0' && c <= '9') + r = c - '0'; + else if (c >= 'A' && c <= 'Z') + r = c - 'A'; + else if (c >= 'a' && c <= 'z') + r = c - 'a'; + else + return -1; + if (r >= base) + return -1; + return r; +} + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strtoul.html +unsigned long strtoul(const char *restrict str, char **restrict endptr, + int base) { + unsigned long ret_value = 0; + if (endptr) + *endptr = str; + // Ignore inital white-space sequence + for (; *str && isspace(*str); str++) + ; + if (!*str) + return ret_value; + + int sign = 0; + if ('-' == *str) { + // FIXME + sign = 1; + str++; + assert(0); + } else if ('+' == *str) { + str++; + } + + if (0 == base) { + // FIXME + assert(0); + } + + if (2 <= base && 36 >= base) { + for (; *str; str++) { + ret_value *= base; + int val = get_value(*str, base); + /* + if (-1 == val) { + errno = ERANGE; + return 0; + }*/ + if (ret_value > ULONG_MAX - val) { + errno = ERANGE; + return 0; + } + + ret_value += val; + } + } else { + errno = EINVAL; + return 0; + } + if (endptr) + *endptr = str; + return ret_value; +} diff --git a/userland/libc/stdlib/system.c b/userland/libc/stdlib/system.c new file mode 100644 index 0000000..d951c5c --- /dev/null +++ b/userland/libc/stdlib/system.c @@ -0,0 +1,17 @@ +#include <stdlib.h> + +int system(const char *command) { + if (!command) + return NULL; + int pid = fork(); + if (0 == pid) { + char *argv[2]; + argv[0] = "/sh"; + argv[1] = command; + execv("/sh", argv); + } + // FIXME: Use waitpid + int rc; + (void)wait(&rc); + return rc; +} diff --git a/userland/libc/string.h b/userland/libc/string.h new file mode 100644 index 0000000..f811dba --- /dev/null +++ b/userland/libc/string.h @@ -0,0 +1,17 @@ +#ifndef STRING_H +#define STRING_H +#include <stddef.h> +#include <stdint.h> + +char *strerror(int errnum); +void *memset(void *s, int c, size_t n); +void *memcpy(void *dest, const void *src, uint32_t n); +int strcmp(const char *s1, const char *s2); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *s); +size_t strnlen(const char *s, size_t maxlen); +int sscanf(const char *s, const char *restrict format, ...); +char *strrchr(const char *s, int c); +int strncmp(const char *s1, const char *s2, size_t n); +char *strncpy(char *s1, const char *s2, size_t n); +#endif diff --git a/userland/libc/string/memcmp.c b/userland/libc/string/memcmp.c new file mode 100644 index 0000000..01109b8 --- /dev/null +++ b/userland/libc/string/memcmp.c @@ -0,0 +1,11 @@ +#include <string.h> + +int memcmp(const void *s1, const void *s2, size_t n) { + int return_value = 0; + + for (uint32_t i = 0; i < n; i++) + if (((unsigned char *)(s1))[i] != ((unsigned char *)(s2))[i]) + return_value++; + + return return_value; +} diff --git a/userland/libc/string/memcpy.c b/userland/libc/string/memcpy.c new file mode 100644 index 0000000..e19dec9 --- /dev/null +++ b/userland/libc/string/memcpy.c @@ -0,0 +1,9 @@ +#include <string.h> + +void *memcpy(void *dest, const void *src, uint32_t n) { + unsigned char *d = dest; + const unsigned char *s = src; + for (; n; n--) + *d++ = *s++; + return dest; +} diff --git a/userland/libc/string/memmove.c b/userland/libc/string/memmove.c new file mode 100644 index 0000000..5fc49f7 --- /dev/null +++ b/userland/libc/string/memmove.c @@ -0,0 +1,14 @@ +#include <string.h> + +// copy bytes in memory with overlapping areas +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/memmove.html +void *memmove(void *s1, const void *s2, size_t n) { + // Copying takes place as if the n bytes from the object pointed to by s2 are + // first copied into a temporary array of n bytes that does not overlap the + // objects pointed to by s1 and s2, and then the n bytes from the temporary + // array are copied into the object pointed to by s1. + unsigned char tmp[n]; + memcpy(tmp, s2, n); + memcpy(s1, tmp, n); + return s1; +} diff --git a/userland/libc/string/sscanf.c b/userland/libc/string/sscanf.c new file mode 100644 index 0000000..28e1ce1 --- /dev/null +++ b/userland/libc/string/sscanf.c @@ -0,0 +1,193 @@ +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +extern int errno; +extern int get_value(char c, long base); + +long ftnum(FILE *stream, int base, int *error) { + char c; + long ret_value = 0; + *error = 0; + // Ignore inital white-space sequence + for (;;) { + if (EOF == (c = fgetc(stream))) { + *error = 1; + return 0; + } + + if (!isspace(c)) { + ungetc(c, stream); + break; + } + } + if (c == '\0') { + *error = 1; + return 0; + } + if (!isdigit(c)) { + *error = 1; + return 0; + } + if (!(2 <= base && 36 >= base)) { + *error = 1; + return 0; + } + for (;;) { + if (EOF == (c = fgetc(stream))) + break; + if (c == '\0') { + ungetc(c, stream); + break; + } + int val = get_value(c, base); + if (-1 == val) { + ungetc(c, stream); + break; + } + if (ret_value * base > LONG_MAX - val) { + ungetc(c, stream); + errno = ERANGE; + *error = 1; + return 0; + } + ret_value *= base; + ret_value += val; + } + return ret_value; +} + +int vfscanf(FILE *stream, const char *format, va_list ap) { + int rc = 0; // Upon successful completion, these functions shall return the + // number of successfully matched and assigned input items + int cont = 0; + int suppress = 0; + for (; *format; format++) { + if (*format != '%' && !cont) { + char c; + if (isspace(*format)) + continue; + if (EOF == (c = fgetc(stream))) { + break; + } + if (*format == c) // TODO: Make sure this is the correct behaviour + continue; + // TODO: Make sure this is the correct behaviour + errno = EINVAL; + assert(0); + break; + } + + if (*format == '%' && !cont) { + cont = 1; + continue; + } + + int is_long = 0; + switch (*format) { + case 'l': + is_long++; + assert(is_long < 3); + cont = 1; + break; + case 'i': // Matches an optionally signed integer, whose format is the same + // as expected for the subject sequence of strtol() with 0 for the + // base argument. + case 'd': { + // Matches an optionally signed decimal integer, whose format is the + // same as expected for the subject sequence of strtol() with the value + // 10 for the base argument. In the absence of a size modifier, the + // application shall ensure that the corresponding argument is a pointer + // to int. + int err = 0; + int result = ftnum(stream, 10, &err); + if (err) { + cont = 0; + break; + } + if (!suppress) { + if (2 == is_long) { + *((long long *)va_arg(ap, long long *)) = result; + } else if (1 == is_long) { + *((long *)va_arg(ap, long *)) = result; + } else { + *((int *)va_arg(ap, int *)) = result; + } + rc++; + } + assert(0 == err); + cont = 0; + break; + } + case 'c': { + char result = fgetc(stream); + if (!suppress) { + *((char *)va_arg(ap, char *)) = result; + rc++; + } + cont = 0; + break; + } + case '*': // Assignment suppression + suppress = 1; + cont = 1; + break; + default: + printf("vfscanf: Got %c but not supported.\n", *format); + assert(0); + break; + } + if (!cont) { + suppress = 0; + } + } + return rc; +} + +struct sscanf_cookie { + const char *s; +}; + +size_t sscanf_read(FILE *f, unsigned char *s, size_t l) { + struct sscanf_cookie *c = f->cookie; + if (!*(c->s)) { + return 0; + } + size_t r = 0; + for (; l && *(c->s); l--, c->s += 1) { + *s = *(c->s); + s++; + r++; + } + if (!(*(c->s))) + f->is_eof = 1; + /* + memcpy(s, c->s, l); + c->s += l;*/ + return r; +} + +int vsscanf(const char *s, const char *restrict format, va_list ap) { + struct sscanf_cookie c = {.s = s}; + FILE f = { + .read = sscanf_read, + .cookie = &c, + .has_buffered_char = 0, + .is_eof = 0, + .has_error = 0, + .offset_in_file = 0, + }; + return vfscanf(&f, format, ap); +} + +int sscanf(const char *s, const char *restrict format, ...) { + va_list ap; + va_start(ap, format); + int rc = vsscanf(s, format, ap); + va_end(ap); + return rc; +} diff --git a/userland/libc/string/strcasecmp.c b/userland/libc/string/strcasecmp.c new file mode 100644 index 0000000..eed337b --- /dev/null +++ b/userland/libc/string/strcasecmp.c @@ -0,0 +1,28 @@ +#include <strings.h> + +int strcasecmp(const char *s1, const char *s2) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; (*s1 || *s2);) { + if (tolower(*s1) != tolower(*s2)) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strcat.c b/userland/libc/string/strcat.c new file mode 100644 index 0000000..c430698 --- /dev/null +++ b/userland/libc/string/strcat.c @@ -0,0 +1,13 @@ +#include <string.h> + +char *strcat(char *s1, const char *s2) { + strcpy(s1 + strlen(s1), s2); + return s1; + /* +char *r = s1; +for (; *s1; s1++) +; +for (; *s2; s2++, s1++) +*s1 = *s2; +return r;*/ +} diff --git a/userland/libc/string/strchr.c b/userland/libc/string/strchr.c new file mode 100644 index 0000000..1995547 --- /dev/null +++ b/userland/libc/string/strchr.c @@ -0,0 +1,11 @@ +#include <string.h> + +char *strchr(const char *s, int c) { + for (; *s; s++) { + if (*s == (char)c) + return (char*)s; + } + if ((char)c == '\0') + return (char *)s; + return NULL; +} diff --git a/userland/libc/string/strcmp.c b/userland/libc/string/strcmp.c new file mode 100644 index 0000000..368b8fb --- /dev/null +++ b/userland/libc/string/strcmp.c @@ -0,0 +1,29 @@ +#include <string.h> + +// https://pubs.opengroup.org/onlinepubs/9699919799/ +int strcmp(const char *s1, const char *s2) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; *s1 || *s2;) { + if (*s1 != *s2) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strcpy.c b/userland/libc/string/strcpy.c new file mode 100644 index 0000000..9023fd1 --- /dev/null +++ b/userland/libc/string/strcpy.c @@ -0,0 +1,7 @@ +#include <string.h> + +char *strcpy(char *dest, const char *src) { + for (; (*dest = *src); dest++, src++) + ; + return dest; +} diff --git a/userland/libc/string/strcspn.c b/userland/libc/string/strcspn.c new file mode 100644 index 0000000..2ad38d5 --- /dev/null +++ b/userland/libc/string/strcspn.c @@ -0,0 +1,14 @@ +#include <string.h> + +size_t strcspn(const char *s1, const char *s2) { + size_t r = 0; + for (; *s1; s1++) { + for (const char *t = s2; *t; t++) { + if (*s1 == *s2) { + r++; + break; + } + } + } + return r; +} diff --git a/userland/libc/string/strdup.c b/userland/libc/string/strdup.c new file mode 100644 index 0000000..9e22f94 --- /dev/null +++ b/userland/libc/string/strdup.c @@ -0,0 +1,15 @@ +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +// The strdup() function shall return a pointer to a new string, which is a +// duplicate of the string pointed to by s. The returned pointer can be passed +// to free(). A null pointer is returned if the new string cannot be created. +char *strdup(const char *s) { + size_t l = strlen(s); + char *r = malloc(l + 1); + if (!r) + return NULL; + strcpy(r, s); + return r; +} diff --git a/userland/libc/string/strlcpy.c b/userland/libc/string/strlcpy.c new file mode 100644 index 0000000..a2d3dd9 --- /dev/null +++ b/userland/libc/string/strlcpy.c @@ -0,0 +1,20 @@ +#include <string.h> + +// Copy string s2 to buffer s1 of size n. At most n-1 +// chars will be copied. Always NUL terminates (unless n == 0). +// Returns strlen(s2); if retval >= n, truncation occurred. +size_t *strlcpy(char *s1, const char *s2, size_t n) { + size_t tmp_n = n; + const char *os2 = s2; + for (; tmp_n; tmp_n--) { + if ((*s1++ = *s2++) == '\0') + break; + } + if (tmp_n == 0) { + if (n != 0) + *s1 = '\0'; /* NUL-terminate s1 */ + while (*s2++) + ; + } + return s2 - os2 - 1; +} diff --git a/userland/libc/string/strlen.c b/userland/libc/string/strlen.c new file mode 100644 index 0000000..8e3e77a --- /dev/null +++ b/userland/libc/string/strlen.c @@ -0,0 +1,8 @@ +#include <string.h> + +size_t strlen(const char *s) { + const char *d = s; + for (; *s; s++) + ; + return s - d; +} diff --git a/userland/libc/string/strncasecmp.c b/userland/libc/string/strncasecmp.c new file mode 100644 index 0000000..9ce8c04 --- /dev/null +++ b/userland/libc/string/strncasecmp.c @@ -0,0 +1,29 @@ +#include <strings.h> +#include <stddef.h> + +int strncasecmp(const char *s1, const char *s2, size_t n) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; (*s1 || *s2) && n > 0; n--) { + if (tolower(*s1) != tolower(*s2)) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strncmp.c b/userland/libc/string/strncmp.c new file mode 100644 index 0000000..fd46189 --- /dev/null +++ b/userland/libc/string/strncmp.c @@ -0,0 +1,28 @@ +#include <string.h> + +int strncmp(const char *s1, const char *s2, size_t n) { + // The strcmp() function shall compare the string pointed to by s1 + // to the string pointed to by s2. + int l1, l2, rc; + l1 = l2 = rc = 0; + for (; (*s1 || *s2) && n > 0; n--) { + if (*s1 != *s2) + rc++; + if (*s1) { + l1++; + s1++; + } + if (*s2) { + l2++; + s2++; + } + } + + // Upon completion, strcmp() shall return an integer greater than, + // equal to, or less than 0, if the string pointed to by s1 is + // greater than, equal to, or less than the string pointed to by + // s2, respectively. + if (l2 > l1) + return -rc; + return rc; +} diff --git a/userland/libc/string/strncpy.c b/userland/libc/string/strncpy.c new file mode 100644 index 0000000..0e88c63 --- /dev/null +++ b/userland/libc/string/strncpy.c @@ -0,0 +1,13 @@ +#include <string.h> + +char *strncpy(char *s1, const char *s2, size_t n) { + char *rc = s1; + for (; n > 0; s1++, s2++, n--) { + *s1 = *s2; + if (!*s2) + break; + } + for (; n > 0; n--,s1++) + *s1 = '\0'; + return rc; +} diff --git a/userland/libc/string/strndup.c b/userland/libc/string/strndup.c new file mode 100644 index 0000000..ffb2088 --- /dev/null +++ b/userland/libc/string/strndup.c @@ -0,0 +1,22 @@ +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +// The strndup() function shall be equivalent to the strdup() function, +// duplicating the provided s in a new block of memory allocated as if +// by using malloc(), with the exception being that strndup() copies at +// most size plus one bytes into the newly allocated memory, terminating +// the new string with a NUL character. If the length of s is larger +// than size, only size bytes shall be duplicated. If size is larger +// than the length of s, all bytes in s shall be copied into the new +// memory buffer, including the terminating NUL character. The newly +// created string shall always be properly terminated. +char *strndup(const char *s, size_t size) { + size_t l = strlen(s); + size_t real_l = min(l, size); + char *r = malloc(real_l + 1); + if (!r) + return NULL; + strlcpy(r, s, real_l); + return r; +} diff --git a/userland/libc/string/strnlen.c b/userland/libc/string/strnlen.c new file mode 100644 index 0000000..86df42e --- /dev/null +++ b/userland/libc/string/strnlen.c @@ -0,0 +1,9 @@ +#include <string.h> + +size_t strnlen(const char *s, size_t maxlen) { + size_t i; + for (i = 0; i < maxlen; i++) + if (s[i] == 0) + break; + return i; +} diff --git a/userland/libc/string/strpbrk.c b/userland/libc/string/strpbrk.c new file mode 100644 index 0000000..fb16b0c --- /dev/null +++ b/userland/libc/string/strpbrk.c @@ -0,0 +1,12 @@ +#include <string.h> + +char *strpbrk(const char *s1, const char *s2) { + for (; *s1; s1++) { + for (const char *t = s2; *t; t++) { + if (*s1 == *t) { + return s1; + } + } + } + return NULL; +} diff --git a/userland/libc/string/strrchr.c b/userland/libc/string/strrchr.c new file mode 100644 index 0000000..a44199a --- /dev/null +++ b/userland/libc/string/strrchr.c @@ -0,0 +1,12 @@ +#include <string.h> + +char *strrchr(const char *s, int c) { + char *last = NULL; + for (; *s; s++) { + if (*s == (char)c) + last = (char *)s; + } + if ((char)c == '\0') + last = (char*)s; + return last; +} diff --git a/userland/libc/string/strspn.c b/userland/libc/string/strspn.c new file mode 100644 index 0000000..2a7d3ae --- /dev/null +++ b/userland/libc/string/strspn.c @@ -0,0 +1,18 @@ +#include <string.h> + +size_t strspn(const char *s1, const char *s2) { + size_t r = 0; + for (; *s1; s1++) { + int e = 0; + for (const char *t = s2; *t; t++) { + if (*s1 == *t) { + e = 1; + break; + } + } + if (!e) + break; + r++; + } + return r; +} diff --git a/userland/libc/string/strstr.c b/userland/libc/string/strstr.c new file mode 100644 index 0000000..20b9dc2 --- /dev/null +++ b/userland/libc/string/strstr.c @@ -0,0 +1,21 @@ +#include <string.h> + +char *strstr(const char *s1, const char *s2) { + // If s2 points to a string with zero length, the function shall return s1. + if ('\0' == *s2) + return s1; + for (; *s1; s1++) { + const char *t1 = s1; + const char *t2 = s2; + int is_dif = 0; + for (; *t2 && *t1; t1++, t2++) { + if (*t2 != *t1) { + is_dif = 1; + break; + } + } + if (!is_dif) + return s1; + } + return NULL; +} diff --git a/userland/libc/string/strtok.c b/userland/libc/string/strtok.c new file mode 100644 index 0000000..7b8d0e3 --- /dev/null +++ b/userland/libc/string/strtok.c @@ -0,0 +1,26 @@ +#include <string.h> + +char *strtok_s; + +char *strtok(char *restrict s, const char *restrict sep) { + if (s) { + strtok_s = s; + return strtok(NULL, sep); + } + if(!strtok_s) + return NULL; + char *e = strpbrk(strtok_s, sep); + if (!e) { + char *r = strtok_s; + strtok_s = NULL; + return r; + } + *e = '\0'; + e--; + for (; *sep; sep++) + e++; + e++; + char *r = strtok_s; + strtok_s = e; + return r; +} diff --git a/userland/libc/strings.h b/userland/libc/strings.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/strings.h diff --git a/userland/libc/sys/mman.h b/userland/libc/sys/mman.h new file mode 100644 index 0000000..e3ff734 --- /dev/null +++ b/userland/libc/sys/mman.h @@ -0,0 +1,8 @@ +#ifndef MMAP_H +#define MMAP_H +#include <stdint.h> +#include <stddef.h> + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset); +#endif diff --git a/userland/libc/sys/mman/mmap.c b/userland/libc/sys/mman/mmap.c new file mode 100644 index 0000000..b9ad3a2 --- /dev/null +++ b/userland/libc/sys/mman/mmap.c @@ -0,0 +1,19 @@ +#include <syscall.h> +#include <errno.h> +#include <sys/mman.h> + +extern int errno; + +void *mmap(void *addr, size_t length, int prot, int flags, int fd, + size_t offset) { + SYS_MMAP_PARAMS args = { + .addr = addr, + .length = length, + .prot = prot, + .flags = flags, + .fd = fd, + .offset = offset, + }; +// return (void*)syscall(SYS_MMAP, &args, 0, 0, 0, 0); + RC_ERRNO(syscall(SYS_MMAP, &args, 0, 0, 0, 0)); +} diff --git a/userland/libc/sys/stat.h b/userland/libc/sys/stat.h new file mode 100644 index 0000000..2fe6cdc --- /dev/null +++ b/userland/libc/sys/stat.h @@ -0,0 +1,30 @@ +#ifndef STAT_H +#define STAT_H +#include <sys/types.h> +#include <time.h> + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atime; // Last data access timestamp. + struct timespec st_mtime; // Last data modification timestamp. + struct timespec st_ctime; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; +int stat(const char *path, struct stat *buf); +#endif diff --git a/userland/libc/sys/stat/mkdir.c b/userland/libc/sys/stat/mkdir.c new file mode 100644 index 0000000..c057fa7 --- /dev/null +++ b/userland/libc/sys/stat/mkdir.c @@ -0,0 +1,9 @@ +#include <sys/stat.h> +#include <assert.h> + +int mkdir(const char *path, mode_t mode) { + (void)path; + (void)mode; + assert(0); // TODO: Implement + return 0; +} diff --git a/userland/libc/sys/stat/stat.c b/userland/libc/sys/stat/stat.c new file mode 100644 index 0000000..e37223e --- /dev/null +++ b/userland/libc/sys/stat/stat.c @@ -0,0 +1,13 @@ +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <sys/stat.h> +#include <syscall.h> + +int stat(const char *path, struct stat *buf) { + SYS_STAT_PARAMS args = { + .pathname = path, + .statbuf = buf, + }; + RC_ERRNO(syscall(SYS_STAT, &args, 0, 0, 0, 0)); +} diff --git a/userland/libc/sys/time/gettimeofday.c b/userland/libc/sys/time/gettimeofday.c new file mode 100644 index 0000000..e172cf2 --- /dev/null +++ b/userland/libc/sys/time/gettimeofday.c @@ -0,0 +1,5 @@ +#include <sys/time.h> +#include <time.h> + +static int return_tod =0; +int gettimeofday(struct timeval *tp, void *tzp) {return return_tod++;} diff --git a/userland/libc/sys/types.h b/userland/libc/sys/types.h new file mode 100644 index 0000000..ffcf281 --- /dev/null +++ b/userland/libc/sys/types.h @@ -0,0 +1,27 @@ +#ifndef TYPES_H +#define TYPES_H +typedef unsigned int ino_t; + +typedef int mode_t; + +typedef int nlink_t; +typedef int uid_t; +typedef int gid_t; +typedef int id_t; + +typedef int blkcnt_t; +typedef int off_t; + +typedef int dev_t; +typedef unsigned int fsblkcnt_t; +typedef unsigned int fsfilcnt_t; +typedef unsigned int ino_t; +//typedef unsigned int size_t; + +typedef int blksize_t; +typedef int pid_t; +typedef int ssize_t; + +//typedef int clock_t; +typedef int time_t; +#endif diff --git a/userland/libc/syscall.h b/userland/libc/syscall.h new file mode 100644 index 0000000..952492f --- /dev/null +++ b/userland/libc/syscall.h @@ -0,0 +1,149 @@ +#ifndef SYSCALL_H +#define SYSCALL_H +#include "socket.h" +#include <stddef.h> +#include <stdint.h> + +#define SYS_OPEN 0 +#define SYS_READ 1 +#define SYS_WRITE 2 +#define SYS_PREAD 3 +#define SYS_PWRITE 4 +#define SYS_FORK 5 +#define SYS_EXEC 6 +#define SYS_GETPID 7 +#define SYS_EXIT 8 +#define SYS_WAIT 9 +#define SYS_BRK 10 +#define SYS_SBRK 11 +#define SYS_PIPE 12 +#define SYS_DUP2 13 +#define SYS_CLOSE 14 +#define SYS_OPENPTY 15 +#define SYS_POLL 16 +#define SYS_MMAP 17 +#define SYS_ACCEPT 18 +#define SYS_BIND 19 +#define SYS_SOCKET 20 +#define SYS_SHM_OPEN 21 +#define SYS_FTRUNCATE 22 +#define SYS_STAT 23 +#define SYS_MSLEEP 24 +#define SYS_UPTIME 25 + +int syscall(uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, + uint32_t esi, uint32_t edi); +int s_syscall(int sys); + +extern int errno; +#define RC_ERRNO(_rc) \ + { \ + int c = _rc; \ + if (c < 0) { \ + errno = -(c); \ + return -1; \ + } \ + return c; \ + } + +typedef int mode_t; + +typedef struct SYS_OPEN_PARAMS { + char *file; + int flags; + int mode; +} __attribute__((packed)) SYS_OPEN_PARAMS; + +typedef struct SYS_PREAD_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PREAD_PARAMS; + +typedef struct SYS_READ_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_READ_PARAMS; + +typedef struct SYS_PWRITE_PARAMS { + int fd; + void *buf; + size_t count; + size_t offset; +} __attribute__((packed)) SYS_PWRITE_PARAMS; + +typedef struct SYS_WRITE_PARAMS { + int fd; + void *buf; + size_t count; +} __attribute__((packed)) SYS_WRITE_PARAMS; + +typedef struct SYS_EXEC_PARAMS { + char *path; + char **argv; +} __attribute__((packed)) SYS_EXEC_PARAMS; + +typedef struct SYS_DUP2_PARAMS { + int org_fd; + int new_fd; +} __attribute__((packed)) SYS_DUP2_PARAMS; + +typedef struct SYS_OPENPTY_PARAMS { + int *amaster; + int *aslave; + char *name; + /*const struct termios*/ void *termp; + /*const struct winsize*/ void *winp; +} __attribute__((packed)) SYS_OPENPTY_PARAMS; + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +typedef struct SYS_FTRUNCATE_PARAMS { + int fildes; + uint64_t length; +} __attribute__((packed)) SYS_FTRUNCATE_PARAMS; + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; +#endif diff --git a/userland/libc/time.h b/userland/libc/time.h new file mode 100644 index 0000000..771e430 --- /dev/null +++ b/userland/libc/time.h @@ -0,0 +1,20 @@ +#include <sys/types.h> + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long __tm_gmtoff; + const char *__tm_zone; +}; + +struct timespec { + time_t tv_sec; // Seconds. + long tv_nsec; // Nanoseconds. +}; diff --git a/userland/libc/time/clock_gettime.c b/userland/libc/time/clock_gettime.c new file mode 100644 index 0000000..15f0cb7 --- /dev/null +++ b/userland/libc/time/clock_gettime.c @@ -0,0 +1,14 @@ +#include <syscall.h> +#include <time.h> + +int clock_gettime(clockid_t clock_id, struct timespec *tp) { + tp->tv_sec = 0; + tp->tv_nsec = 0; + return 0; + /* +SYS_CLOCK_GETTIME_PARAMS args = { +.clk = clock_id, +.ts = tp, +}; +return syscall(SYS_CLOCK_GETTIME, &args);*/ +} diff --git a/userland/libc/time/ctime_r.c b/userland/libc/time/ctime_r.c new file mode 100644 index 0000000..66e6416 --- /dev/null +++ b/userland/libc/time/ctime_r.c @@ -0,0 +1,13 @@ +#include <string.h> +#include <time.h> + +// TODO: Implement this + +// Time, formatting and parsing are some of the most annoying parts of +// programming. Lets just hope this function is not important +char *ctime_r(const time_t *clock, char *buf) { + (void)clock; + size_t l = strlen(buf); + memset(buf, '0', l); + return buf; +} diff --git a/userland/libc/time/gmtime.c b/userland/libc/time/gmtime.c new file mode 100644 index 0000000..44e0ff3 --- /dev/null +++ b/userland/libc/time/gmtime.c @@ -0,0 +1,21 @@ +#include <time.h> + +struct tm gmtime_r = { + .tm_sec = 0, + .tm_min = 0, + .tm_hour = 0, + .tm_mday = 0, + .tm_mon = 0, + .tm_year = 0, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst = 0, + .__tm_gmtoff = 0, + .__tm_zone = 0, +}; + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/gmtime.html +struct tm *gmtime(const time_t *timer) { + // TODO: Implement + return &gmtime_r; +} diff --git a/userland/libc/time/localtime.c b/userland/libc/time/localtime.c new file mode 100644 index 0000000..40ca351 --- /dev/null +++ b/userland/libc/time/localtime.c @@ -0,0 +1,21 @@ +#include <time.h> + + struct tm localtime_r = { + .tm_sec = 0, + .tm_min = 0, + .tm_hour = 0, + .tm_mday = 0, + .tm_mon = 0, + .tm_year = 0, + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst = 0, + .__tm_gmtoff = 0, + .__tm_zone = 0, + }; + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/localtime.html +struct tm *localtime(const time_t *timer) { + // TODO: Implement + return &localtime_r; +} diff --git a/userland/libc/time/strftime.c b/userland/libc/time/strftime.c new file mode 100644 index 0000000..30a080d --- /dev/null +++ b/userland/libc/time/strftime.c @@ -0,0 +1,7 @@ +#include <time.h> +#include <stddef.h> + +size_t strftime(char *restrict s, size_t maxsize, + const char *restrict format, const struct tm *restrict timeptr) { + return 0; +} diff --git a/userland/libc/time/time.c b/userland/libc/time/time.c new file mode 100644 index 0000000..9931b71 --- /dev/null +++ b/userland/libc/time/time.c @@ -0,0 +1,9 @@ +#include <time.h> + +time_t time(time_t *tloc) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + if (tloc) + *tloc = ts.tv_sec; + return ts.tv_sec; +} diff --git a/userland/libc/ubsan.c b/userland/libc/ubsan.c new file mode 100644 index 0000000..9ac9879 --- /dev/null +++ b/userland/libc/ubsan.c @@ -0,0 +1,49 @@ +#include <stdio.h> +#include <ubsan.h> + +void ubsan_log(const char *cause, struct source_location source) { + printf("UBSAN\n"); + printf("%s: %s : %d\n", cause, source.file_name, source.line); + for (;;) + ; +} + +void __ubsan_handle_shift_out_of_bounds(struct ShiftOutOfBoundsData *data, + unsigned long lhs, unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_shift_out_of_bounds", data->location); +} + +void __ubsan_handle_add_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_add_overflow", data->location); +} + +void __ubsan_handle_sub_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_sub_overflow", data->location); +} + +void __ubsan_handle_negate_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_negate_overflow", data->location); +} + +void __ubsan_handle_mul_overflow(struct OverflowData *data, unsigned long lhs, + unsigned long rhs) { + (void)lhs; + (void)rhs; + ubsan_log("handle_mul_overflow", data->location); +} + +void __ubsan_handle_out_of_bounds(struct OutOfBoundsData *data, void *index) { + (void)index; + ubsan_log("handle_out_of_bounds", data->location); +} diff --git a/userland/libc/ubsan.h b/userland/libc/ubsan.h new file mode 100644 index 0000000..dac5407 --- /dev/null +++ b/userland/libc/ubsan.h @@ -0,0 +1,79 @@ +#include <stdint.h> + +enum { type_kind_int = 0, type_kind_float = 1, type_unknown = 0xffff }; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct source_location { + const char *file_name; + union { + unsigned long reported; + struct { + uint32_t line; + uint32_t column; + }; + }; +}; + +struct OverflowData { + struct source_location location; + struct type_descriptor *type; +}; + +struct type_mismatch_data { + struct source_location location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_v1 { + struct source_location location; + struct type_descriptor *type; + unsigned char log_alignment; + unsigned char type_check_kind; +}; + +struct type_mismatch_data_common { + struct source_location *location; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct nonnull_arg_data { + struct source_location location; + struct source_location attr_location; + int arg_index; +}; + +struct OutOfBoundsData { + struct source_location location; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct ShiftOutOfBoundsData { + struct source_location location; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct unreachable_data { + struct source_location location; +}; + +struct invalid_value_data { + struct source_location location; + struct type_descriptor *type; +}; + +struct alignment_assumption_data { + struct source_location location; + struct source_location assumption_location; + struct type_descriptor *type; +}; diff --git a/userland/libc/unistd.h b/userland/libc/unistd.h new file mode 100644 index 0000000..b1e3434 --- /dev/null +++ b/userland/libc/unistd.h @@ -0,0 +1,14 @@ +#ifndef UNISTD_H +#define UNISTD_H +#include <stddef.h> + +extern int opterr, optind, optopt; +extern char *optarg; + +int close(int fildes); +int ftruncate(int fildes, size_t length); +int execv(char *path, char **argv); +int pipe(int fd[2]); +int dup2(int org_fd, int new_fd); +int getopt(int argc, char * const argv[], const char *optstring); +#endif diff --git a/userland/libc/unistd/_exit.c b/userland/libc/unistd/_exit.c new file mode 100644 index 0000000..c6d64be --- /dev/null +++ b/userland/libc/unistd/_exit.c @@ -0,0 +1,8 @@ +#include <syscall.h> +#include <unistd.h> + +// FIXME: Technically exit and _exit are different but this +// stackoverflow answer says that it does not usually matter. So lets +// hope that is the case. +// https://stackoverflow.com/a/5423108 +void _exit(int status) { syscall(SYS_EXIT, (void *)status, 0, 0, 0, 0); } diff --git a/userland/libc/unistd/execvp.c b/userland/libc/unistd/execvp.c new file mode 100644 index 0000000..573e822 --- /dev/null +++ b/userland/libc/unistd/execvp.c @@ -0,0 +1,8 @@ +#include <unistd.h> +#include <syscall.h> + +// FIXME: Path resolution +int execvp(const char *file, char *const argv[]) { + struct SYS_EXEC_PARAMS args = {.path = file, .argv = argv}; + return syscall(SYS_EXEC, &args, 0, 0, 0, 0); +} diff --git a/userland/libc/unistd/getopt.c b/userland/libc/unistd/getopt.c new file mode 100644 index 0000000..a026b59 --- /dev/null +++ b/userland/libc/unistd/getopt.c @@ -0,0 +1,14 @@ +#include <assert.h> +#include <unistd.h> + +int opterr, optind, optopt; +char *optarg; + +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html +int getopt(int argc, char *const argv[], const char *optstring) { + // TODO + optind = 1; + optarg = NULL; + // assert(0); + return -1; +} diff --git a/userland/libc/unistd/getpid.c b/userland/libc/unistd/getpid.c new file mode 100644 index 0000000..8aeef10 --- /dev/null +++ b/userland/libc/unistd/getpid.c @@ -0,0 +1,7 @@ +#include <unistd.h> +#include <syscall.h> +#include <sys/types.h> + +pid_t getpid(void) { + return s_syscall(SYS_GETPID); +} diff --git a/userland/libc/unistd/msleep.c b/userland/libc/unistd/msleep.c new file mode 100644 index 0000000..0b016c6 --- /dev/null +++ b/userland/libc/unistd/msleep.c @@ -0,0 +1,6 @@ +// Not standard, but it feels like it should be. +#include <syscall.h> +#include <unistd.h> +#include <stdint.h> + +void msleep(uint32_t ms) { syscall(SYS_MSLEEP, (void *)ms, 0, 0, 0, 0); } diff --git a/userland/libc/unistd/unlink.c b/userland/libc/unistd/unlink.c new file mode 100644 index 0000000..ccac0df --- /dev/null +++ b/userland/libc/unistd/unlink.c @@ -0,0 +1,7 @@ +#include <unistd.h> + +int unlink(const char *path) { + // TODO + printf("TODO: Implement unlink"); + return 0; +} diff --git a/userland/libc/unistd/uptime.c b/userland/libc/unistd/uptime.c new file mode 100644 index 0000000..090a0e5 --- /dev/null +++ b/userland/libc/unistd/uptime.c @@ -0,0 +1,6 @@ +// Not standard, but it feels like it should be. +#include <stdint.h> +#include <syscall.h> +#include <unistd.h> + +uint32_t uptime(void) { return syscall(SYS_UPTIME, 0, 0, 0, 0, 0); } diff --git a/userland/libc/wchar.h b/userland/libc/wchar.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/wchar.h diff --git a/userland/libc/wctype.h b/userland/libc/wctype.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/userland/libc/wctype.h diff --git a/userland/libgui/Makefile b/userland/libgui/Makefile new file mode 100644 index 0000000..5a895c4 --- /dev/null +++ b/userland/libgui/Makefile @@ -0,0 +1,17 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +AR="/home/anton/prj/osdev/sysroot/bin/i686-sb-ar" +#CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -nostdlib -static -Wno-undef -fsanitize=shift,signed-integer-overflow,bounds +CFLAGS = -O2 -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -nostdlib -static -Wno-undef +BINS=libgui.a +all: $(BINS) +LIBS=-L../libc -lc -L../json -ljson -lgcc +OBJ=libgui.o + +libgui.o: libgui.c + $(CC) $(CFLAGS) -c libgui.c -I../libc/ -I../json/ $(LIBS) + +libgui.a: $(OBJ) + $(AR) rcs libgui.a $^ + +clean: + rm $(OBJ) $(BINS) diff --git a/userland/libgui/font.h b/userland/libgui/font.h new file mode 100644 index 0000000..763b438 --- /dev/null +++ b/userland/libgui/font.h @@ -0,0 +1,3 @@ +#ifndef FONT_H +#define FONT_H +#endif diff --git a/userland/libgui/libgui.c b/userland/libgui/libgui.c new file mode 100644 index 0000000..5f5526d --- /dev/null +++ b/userland/libgui/libgui.c @@ -0,0 +1,290 @@ +#include "libgui.h" +#include "font.h" +#include <assert.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#define place_pixel_pos(_p, _pos) \ + { *(uint32_t *)(w->bitmap_ptr + _pos) = _p; } + +static const unsigned char font8x8_basic[128][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + {0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + {0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + {0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + {0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + {0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + {0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + {0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + {0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + {0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + {0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + {0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + {0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + {0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + {0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + {0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + {0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + {0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + {0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + {0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + {0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + {0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + {0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + {0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + {0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + {0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + {0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + {0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + {0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + {0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + {0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + {0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + {0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + {0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + {0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + {0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + {0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + {0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + {0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + {0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + {0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + {0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + {0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + {0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + {0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + {0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + {0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + {0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + {0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + {0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + {0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + {0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + {0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + {0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + {0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + {0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + {0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + {0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + {0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + {0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + {0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + {0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + {0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + {0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + {0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + {0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + {0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + {0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + {0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + {0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + {0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + {0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + {0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + {0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; + +#define pokeb(S, O, V) (*(unsigned char *)((S) + (O)) = (V)) + +// Very temporary +char *random_string(void) { + int fd = open("/dev/urandom", O_RDONLY, 0); + char *r = malloc(sizeof(char[10])); + for (int i = 0; i < 10 - 1; i++) { + char c; + read(fd, &c, 1); + r[i] = 'a' + (c & 0xF); + } + close(fd); + r[9] = '\0'; + printf("r: %s\n", r); + return r; +} + +int get_bitmap_value(const unsigned char bitmap[], int i) { + int array_index = i / 8; + int byte_index = i % 8; + int rc = (bitmap[array_index] >> byte_index) & 0x1; + return rc; +} + +void GUI_OverwriteFont(GUI_Window *w, uint32_t px, uint32_t py, + const uint32_t color) { + int sx, sy; + sx = 8; + sy = 8; + int x, y; + x = px; + y = py; + if (px + sx > w->sx) + return; + if (py + sy > w->sy) + return; + for (int i = 0; i < sx * sy; i++) { + int pos = x + y * w->sx; + place_pixel_pos(color, pos); + x++; + if (x >= sx + px) { + y++; + x = px; + } + if (y > py + sy) + break; + } +} + +void GUI_DrawFont(GUI_Window *w, uint32_t px, uint32_t py, const uint32_t c) { + int sx, sy; + sx = 8; + sy = 8; + int x, y; + x = px; + y = py; + if (px + sx > w->sx) + return; + if (py + sy > w->sy) + return; + const unsigned char *bitmap = font8x8_basic[c]; + for (int i = 0; i < sx * sy; i++) { + int pos = x + y * w->sx; + if (get_bitmap_value(bitmap, i)) { + place_pixel_pos(0xFFFFFF, pos); + } else { + place_pixel_pos(0x0, pos); + } + x++; + if (x >= sx + px) { + y++; + x = px; + } + if (y > py + sy) + break; + } +} + +typedef struct { + uint16_t px; + uint16_t py; + uint16_t sx; + uint16_t sy; + uint8_t name_len; +} WS_EVENT_CREATE; + +void GUI_ClearScreen(GUI_Window *w, uint32_t color) { + for (int i = 0; i < w->sx * w->sy; i++) + w->bitmap_ptr[i] =color; +} + +GUI_Window *GUI_CreateWindow(uint32_t x, uint32_t y, uint32_t sx, uint32_t sy) { + GUI_Window *w = malloc(sizeof(GUI_Window)); + if (!w) + return NULL; + w->x = x; + w->y = y; + w->sx = sx; + w->sy = sy; + + // Connect to the windowserver + int ws_fd = -1; + for (; - 1 == ws_fd;) { + ws_fd = open("/dev/windowserver", O_RDWR | O_NONBLOCK, 0); + } + w->ws_socket = ws_fd; + char *str = random_string(); + WS_EVENT_CREATE e; + e.px = x; + e.py = y; + e.sx = sx; + e.sy = sy; + e.name_len = (uint8_t)strlen(str) + 1; + + // Create bitmap + w->bitmap_fd = shm_open(str, O_RDWR, 0); + if (!((int)w->bitmap_fd >= 0)) { + printf("bitmap_fd: %x\n", w->bitmap_fd); + assert(0); + } + ftruncate(w->bitmap_fd, sx * sy * sizeof(uint32_t)); + void *rc = mmap(NULL, sx * sy * sizeof(uint32_t), 0, 0, w->bitmap_fd, 0); + if (!((int)rc >= 0)) { + printf("rc: %x\n", rc); + assert(0); + } + w->bitmap_ptr = rc; + + // Send the request to the windowserver + uint8_t l = 1; + uint8_t len = sizeof(l) + sizeof(e) + e.name_len; + char *buffer = malloc(len); + char *p = buffer; + memcpy(p, &l, sizeof(l)); + p += sizeof(l); + memcpy(p, &e, sizeof(e)); + p += sizeof(e); + strcpy(p, str); + write(ws_fd, buffer, len); + return w; +} + +void GUI_UpdateWindow(GUI_Window *w) { + uint8_t l = 0; + write(w->ws_socket, &l, sizeof(l)); +} diff --git a/userland/libgui/libgui.h b/userland/libgui/libgui.h new file mode 100644 index 0000000..d58c23c --- /dev/null +++ b/userland/libgui/libgui.h @@ -0,0 +1,34 @@ +#ifndef LIBGUI_H +#define LIBGUI_H +#include <stddef.h> +#include <stdint.h> + +typedef struct { + int ws_socket; + int bitmap_fd; + uint32_t *bitmap_ptr; + int x; + int y; + int sx; + int sy; +} GUI_Window; + +// Taken from drivers/keyboard.c +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +typedef struct { + int type; + struct KEY_EVENT ev; +} WS_EVENT; + +GUI_Window *GUI_CreateWindow(uint32_t x, uint32_t y, uint32_t sx, uint32_t sy); +void GUI_DrawFont(GUI_Window *w, uint32_t px, uint32_t py, const uint32_t c); +void GUI_UpdateWindow(GUI_Window *w); +void GUI_OverwriteFont(GUI_Window *w, uint32_t px, uint32_t py, + const uint32_t color); +void GUI_ClearScreen(GUI_Window *w, uint32_t color); +#endif diff --git a/userland/minibox/Makefile b/userland/minibox/Makefile new file mode 100644 index 0000000..5448f96 --- /dev/null +++ b/userland/minibox/Makefile @@ -0,0 +1,12 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS=-Wall -Wextra -pedantic -Wimplicit-fallthrough -g -O0 +OBJ=minibox.o utilities/cat.o utilities/echo.o utilities/yes.o utilities/minibox.o utilities/ascii.o utilities/wc.o utilities/init.o utilities/ls.o utilities/touch.o utilities/ed.o + +%.o: %.c + $(CC) $(CFLAGS) $(INCLUDE) $(LIBS) -c $< -o $@ + +minibox: $(OBJ) + $(CC) $(INCLUDE) -o $@ $^ $(CFLAGS) $(LIBS) + +clean: + rm minibox $(OBJ) diff --git a/userland/minibox/minibox.c b/userland/minibox/minibox.c new file mode 100644 index 0000000..63eaee8 --- /dev/null +++ b/userland/minibox/minibox.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: 0BSD +// TODO: Possibly use getprogname() instead of using argv[0] to get the +// utility name. +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "utilities/include.h" + +#define ARRAY_LENGTH(array) (sizeof(array) / sizeof((array)[0])) + +typedef struct Command { + char *name; + int (*function)(int, char **); +} Command; + +#define STR2(_x) #_x +#define STR(_x) STR2(_x) +#define COMMAND(NAME) \ + { STR(NAME), NAME##_main } + +Command utilities[] = {COMMAND(minibox), COMMAND(ascii), COMMAND(echo), + COMMAND(cat), COMMAND(yes), COMMAND(wc), + COMMAND(init), COMMAND(ls), COMMAND(touch), + COMMAND(ed)}; + +char *parse_filename(char *str) { + char *tmp = NULL, *is = str; + for (; *is++;) + if ('/' == *is) + tmp = is; + return tmp ? tmp + 1 : str; +} + +void usage(void) { + for (int i = 0; i < ARRAY_LENGTH(utilities); i++) { + printf("%s ", utilities[i].name); + } + printf("\n"); +} + +int main(int argc, char **argv) { + if (argc < 1) + return 1; +#ifdef SINGLE_MAIN + return utilities[0].function(argc, argv); +#endif + + // argv[0] will be checked to determine what utility + // is supposed to be ran. + // NOTE: "minibox" is a utility than can be ran. "minibox" + // will switch argv and argc so that argv[1] -> argv[0] + // then it will rerun main(). This allows utlities + // to be ran like "minibox <utility> <arguments>" or + // even "minibox minibox <utility> <arguments>" + const char *utility_name = parse_filename(argv[0]); + if (*utility_name == '/') + utility_name++; + for (int i = 0; i < ARRAY_LENGTH(utilities); i++) + if (0 == strcmp(utility_name, utilities[i].name)) + return utilities[i].function(argc, argv); + + usage(); + return 0; +} diff --git a/userland/minibox/utilities/ascii.c b/userland/minibox/utilities/ascii.c new file mode 100644 index 0000000..53429dc --- /dev/null +++ b/userland/minibox/utilities/ascii.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +const char * const ascii_table[] = +{ +"Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex", +" 0 00 NUL 16 10 DLE 32 20 48 30 0 64 40 @ 80 50 P 96 60 ` 112 70 p", +" 1 01 SOH 17 11 DC1 33 21 ! 49 31 1 65 41 A 81 51 Q 97 61 a 113 71 q", +" 2 02 STX 18 12 DC2 34 22 \" 50 32 2 66 42 B 82 52 R 98 62 b 114 72 r", +" 3 03 ETX 19 13 DC3 35 23 # 51 33 3 67 43 C 83 53 S 99 63 c 115 73 s", +" 4 04 EOT 20 14 DC4 36 24 $ 52 34 4 68 44 D 84 54 T 100 64 d 116 74 t", +" 5 05 ENQ 21 15 NAK 37 25 % 53 35 5 69 45 E 85 55 U 101 65 e 117 75 u", +" 6 06 ACK 22 16 SYN 38 26 & 54 36 6 70 46 F 86 56 V 102 66 f 118 76 v", +" 7 07 BEL 23 17 ETB 39 27 ' 55 37 7 71 47 G 87 57 W 103 67 g 119 77 w", +" 8 08 BS 24 18 CAN 40 28 ( 56 38 8 72 48 H 88 58 X 104 68 h 120 78 x", +" 9 09 HT 25 19 EM 41 29 ) 57 39 9 73 49 I 89 59 Y 105 69 i 121 79 y", +" 10 0A LF 26 1A SUB 42 2A * 58 3A : 74 4A J 90 5A Z 106 6A j 122 7A z", +" 11 0B VT 27 1B ESC 43 2B + 59 3B ; 75 4B K 91 5B [ 107 6B k 123 7B {", +" 12 0C FF 28 1C FS 44 2C , 60 3C < 76 4C L 92 5C \\ 108 6C l 124 7C |", +" 13 0D CR 29 1D GS 45 2D - 61 3D = 77 4D M 93 5D ] 109 6D m 125 7D }", +" 14 0E SO 30 1E RS 46 2E . 62 3E > 78 4E N 94 5E ^ 110 6E n 126 7E ~", +" 15 0F SI 31 1F US 47 2F / 63 3F ? 79 4F O 95 5F _ 111 6F o 127 7F DEL", +}; + +int ascii_main(int argc, char ** argv) +{ + for(int i = 0;i < sizeof(ascii_table)/sizeof(ascii_table[0]);i++) + puts(ascii_table[i]); + + return 0; +} diff --git a/userland/minibox/utilities/cat.c b/userland/minibox/utilities/cat.c new file mode 100644 index 0000000..c528d49 --- /dev/null +++ b/userland/minibox/utilities/cat.c @@ -0,0 +1,54 @@ +// cat - concatenate and print files +// https://pubs.opengroup.org/onlinepubs/9699919799/ +// +// TODO: Add -u flag "Write bytes from the input file to the standard +// output without delay as each is read." +#include "include.h" +#include <dirent.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int fd_to_stdout(int fd) { + int rc; + for (char buffer[CAT_BUFFER]; (rc = read(fd, &buffer, sizeof(buffer)));) { + if (-1 == rc) + return 0; + if (-1 == write(fd_stdout, buffer, rc)) + return 0; + } + return 1; +} + +int cat_main(int argc, char **argv) { + int fd = fd_stdin; + + // If no file operands are specified, the standard input shall be + // used. + if (argc < 2) { + return (fd_to_stdout(0)) ? 0 : 1; + } + + argv++; + for (; *argv; argv++) { + // If a file is '-', the cat utility shall read from the standard + // input at that point in the sequence. + if (0 == strcmp(*argv, "-")) { + if (!fd_to_stdout(0)) + return 1; + continue; + } + + if (-1 == (fd = open(*argv, O_RDONLY, 0))) { + printf("cat: "); + // fflush(stdout); + perror(*argv); + return 1; + } + if (!fd_to_stdout(fd)) + return 1; + close(fd); + } + return 0; +} diff --git a/userland/minibox/utilities/echo.c b/userland/minibox/utilities/echo.c new file mode 100644 index 0000000..5ec68a7 --- /dev/null +++ b/userland/minibox/utilities/echo.c @@ -0,0 +1,30 @@ +#include "include.h" +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> + +int echo(char **str, int new_line) { + for (; *str;) { + printf("%s", *str); + if (*++str) + putchar(' '); + } + + if (new_line) + putchar('\n'); + return 0; +} + +int echo_main(int argc, char **argv) { + int new_line = 1; + + for (; *++argv && '-' == **argv;) + switch (*(*argv + 1)) { + case 'n': + new_line = 0; + break; + } + + return echo(argv, new_line); +} diff --git a/userland/minibox/utilities/ed.c b/userland/minibox/utilities/ed.c new file mode 100644 index 0000000..53270dc --- /dev/null +++ b/userland/minibox/utilities/ed.c @@ -0,0 +1,145 @@ +// ed - edit text +// ed [-p string] [-s] [file] +#include <assert.h> +#include <stdio.h> +#include <string.h> +#define COMMAND_MODE 0 +#define INPUT_MODE 1 + +int mode = COMMAND_MODE; + +FILE *fp = NULL; +FILE *mem_fp = NULL; +int line_number = 1; + +int getline(char *buffer, size_t s) { + (void)s; + int i = 0; + char c; + for (;; i++) { + int rc = read(0, &c, 1); + assert(rc > 0); + printf("%c", c); + buffer[i] = c; + if ('\n' == c) + break; + } + buffer[i] = '\0'; + return i; +} + +void goto_line(void) { + char c; + fseek(mem_fp, 0, SEEK_SET); + int line = 1; + if (1 != line_number) { + // Goto line + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + line++; + if (line == line_number) + return; + } + printf("got to line: %d\n", line); + assert(0); + } +} + +void read_line(void) { + char c; + goto_line(); + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + break; + printf("%c", c); + } + printf("\n"); +} + +void goto_end_of_line(void) { + char c; + for (; fread(&c, 1, 1, mem_fp);) { + if ('\n' == c) + break; + } +} + +void delete_line(void) { + long s = ftell(mem_fp); + printf("s: %d\n", s); + goto_end_of_line(); + long end = ftell(mem_fp); + printf("end: %d\n", end); + long offset = end - s; + for (char buffer[4096];;) { + int rc = fread(buffer, 1, 100, mem_fp); + long reset = ftell(mem_fp); + if (0 == rc) + break; + fseek(mem_fp, s, SEEK_SET); + fwrite(buffer, 1, rc, mem_fp); + s += rc; + fseek(mem_fp, reset, SEEK_SET); + } +} + +void read_command(void) { + char buffer[4096]; + char *s = buffer; + getline(buffer, 4096); + int a = -1; + int rc = sscanf(buffer, "%d", &a); + if (0 < rc) { + line_number = a; + } + for (; isdigit(*s); s++) + ; + if (0 == strcmp(s, "i")) { + mode = INPUT_MODE; + return; + } + if (0 == strcmp(s, ".")) { + read_line(); + return; + } + return; +} + +void read_input(void) { + char buffer[4096]; + int l = getline(buffer, 4096); + if (0 == strcmp(buffer, ".")) { + mode = COMMAND_MODE; + return; + } + goto_line(); + delete_line(); + goto_line(); + assert(fwrite(buffer, l, 1, mem_fp)); + return; +} + +int ed_main(char argc, char **argv) { + if (argc < 2) + return 1; + char *buffer; + size_t size; + mem_fp = open_memstream(&buffer, &size); + assert(mem_fp); + fp = fopen(argv[1], "r"); + assert(fp); + char r_buffer[4096]; + for (int rc; (rc = fread(buffer, 1, 4096, fp));) { + fwrite(r_buffer, 1, rc, mem_fp); + } + + for (;;) { + if (COMMAND_MODE == mode) + read_command(); + else + read_input(); + } + fclose(fp); + fclose(mem_fp); + return 0; +} diff --git a/userland/minibox/utilities/include.h b/userland/minibox/utilities/include.h new file mode 100644 index 0000000..7ffd136 --- /dev/null +++ b/userland/minibox/utilities/include.h @@ -0,0 +1,41 @@ +#include <stdio.h> +/* General constants */ +#define fd_stdin 0 /* standard in file descriptor */ +#define fd_stdout 1 /* standard out file descriptor */ +#define ASSERT_NOT_REACHED assert(0); +/* END General constants */ + +/* CAT SETTINGS */ +#define CAT_BUFFER 4096 /* size of the read buffer */ +/* END CAT SETTINGS */ + +/* HTTP SETTINGS */ +#define HTTP_MAX_BUFFER 4096 /* size of the read buffer */ +#define HTTP_DEFAULT_PORT 1337 /* default port should -p not be supplied */ +#define HTTP_WEBSITE_ROOT "site/" /* default directory that it chroots into */ + +/* should xxx.html not exist these will be supplied instead */ +#define HTTP_DEFAULT_404_SITE "404 - Not Found" +#define HTTP_DEFAULT_400_SITE "400 - Bad Request" +/* END HTTP SETTINGS */ + +#define COND_PERROR_EXP(condition, function_name, expression) \ + if (condition) { \ + perror(function_name); \ + expression; \ + } + +int minibox_main(int argc, char **argv); +int ascii_main(int argc, char **argv); +int echo_main(int argc, char **argv); +int http_main(int argc, char **argv); +int lock_main(int argc, char **argv); +int yes_main(int argc, char **argv); +int cat_main(int argc, char **argv); +int pwd_main(int argc, char **argv); +int wc_main(int argc, char **argv); +int ls_main(int argc, char **argv); +int touch_main(int argc, char **argv); +int ed_main(int argc, char **argv); + +int init_main(void); diff --git a/userland/minibox/utilities/init.c b/userland/minibox/utilities/init.c new file mode 100644 index 0000000..35bedf2 --- /dev/null +++ b/userland/minibox/utilities/init.c @@ -0,0 +1,72 @@ +#include <assert.h> +#include <fcntl.h> +#include <poll.h> +#include <pty.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> + +int cmdfd; + +void execsh(void) { + char *argv[] = {NULL}; + execv("/sh", argv); +} + +void newtty(void) { + int m; + int s; + openpty(&m, &s, NULL, NULL, NULL); + int pid = fork(); + if (0 == pid) { + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + execsh(); + return; + } + close(s); + cmdfd = m; +} + +void shell() { + struct pollfd fds[2]; + fds[0].fd = cmdfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + fds[1].fd = open("/dev/keyboard", O_RDONLY, 0); + fds[1].events = POLLIN; + fds[1].revents = 0; + for (;; fds[0].revents = fds[1].revents = 0) { + poll(fds, 2, 0); + if (fds[0].revents & POLLIN) { + char c[4096]; + int rc = read(fds[0].fd, c, 4096); + assert(rc > 0); + for (int i = 0; i < rc; i++) + putchar(c[i]); + } + if (fds[1].revents & POLLIN) { + char c; + int rc = read(fds[1].fd, &c, 1); + assert(rc > 0); + write(cmdfd, &c, 1); + // putchar(c); + } + } +} + +int init_main(void) { + if (1 != getpid()) { + printf("minibox init must be launched as pid1.\n"); + return 1; + } + if (fork()) + for (;;) + wait(NULL); + char *a[] = {NULL}; + execv("/term", a); + return 1; +} diff --git a/userland/minibox/utilities/ls.c b/userland/minibox/utilities/ls.c new file mode 100644 index 0000000..dc93d36 --- /dev/null +++ b/userland/minibox/utilities/ls.c @@ -0,0 +1,42 @@ +#include "include.h" +#include <dirent.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +int ls_main(int argc, char **argv) { + int list_hidden = 0; + int newline = 0; + /* + for (int ch;-1 != (ch = getopt(argc, argv, "a1"));) + switch ((char)ch) + { + case 'a': + list_hidden = 1; + break; + case '1': + newline = 1; + break; + }*/ + struct dirent **namelist; + int n; + COND_PERROR_EXP(-1 == (n = scandir("/", &namelist, 0, 0)), "scandir", + return 1); + + int prev = 0; + for (int i = 0; i < n; i++) { + if (!list_hidden) + if ('.' == *namelist[i]->d_name) + continue; + + if (prev) + putchar(newline ? '\n' : ' '); + else + prev = 1; + printf("%s", namelist[i]->d_name); + } + putchar('\n'); + return 0; +} diff --git a/userland/minibox/utilities/minibox.c b/userland/minibox/utilities/minibox.c new file mode 100644 index 0000000..ec5fdbd --- /dev/null +++ b/userland/minibox/utilities/minibox.c @@ -0,0 +1,15 @@ +#include "include.h" + +void usage(void); +int main(int argc, char **argv); + +// Should a command be called via "minibox <command> <arguments>" then shift +// argv and argc to become "<command> <arguments>" and rerun main() +int minibox_main(int argc, char **argv) { + if (argc < 2) + usage(); + + argc--; + argv++; + return main(argc, argv); +} diff --git a/userland/minibox/utilities/pwd.c b/userland/minibox/utilities/pwd.c new file mode 100644 index 0000000..29d8129 --- /dev/null +++ b/userland/minibox/utilities/pwd.c @@ -0,0 +1,12 @@ +#include "include.h" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> + +int pwd_main(int argc, char **argv) { + char cwd[PATH_MAX]; + COND_PERROR_EXP(NULL == (getcwd(cwd, PATH_MAX)), "getcwd", return 1); + puts(cwd); + return 0; +} diff --git a/userland/minibox/utilities/touch.c b/userland/minibox/utilities/touch.c new file mode 100644 index 0000000..949ad96 --- /dev/null +++ b/userland/minibox/utilities/touch.c @@ -0,0 +1,11 @@ +#include "include.h" +#include <fcntl.h> + +int touch_main(int argc, char **argv) { + if (argc < 2) + return 1; + int fd; + COND_PERROR_EXP(open(argv[1], 0, O_CREAT), "open", return 1) + close(fd); + return 0; +} diff --git a/userland/minibox/utilities/wc.c b/userland/minibox/utilities/wc.c new file mode 100644 index 0000000..886eb9e --- /dev/null +++ b/userland/minibox/utilities/wc.c @@ -0,0 +1,106 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <ctype.h> +#include "include.h" + +int cmode, wmode, lmode; + +void output(const char * str, size_t lines, size_t words, size_t chars) +{ + if(lmode) + printf("%d", lines); + + if(wmode) + { + if(lmode) putchar(' '); + + printf("%d", words); + } + + if(cmode) + { + if(lmode) putchar(' '); + + printf("%d", chars); + } + + if(str) printf(" %s", str); + + putchar('\n'); +} + +void wc(int argc, char ** argv) +{ + int fd = fd_stdin; + size_t total_chars, total_words, total_lines; + total_chars = total_words = total_lines = 0; + + if(NULL == *argv) + goto read_stdin; + + + for(;*argv;argv++) + { + int new_word = 1; + size_t chars = 0, + words = chars, + lines = chars; + + fd = open(*argv, O_RDONLY, 0); +read_stdin: + for(char c;read(fd, &c, 1);) + { + if(cmode) + chars++; + + if(wmode) + { + if(isspace(c)) { + new_word = 1; + } else if(new_word) { + words++; + new_word = 0; + } + } + + if(lmode) + if('\n' == c) + lines++; + } + close(fd); + if(lmode) total_lines += lines; + if(wmode) total_words += words; + if(cmode) total_chars += chars; + + output(*argv, lines, words, chars); + if(NULL == *argv) return; // We read from stdin + } + + if(argc > 1) output("total", total_lines, total_words, total_chars); +} + +int wc_main(int argc, char ** argv) +{ + cmode = wmode = lmode = 0; + for(argc--;*++argv && '-' == **argv;argc--) + switch(*(*argv+1)) + { + case 'l': + lmode = 1; + break; + case 'w': + wmode = 1; + break; + case 'c': + cmode = 1; + break; + } + + if(!(lmode || cmode || wmode)) + cmode = wmode = lmode = 1; + + wc(argc, argv); + return 0; +} diff --git a/userland/minibox/utilities/yes.c b/userland/minibox/utilities/yes.c new file mode 100644 index 0000000..ff19004 --- /dev/null +++ b/userland/minibox/utilities/yes.c @@ -0,0 +1,13 @@ +#include "include.h" +#include <stdio.h> + +int yes_main(int argc, char **argv) { + if (argc < 2) + for (;;) + puts("y"); + + for (;; putchar('\n')) + for (int i = 1; i < argc; i++) + printf("%s ", argv[i]); + return 0; +} diff --git a/userland/sh/Makefile b/userland/sh/Makefile new file mode 100644 index 0000000..adccfb3 --- /dev/null +++ b/userland/sh/Makefile @@ -0,0 +1,13 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -fsanitize=shift,signed-integer-overflow,bounds +BINS=sh +all: $(BINS) + +sh.o: sh.c + $(CC) $(CFLAGS) -L../libc/ -lc -c sh.c -I../libc/ +# $(CC) $(CFLAGS) ../libc/libc.o ../libc/crt0.o sh.c -I../libc/ + +clean: + rm sh sh.o +sh: sh.o + $(CC) -shared -o sh -ffreestanding -nostdlib $(CFLAGS) sh.o -L../libc/ -lc -lgcc #-L../libc/c.a diff --git a/userland/sh/sh b/userland/sh/sh Binary files differnew file mode 100755 index 0000000..7791495 --- /dev/null +++ b/userland/sh/sh diff --git a/userland/sh/sh.c b/userland/sh/sh.c new file mode 100644 index 0000000..5fe7f63 --- /dev/null +++ b/userland/sh/sh.c @@ -0,0 +1,224 @@ +#include <assert.h> +#include <fcntl.h> +#include <limits.h> +#include <poll.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#define MAX_ARGS 20 + +#define IS_SPECIAL(_c) (';' == _c || '\n' == _c || '&' == _c || '|' == _c) + +char *PATH = "/:/bin"; + +int can_open(char *f) { + int rc; + if (-1 == (rc = open(f, O_RDONLY, 0))) + return 0; + close(rc); + return 1; +} + +int find_path(char *file, char *buf) { + if ('/' == *file || '.' == *file) { // Real path + if (!can_open(file)) { + return 0; + } + strcpy(buf, file); + return 1; + } + + char *p = PATH; + for (;;) { + char *b = p; + for (; *p && ':' != *p; p++) + ; + size_t l = p - b; + strlcpy(buf, b, l); + strcat(buf, "/"); + strcat(buf, file); + if (can_open(buf)) { + return 1; + } + if (!*p) + break; + p++; + } + return 0; +} + +int internal_exec(char *file, char **argv) { + char r_path[PATH_MAX]; + if (!find_path(file, r_path)) + return 0; + if (-1 == execv(r_path, argv)) { + perror("exec"); + return 0; + } + return 1; +} + +int execute_program(char *s, size_t l, int ignore_rc, int f_stdout, + int *new_out) { + if (!l) + return -1; + + char c[l + 1]; + memcpy(c, s, l); + c[l] = 0; + + char *argv[MAX_ARGS]; + int args = 0; + char *p = c; + for (size_t i = 0; i <= l; i++) { + if (' ' == c[i]) { + if (p == c + i) { + for (; ' ' == *p; p++, i++) + ; + i--; + continue; + } + c[i] = '\0'; + + if (strlen(p) == 0) + break; + + argv[args] = p; + args++; + p = c + i + 1; + } else if (i == l) { + if (strlen(p) == 0) + break; + argv[args] = p; + args++; + } + } + argv[args] = NULL; + + int fd[2]; + pipe(fd); + + int pid = fork(); + if (0 == pid) { + if (new_out) + dup2(fd[1], 1); + if (-1 != f_stdout) + dup2(f_stdout, 0); + close(fd[0]); + if (!internal_exec(argv[0], argv)) { + printf("exec failed\n"); + exit(1); + } + } + + close(fd[1]); + if (new_out) + *new_out = fd[0]; + + if (ignore_rc) + return 0; + + int rc; + wait(&rc); + return rc; +} + +int compute_expression(char *exp) { + char *n = exp; + int ignore_next = 0; + int rc; + int f_stdout = -1; + int new_out = f_stdout; + for (; *exp; exp++) { + if (!IS_SPECIAL(*exp)) { + continue; + } + if ('\n' == *exp) + break; + if (';' == *exp) { + if (!ignore_next) { + execute_program(n, exp - n, 0, f_stdout, NULL); + } + n = exp + 1; + continue; + } + if ('&' == *exp && '&' == *(exp + 1)) { + if (!ignore_next) { + rc = execute_program(n, exp - n, 0, f_stdout, NULL); + if (0 != rc) + ignore_next = 1; + } + n = exp + 2; + exp++; + continue; + } else if ('&' == *exp) { + if (!ignore_next) { + execute_program(n, exp - n, 1, f_stdout, NULL); + } + n = exp + 1; + continue; + } + if ('|' == *exp && '|' == *(exp + 1)) { + if (!ignore_next) { + rc = execute_program(n, exp - n, 0, f_stdout, NULL); + if (0 == rc) + ignore_next = 1; + } + n = exp + 2; + exp++; + continue; + } else if ('|' == *exp) { + if (!ignore_next) { + execute_program(n, exp - n, 1, f_stdout, &new_out); + f_stdout = new_out; + } + n = exp + 1; + continue; + } + } + if (!ignore_next) + rc = execute_program(n, exp - n, 0, f_stdout, NULL); + return rc; +} + +char *get_line(void) { + char *str = malloc(1024); + char *p = str; + int rc; + for (;;) { + if (0 == (rc = read(0, p, 1))) { + continue; + } + if (0 > rc) { + perror("read"); + continue; + } + if (8 == *p) { + if (p == str) + continue; + putchar(*p); + p--; + continue; + } + putchar(*p); + if ('\n' == *p) { + break; + } + p++; + } + p++; + *p = '\0'; + return str; +} + +int main(void) { + for (;;) { + printf("/ : "); + char *l = get_line(); + compute_expression(l); + free(l); + } + return 0; +} diff --git a/userland/sh/sh_a b/userland/sh/sh_a Binary files differnew file mode 100755 index 0000000..7b435ab --- /dev/null +++ b/userland/sh/sh_a diff --git a/userland/sh/sh_bad b/userland/sh/sh_bad Binary files differnew file mode 100755 index 0000000..7f93418 --- /dev/null +++ b/userland/sh/sh_bad diff --git a/userland/snake/Makefile b/userland/snake/Makefile new file mode 100644 index 0000000..f29df30 --- /dev/null +++ b/userland/snake/Makefile @@ -0,0 +1,15 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -static -fsanitize=shift,signed-integer-overflow,bounds +LIB=-L../libgui -lgui -L../json -ljson -L../libc -lc -lgcc +INC=-I../libc/ -I../json/ -I../libgui/ +BINS=snake +all: $(BINS) + +snake.o: snake.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +snake: snake.o + $(CC) -nostdlib $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/snake/snake.c b/userland/snake/snake.c new file mode 100644 index 0000000..7bfb312 --- /dev/null +++ b/userland/snake/snake.c @@ -0,0 +1,109 @@ +#include <assert.h> +#include <fcntl.h> +#include <json.h> +#include <libgui.h> +#include <poll.h> +#include <pty.h> +#include <socket.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +GUI_Window *global_w; + +#define SNAKE_WIDTH 10 + +int get_key_event(char *c) { + if (0 >= read(global_w->ws_socket, c, 1)) + return 0; + if (0 == *c) + return 0; + return 1; +} + +void draw_snake(int x, int y) { + int sx = global_w->sx; + uint32_t *b = &global_w->bitmap_ptr[y * sx + x]; + for (int i = 0; i < SNAKE_WIDTH; i++) { + for (int j = 0; j < SNAKE_WIDTH; j++) { + b[j] = 0xFF00FF; + } + b += sx; + } +} + +int clamp(int *x, int *y) { + int clamped = 0; + if (*x + SNAKE_WIDTH > global_w->sx) { + *x = global_w->sx - SNAKE_WIDTH; + clamped = 1; + } + if (*y + SNAKE_WIDTH > global_w->sy) { + *y = global_w->sy - SNAKE_WIDTH; + clamped = 1; + } + return clamped; +} + +void loop() { + int vel = SNAKE_WIDTH; + static int y_dir = SNAKE_WIDTH; + static int x_dir = 0; + static int snake_x = 10; + static int snake_y = 10; + static int ticks = 0; + ticks++; + char c; + if (get_key_event(&c)) { + switch (c) { + case 'w': + y_dir = -1 * vel; + x_dir = 0; + break; + case 's': + y_dir = vel; + x_dir = 0; + break; + case 'a': + x_dir = -1 * vel; + y_dir = 0; + break; + case 'd': + x_dir = vel; + y_dir = 0; + break; + case 'q': + exit(0); + break; + default: + break; + } + } + + if (!(ticks > 5)) + return; + ticks = 0; + + snake_x += x_dir; + snake_y += y_dir; + if (clamp(&snake_x, &snake_y)) + return; + draw_snake(snake_x, snake_y); + if (y_dir || x_dir) + GUI_UpdateWindow(global_w); +} + +int main(void) { + global_w = GUI_CreateWindow(10, 10, 150 * 4, 150 * 4); + assert(global_w); + for (int i = 0; i < 150 * 150 * 4 * 4; i++) + global_w->bitmap_ptr[i] = 0xFFFFFF; + GUI_UpdateWindow(global_w); + for (;;) { + loop(); + msleep(50); + } + return 0; +} diff --git a/userland/terminal/Makefile b/userland/terminal/Makefile new file mode 100644 index 0000000..330f6e0 --- /dev/null +++ b/userland/terminal/Makefile @@ -0,0 +1,15 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O0 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -static -fsanitize=shift,signed-integer-overflow,bounds +LIB=-L../libgui -lgui -L../json -ljson -L../libc -lc -lgcc +INC=-I../libc/ -I../json/ -I../libgui/ +BINS=term +all: $(BINS) + +term.o: term.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +term: term.o + $(CC) -nostdlib $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm $(BINS) *.o diff --git a/userland/terminal/term.c b/userland/terminal/term.c new file mode 100644 index 0000000..8a2ae83 --- /dev/null +++ b/userland/terminal/term.c @@ -0,0 +1,166 @@ +#include <assert.h> +#include <fcntl.h> +#include <json.h> +#include <libgui.h> +#include <poll.h> +#include <pty.h> +#include <socket.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define TERM_BACKGROUND 0x000000 + +int cmdfd; +GUI_Window *global_w; +uint32_t screen_pos_x = 0; +uint32_t screen_pos_y = 0; +int serial_fd; + +void execsh(void) { + char *argv[] = {NULL}; + execv("/sh", argv); +} + +uint32_t cursor_pos_x = 0; +uint32_t cursor_pos_y = 0; + +void screen_remove_old_cursor() { + GUI_OverwriteFont(global_w, cursor_pos_x, cursor_pos_y, TERM_BACKGROUND); +} + +void screen_update_cursor() { + GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, 0xFFFFFF); + cursor_pos_x = screen_pos_x; + cursor_pos_y = screen_pos_y; +} + +void screen_putchar(uint32_t c) { + if (c == '\n') { + screen_pos_x = 0; + screen_pos_y += 8; + screen_remove_old_cursor(); + screen_update_cursor(); + return; + } + if (screen_pos_y > global_w->sy - 8) { + uint8_t line[global_w->sx * sizeof(uint32_t)]; + for (int i = 0; i < global_w->sy - 8; i++) { + memcpy(line, global_w->bitmap_ptr + ((i + 8) * global_w->sx), + global_w->sx * sizeof(uint32_t)); + memcpy(global_w->bitmap_ptr + (i * global_w->sx), line, + global_w->sx * sizeof(uint32_t)); + } + for (int i = 0; i < global_w->sx; i += 8) { + GUI_OverwriteFont(global_w, i, screen_pos_y - 8, TERM_BACKGROUND); + } + screen_pos_x = 0; + screen_pos_y -= 8; + } + GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); + screen_pos_x += 8; + if (screen_pos_x >= global_w->sx - 8) { + screen_pos_x = 0; + screen_pos_y += 8; + } + screen_update_cursor(); +} + +void screen_delete_char(void) { + GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, TERM_BACKGROUND); + screen_pos_x -= 8; + GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, TERM_BACKGROUND); + screen_update_cursor(); +} + +void screen_print(const unsigned char *s, int l) { + for (; l; l--, s++) { + if ('\b' == *s) { + screen_delete_char(); + continue; + } + screen_putchar((uint32_t)*s); + } +} + +void newtty(void) { + int m; + int s; + openpty(&m, &s, NULL, NULL, NULL); + int pid = fork(); + if (0 == pid) { + dup2(s, 0); + dup2(s, 1); + dup2(s, 2); + execsh(); + return; + } + close(s); + cmdfd = m; +} + +void writetty(const char *b, size_t len) { + write(serial_fd, b, len); + for (int rc; len; len -= rc) { + rc = write(cmdfd, b, len); + if (-1 == rc) { + perror("write"); + assert(0); + } + } +} + +void run() { + char buffer[4096]; + struct pollfd fds[2]; + fds[0].fd = cmdfd; + fds[0].events = POLLIN; + fds[0].revents = 0; + fds[1].fd = global_w->ws_socket; + fds[1].events = POLLIN; + fds[1].revents = 0; + for (;; fds[0].revents = fds[1].revents = 0) { + poll(fds, 2, 0); + if (fds[0].revents & POLLIN) { + int rc; + if ((rc = read(cmdfd, buffer, 4096))) { + screen_print(buffer, rc); + GUI_UpdateWindow(global_w); + } + } + if (fds[1].revents & POLLIN) { + WS_EVENT e; + int rc; + if (0 >= (rc = read(global_w->ws_socket, &e, sizeof(e)))) + continue; + if (1 == e.ev.release) + continue; + if (0 == e.ev.c) + continue; + write(cmdfd, &e.ev.c, 1); + } + } +} + +int main(void) { + open("/dev/serial", O_RDWR, 0); + open("/dev/serial", O_RDWR, 0); + printf("running the terminal\n"); + int pid = fork(); + if (0 == pid) { + char *argv[] = {NULL}; + execv("/ws", argv); + } + + global_w = GUI_CreateWindow(20, 20, 250 * 4, 150 * 4); + assert(global_w); + for (int i = 0; i < 250 * 150 * 4 * 4; i++) + global_w->bitmap_ptr[i] = TERM_BACKGROUND; + // memset(global_w->bitmap_ptr, 0x0, 50 * 50); + GUI_UpdateWindow(global_w); + newtty(); + run(); + return 0; +} diff --git a/userland/test/Makefile b/userland/test/Makefile new file mode 100644 index 0000000..7287939 --- /dev/null +++ b/userland/test/Makefile @@ -0,0 +1,16 @@ +#CC="/home/anton/opt/cross/bin/i686-elf-gcc" +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -O2 -Wall -Wextra -pedantic -Wimplicit-fallthrough -static +LIB=-L../json -L../json/hashmap -ljson -lhashmap +INC=-I../json/ +BINS=test +all: $(BINS) + +test.o: test.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +test: test.o + $(CC) $(CFLAGS) -o $@ $^ $(LIB) + +clean: + rm test.o test diff --git a/userland/test/linux.sh b/userland/test/linux.sh new file mode 100755 index 0000000..d40d6cc --- /dev/null +++ b/userland/test/linux.sh @@ -0,0 +1,4 @@ +#!/bin/bash +gcc -DLINUX test.c -o ./local/a.out +cd local +./a.out diff --git a/userland/test/local/a.out b/userland/test/local/a.out Binary files differnew file mode 100755 index 0000000..1069f1f --- /dev/null +++ b/userland/test/local/a.out diff --git a/userland/test/local/testfile b/userland/test/local/testfile new file mode 100644 index 0000000..629ae5e --- /dev/null +++ b/userland/test/local/testfile @@ -0,0 +1 @@ +ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz diff --git a/userland/test/test b/userland/test/test Binary files differnew file mode 100755 index 0000000..63f9d8b --- /dev/null +++ b/userland/test/test diff --git a/userland/test/test.c b/userland/test/test.c new file mode 100644 index 0000000..041b08a --- /dev/null +++ b/userland/test/test.c @@ -0,0 +1,722 @@ +#include <assert.h> +#include <fcntl.h> +//#include <json.h> +#include <ctype.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if 1 +void dbgln(const char *fmt) { printf("%s\n", fmt); } +#else +void dbgln(const char *fmt, ...) { + printf("| "); + va_list ap; + va_start(ap, fmt); + int rc = vdprintf(1, fmt, ap); + va_end(ap); + printf("\n"); +} +#endif + +void isx_test() { + dbgln("isx TEST"); + { + assert(isspace(' ')); + assert(isspace('\t')); + assert(!isspace('A')); + + assert(isalpha('A')); + assert(!isalpha('9')); + assert(!isalpha(' ')); + assert(!isalpha('z' + 1)); + + assert(isascii('A')); + assert(isascii('9')); + assert(isascii(' ')); + assert(!isascii(0xFF)); + + assert(ispunct('.')); + assert(!ispunct('A')); + + assert(isdigit('9')); + assert(!isdigit('A')); + } + dbgln("isx TEST PASSED"); +} + +void malloc_test(void) { + dbgln("malloc TEST"); + for (int j = 0; j < 100; j++) { + // printf("j : %x\n", j); + uint8_t *t = malloc(400 + j); + memset(t, 0x43 + (j % 10), 400 + j); + uint8_t *p = malloc(900 + j); + memset(p, 0x13 + (j % 10), 900 + j); + assert(p > t && p > (t + 400 + j)); + + for (int i = 0; i < 400 + j; i++) + if (t[i] != 0x43 + (j % 10)) { + printf("t addy: %x, val: %x, should be: %x\n", t + i, t[i], + 0x43 + (j % 10)); + assert(0); + } + + for (int i = 0; i < 900 + j; i++) + if (p[i] != 0x13 + (j % 10)) { + printf("p addy: %x, val: %x, should be: %x\n", p + i, t[i], + 0x13 + (j % 10)); + assert(0); + } + free(t); + } + dbgln("malloc TEST PASSED"); +} + +void memcmp_test(void) { + dbgln("memcmp TEST"); + { + assert(0 == memcmp("\xAA\xBB\xCC", "\xAA\xBB\xCC", 3)); + assert(1 == memcmp("\xAF\xBB\xCC", "\xAA\xBB\xCC", 3)); + } + dbgln("memcmp TEST PASSED"); +} + +void memcpy_test(void) { + dbgln("memcpy TEST"); + { + char buf[100]; + assert(buf == memcpy(buf, "\xAA\xBB\xCC", 3)); + assert(0 == memcmp(buf, "\xAA\xBB\xCC", 3)); + assert(buf == memcpy(buf, "\xCC\xBB\xCC", 3)); + assert(0 == memcmp(buf, "\xCC\xBB\xCC", 3)); + + assert(buf == memcpy(buf, "\xAA\xBB\xCC\xDD", 4)); + assert(0 == memcmp(buf, "\xAA\xBB\xCC\xDD", 4)); + assert(buf == memcpy(buf, "\xAA\xBB\xCC\xEE", 3)); + assert(0 == memcmp(buf, "\xAA\xBB\xCC\xDD", 4)); + } + dbgln("memcpy TEST PASSED"); +} + +void memmove_test(void) { + dbgln("memmove TEST"); + { + char buf[100]; + memcpy(buf, "foobar", 6); + const char *p = buf + 2; // obar + + assert(buf == memmove(buf, p, 4)); + assert(0 == memcmp(buf, "obarar", 6)); + } + dbgln("memmove TEST PASSED"); +} + +void strlen_test(void) { + dbgln("strlen TEST"); + { + assert(0 == strlen("")); + assert(3 == strlen("%is")); + assert(3 == strlen("foo")); + assert(3 == strlen("bar")); + assert(6 == strlen("foobar")); + } + dbgln("strlen TEST PASSED"); +} + +void strnlen_test(void) { + dbgln("strnlen TEST"); + { + assert(0 == strnlen("", 0)); + assert(0 == strnlen("", 3)); + assert(3 == strnlen("foo", 3)); + assert(2 == strnlen("bar", 2)); + assert(3 == strnlen("foobar", 3)); + assert(6 == strnlen("foobar", 6)); + assert(6 == strnlen("foobar", 8)); + } + dbgln("strnlen TEST PASSED"); +} + +/* +void json_test(void) { + dbgln("JSON TEST"); + { + const char *s = "{\"string\": \"hello\", \"object\": {\"string\": \"ff\"}}"; + JSON_CTX ctx; + JSON_Init(&ctx); + JSON_Parse(&ctx, s); + JSON_ENTRY *main_entry = JSON_at(&ctx.global_object, 0); + assert(main_entry != NULL); + JSON_ENTRY *index_entry = JSON_at(main_entry, 0); + JSON_ENTRY *string_entry = JSON_search_name(main_entry, "string"); + assert(index_entry != NULL); + assert(index_entry == string_entry); + char *str = index_entry->value; + assert(0 == strcmp(str, "hello")); + + JSON_ENTRY *object = JSON_search_name(main_entry, "object"); + assert(object != NULL); + JSON_ENTRY *object_string = JSON_search_name(object, "string"); + assert(object_string != NULL); + assert(0 == strcmp(object_string->value, "ff")); + } + dbgln("JSON TEST PASSED"); +}*/ + +void random_test(void) { + dbgln("/dev/random TEST"); + { + int fd = open("/dev/random", O_RDONLY, 0); + uint8_t buffer_1[256]; + assert(256 == read(fd, buffer_1, 256)); + close(fd); + fd = open("/dev/random", O_RDONLY, 0); + uint8_t buffer_2[256]; + assert(256 == read(fd, buffer_2, 256)); + close(fd); + assert(0 != memcmp(buffer_1, buffer_2, 256)); + } + dbgln("/dev/random TEST PASSED"); +} + +void sscanf_test(void) { + dbgln("sscanf TEST"); + { + int d1; + int d2; + sscanf("1337:7331", "%d:%d", &d1, &d2); + assert(1337 == d1); + assert(7331 == d2); + sscanf(" 1234 31415", "%d%d", &d1, &d2); + assert(1234 == d1); + assert(31415 == d2); + sscanf(" 1234 441122", "%*d%d", &d1); + assert(441122 == d1); + + char f; + char b; + sscanf("f:b", "%c:%c", &f, &b); + assert('f' == f); + assert('b' == b); + } + dbgln("sscanf TEST PASSED"); +} + +void strtoul_test(void) { + dbgln("strtoul TEST"); + { + long r; + char *s = "1234"; + char *endptr; + r = strtoul("1234", &endptr, 10); + assert(1234 == r); + assert(endptr == (s + 4)); + } + dbgln("strtoul TEST PASSED"); +} + +void strcspn_test(void) { + dbgln("strcspn TEST"); + { + assert(4 == strcspn("1234", "")); + assert(3 == strcspn("1234", "4")); + assert(2 == strcspn("1234", "43")); + assert(0 == strcspn("1234", "2143")); + } + dbgln("strcspn TEST PASSED"); +} + +void strpbrk_test(void) { + dbgln("strpbrk TEST"); + { + char *s = "01234"; + assert(s + 3 == strpbrk(s, "3")); + assert(s + 4 == strpbrk(s, "4")); + assert(s + 2 == strpbrk(s, "2")); + assert(s + 2 == strpbrk(s, "23")); + assert(NULL == strpbrk(s, "5")); + } + dbgln("strpbrk TEST PASSED"); +} + +void strcpy_test(void) { + dbgln("strcpy TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strcpy(buf, "hello"); + assert(0 == memcmp(buf, "hello\0\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strcpy TEST PASSED"); +} + +void strncpy_test(void) { + dbgln("strncpy TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strncpy(buf, "hello", 3); + assert(0 == memcmp(buf, "hel\xBB\xBB\xBB\xBB\xBB\xBB\xBB", 10)); + strncpy(buf, "hello", 6); + assert(0 == memcmp(buf, "hello\0\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strncpy TEST PASSED"); +} + +void strlcpy_test(void) { + dbgln("strlcpy TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strlcpy(buf, "hello", 3); + assert(0 == memcmp(buf, "hel\x00\xBB\xBB\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strlcpy TEST PASSED"); +} + +void strcat_test(void) { + dbgln("strcat TEST"); + { + char buf[10]; + memset(buf, '\xBB', 10); + strcpy(buf, "hel"); + assert(0 == memcmp(buf, "hel\0\xBB\xBB\xBB\xBB\xBB\xBB", 10)); + strcat(buf, "lo"); + assert(0 == memcmp(buf, "hello\0\xBB\xBB\xBB\xBB", 10)); + } + dbgln("strcat TEST PASSED"); +} + +void strchr_test(void) { + dbgln("strchr TEST"); + { + char *s = "0123412345"; + assert(s + 3 == strchr(s, '3')); + assert(s + 4 + 5 == strchr(s, '5')); + assert(s + 4 == strchr(s, '4')); + assert(NULL == strchr(s, '9')); + } + dbgln("strchr TEST PASSED"); +} + +void strrchr_test(void) { + dbgln("strrchr TEST"); + { + char *s = "0123412345"; + assert(s + 3 + 4 == strrchr(s, '3')); + assert(s == strrchr(s, '0')); + assert(s + 4 + 5 == strrchr(s, '5')); + assert(NULL == strrchr(s, '9')); + } + dbgln("strrchr TEST PASSED"); +} + +void strdup_test(void) { + dbgln("strdup TEST"); + { + char *s; + s = strdup("hello"); + assert(s); + assert(0 == strcmp(s, "hello")); + free(s); + + s = strdup("abc"); + assert(s); + assert(0 == strcmp(s, "abc")); + free(s); + } + dbgln("strdup TEST PASSED"); +} + +void strndup_test(void) { + dbgln("strdup TEST"); + { + char *s; + s = strndup("hello", 5); + assert(s); + assert(0 == strcmp(s, "hello")); + free(s); + + s = strndup("hello", 3); + assert(s); + assert(0 == strcmp(s, "hel")); + free(s); + } + dbgln("strndup TEST PASSED"); +} + +void abs_test(void) { + dbgln("abs TEST"); + { + assert(1 == abs(1)); + assert(1 == abs(-1)); + assert(0 == abs(0)); + } + dbgln("abs TEST PASSED"); +} + +void strspn_test(void) { + dbgln("strspn TEST"); + { + assert(0 == strspn("abc", "")); + assert(0 == strspn("abc", "xyz")); + assert(1 == strspn("abc", "a")); + assert(2 == strspn("abc", "ab")); + assert(3 == strspn("abcd", "abc")); + assert(3 == strspn("abcde", "abce")); + } + dbgln("strspn TEST PASSED"); +} + +void strtol_test(void) { + dbgln("strtol TEST"); + { + char *s = "1234"; + char *e; + long r; + assert(1234 == strtol(s, &e, 10)); + assert(e == (s + 4)); + } + dbgln("strtol TEST PASSED"); +} + +void strcmp_test(void) { +#define EQ(_s1) \ + { assert(0 == strcmp(_s1, _s1)); } + dbgln("strcmp TEST"); + { + EQ("hello, world"); + EQ(""); + EQ("int: 100, hex: 64, octal: 144 a"); + } + dbgln("strcmp TEST PASSED"); +} + +void strncmp_test(void) { + dbgln("strncmp TEST"); + { + assert(0 == strncmp("hello", "hello", 5)); + assert(0 < strncmp("foo", "bar", 3)); + assert(0 == strncmp("foobar", "foofoo", 3)); + } + dbgln("strncmp TEST PASSED"); +} + +void strcasecmp_test(void) { + dbgln("strcasecmp TEST"); + { + assert(0 == strcasecmp("foobar", "FOObar")); + assert(0 == strcasecmp("foobar", "foobar")); + assert(6 == strcasecmp("foobar", "bar")); + } + dbgln("strcasecmp TEST PASSED"); +} + +void strncasecmp_test(void) { + dbgln("strncasecmp TEST"); + { + assert(0 == strncasecmp("foobar", "FOObar", 6)); + assert(0 == strncasecmp("foobar", "foobar", 6)); + assert(0 == strncasecmp("foo", "foobar", 3)); + assert(-1 == strncasecmp("foo", "foobar", 4)); + } + dbgln("strncasecmp TEST PASSED"); +} + +void strstr_test(void) { + dbgln("strstr TEST"); + { + const char *a = "foobar123"; + const char *b = "bar"; + assert(a + 3 == strstr(a, b)); + } + dbgln("strstr TEST PASSED"); +} + +void strtok_test(void) { + dbgln("strtok TEST"); + { + char *s = "hello,world,goodbye"; + assert(0 == strcmp(strtok(s, ","), "hello")); + assert(0 == strcmp(strtok(NULL, ","), "world")); + assert(0 == strcmp(strtok(NULL, ","), "goodbye")); + assert(NULL == strtok(NULL, ",")); + char *s2 = "hello,,world,,goodbye,test"; + assert(0 == strcmp(strtok(s2, ",,"), "hello")); + assert(0 == strcmp(strtok(NULL, ",,"), "world")); + assert(0 == strcmp(strtok(NULL, ","), "goodbye")); + assert(0 == strcmp(strtok(NULL, ","), "test")); + assert(NULL == strtok(NULL, ",")); + } + dbgln("strtok TEST PASSED"); +} + +void fseek_test(void) { + dbgln("fseek TEST"); + { +#ifndef LINUX + FILE *fp = fopen("/testfile", "r"); +#else + FILE *fp = fopen("testfile", "r"); +#endif + assert(NULL != fp); + char c; + assert(0 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('A' == c); + + assert(1 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('B' == c); + + assert(2 == ftell(fp)); + fseek(fp, 0, SEEK_SET); + assert(0 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('A' == c); + fseek(fp, 2, SEEK_SET); + assert(2 == ftell(fp)); + + assert(1 == fread(&c, 1, 1, fp)); + assert('C' == c); + fseek(fp, 2, SEEK_CUR); + assert(5 == ftell(fp)); + assert(1 == fread(&c, 1, 1, fp)); + assert('F' == c); + + char buffer[100]; + assert(6 == ftell(fp)); + fseek(fp, 0, SEEK_SET); + assert(1 == fread(buffer, 10, 1, fp)); + assert(0 == memcmp(buffer, "ABCDEFGHIJK", 10)); + assert(10 == ftell(fp)); + fseek(fp, 1, SEEK_SET); + assert(10 == fread(buffer, 1, 10, fp)); + assert(0 == memcmp(buffer, "BCDEFGHIJKL", 10)); + + fseek(fp, 0, SEEK_END); + assert(0 == fread(&c, 1, 1, fp)); + fseek(fp, -2, SEEK_CUR); + assert(1 == fread(&c, 1, 1, fp)); + assert('z' == c); + fseek(fp, -3, SEEK_END); + assert(1 == fread(&c, 1, 1, fp)); + assert('y' == c); + + assert(0 == fclose(fp)); + } + dbgln("fseek TEST PASSED"); +} + +void printf_test(void) { +#define EXP(exp) \ + { \ + int exp_n = strlen(exp); \ + if (0 != strcmp(buf, exp) || buf_n != exp_n) { \ + printf("buf n : %d\n", buf_n); \ + printf("exp n : %d\n", snprintf(NULL, 0, "%s", exp)); \ + printf("Expected: %s", exp); \ + printf("\n"); \ + printf("Got: %s", buf); \ + printf("\n"); \ + assert(0); \ + } \ + } + dbgln("printf TEST"); + { + char buf[200]; + int buf_n; + buf_n = sprintf(buf, "hello"); + EXP("hello"); + buf_n = sprintf(buf, "hello %s\n", "world"); + EXP("hello world\n"); + buf_n = sprintf(buf, "int: %d", 100); + EXP("int: 100"); + buf_n = sprintf(buf, "int: %d, hex: %x, octal: %o a", 100, 100, 100); + EXP("int: 100, hex: 64, octal: 144 a"); + + buf_n = sprintf(buf, "int: %02d", 1); + EXP("int: 01"); + buf_n = sprintf(buf, "int: %2d", 1); + EXP("int: 1"); + buf_n = sprintf(buf, "int: %00d", 1); + EXP("int: 1"); + + buf_n = sprintf(buf, "hex: %02x", 1); + EXP("hex: 01"); + buf_n = sprintf(buf, "hex: %2x", 1); + EXP("hex: 1"); + buf_n = sprintf(buf, "hex: %00x", 1); + EXP("hex: 1"); + buf_n = sprintf(buf, "hex: %x", 0x622933f2); + EXP("hex: 622933f2"); + + buf_n = sprintf(buf, "oct: %02o", 1); + EXP("oct: 01"); + buf_n = sprintf(buf, "oct: %2o", 1); + EXP("oct: 1"); + buf_n = sprintf(buf, "oct: %00o", 1); + EXP("oct: 1"); + + buf_n = sprintf(buf, "int: %-2dend", 1); + EXP("int: 1 end"); + buf_n = sprintf(buf, "int: %-2dend", 12); + EXP("int: 12end"); + buf_n = sprintf(buf, "int: %-0dend", 1); + EXP("int: 1end"); + + buf_n = sprintf(buf, "int: %-2xend", 1); + EXP("int: 1 end"); + buf_n = sprintf(buf, "int: %-2xend", 12); + EXP("int: c end"); + buf_n = sprintf(buf, "int: %-0xend", 1); + EXP("int: 1end"); + + buf_n = sprintf(buf, "int: %-2oend", 1); + EXP("int: 1 end"); + buf_n = sprintf(buf, "int: %-2oend", 12); + EXP("int: 14end"); + buf_n = sprintf(buf, "int: %-0oend", 1); + EXP("int: 1end"); + + buf_n = sprintf(buf, "string: %.3s", "foobar"); + EXP("string: foo"); + buf_n = sprintf(buf, "string: %.4s", "foobar"); + EXP("string: foob"); + + buf_n = sprintf(buf, "string: %s\n", "ABCDEFGHIJKLMNOPQRSTUVXYZ"); + EXP("string: ABCDEFGHIJKLMNOPQRSTUVXYZ\n"); + + buf_n = sprintf(buf, "string: %6send", "hello"); + EXP("string: helloend"); + buf_n = sprintf(buf, "string: %-6send", "hello"); + EXP("string: hello end"); + const char *data = "hello"; + char *foo = "foo"; + buf_n = sprintf(buf, " %-20s Legacy alias for \"%s\"\n", data, foo); + EXP(" hello Legacy alias for \"foo\"\n"); + buf_n = sprintf(buf, " %-20s %s%s\n", data, foo, "bar"); + EXP(" hello foobar\n"); + // Make sure that parameters have not changed + assert(0 == strcmp(data, "hello")); + assert(0 == strcmp(foo, "foo")); + + /* snprintf test */ + char out_buffer[100]; + memset(out_buffer, 'A', 100); + assert(5 == snprintf(out_buffer, 5, "hello")); + memcmp("helloAAAAA", out_buffer, 10); + assert(10 == snprintf(out_buffer, 5, "hellofoooo")); + memcmp("helloAAAAA", out_buffer, 10); + assert(10 == snprintf(out_buffer, 10, "hellofoooo")); + memcmp("hellofoookAA", out_buffer, 12); + } + dbgln("printf TEST PASSED"); +} + +int cmpfunc(const void *a, const void *b) { return (*(char *)a - *(char *)b); } + +void qsort_test(void) { + dbgln("qsort TEST"); + { + char buf[] = {'B', 'D', 'C', 'A', '\0'}; + qsort(buf, 4, sizeof(char), cmpfunc); + assert(0 == memcmp(buf, "ABCD", 4)); + } + dbgln("qsort TEST PASSED"); +} + +void basename_test(void) { + dbgln("basename TEST"); + { + char path[100]; + const char *s; + strcpy(path, "/foo/bar"); + s = basename(path); + assert(0 == strcmp(s, "bar")); + + strcpy(path, "/foo/bar/"); + s = basename(path); + assert(0 == strcmp(s, "bar")); + + strcpy(path, "/"); + s = basename(path); + assert(0 == strcmp(s, "/")); + + strcpy(path, "//"); + s = basename(path); + assert(0 == strcmp(s, "/")); + + strcpy(path, ""); + s = basename(path); + assert(0 == strcmp(s, ".")); + + s = basename(NULL); + assert(0 == strcmp(s, ".")); + } + dbgln("basename TEST PASSED"); +} + +void dirname_test(void) { + dbgln("dirname TEST"); + { + char path[100]; + const char *s; + strcpy(path, "/foo/bar"); + s = dirname(path); + assert(0 == strcmp(s, "foo")); + + strcpy(path, "/foo/bar/"); + s = dirname(path); + assert(0 == strcmp(s, "foo")); + + strcpy(path, "/foo/bar/zoo"); + s = dirname(path); + assert(0 == strcmp(s, "bar")); + } + dbgln("dirname TEST PASSED"); +} + +int main(void) { + dbgln("START"); + malloc_test(); + // json_test(); + // random_test(); + isx_test(); + memcmp_test(); + memcpy_test(); + memmove_test(); + strlen_test(); + strnlen_test(); + sscanf_test(); + strtoul_test(); + strcspn_test(); + strpbrk_test(); + strcpy_test(); + strncpy_test(); + strlcpy_test(); + strcat_test(); + strchr_test(); + strrchr_test(); + strdup_test(); + strndup_test(); + strspn_test(); + strtol_test(); + strcmp_test(); + strncmp_test(); + strcasecmp_test(); + strncasecmp_test(); + strstr_test(); + strtok_test(); + abs_test(); + // fseek_test(); + printf_test(); + qsort_test(); + basename_test(); + dirname_test(); + // TODO: Add mkstemp + return 0; +} diff --git a/userland/windowserver/Makefile b/userland/windowserver/Makefile new file mode 100644 index 0000000..f67bd66 --- /dev/null +++ b/userland/windowserver/Makefile @@ -0,0 +1,16 @@ +CC="/home/anton/prj/osdev/sysroot/bin/i686-sb-gcc" +CFLAGS = -ggdb -ffreestanding -O2 -Wall -Wextra -pedantic -mgeneral-regs-only -Wimplicit-fallthrough -fsanitize=shift,signed-integer-overflow,bounds +BIN=ws +LIB=-L../json -ljson -L../json/hashmap -lhashmap -L../libc -lc -lgcc +INC=-I../json/ -I../libgui/ +all: $(BIN) +OBJ=ws.o draw.o + +%.o: %.c + $(CC) $(CFLAGS) $(INC) $(LIB) -o $@ -c $< + +clean: + rm $(OBJ) ws + +$(BIN): $(OBJ) + $(CC) -o $(BIN) -ffreestanding -nostdlib $(CFLAGS) $(OBJ) $(LIB) diff --git a/userland/windowserver/draw.c b/userland/windowserver/draw.c new file mode 100644 index 0000000..caa16a2 --- /dev/null +++ b/userland/windowserver/draw.c @@ -0,0 +1,80 @@ +#include "draw.h" +#include <string.h> + +#define BPP 4 + +#define place_pixel(_p, _w, _h) \ + { *(uint32_t *)(disp->back_buffer + BPP * (_w) + (WIDTH * BPP * (_h))) = _p; } + +#define place_pixel_pos(_p, _pos) \ + { *(uint32_t *)(disp->back_buffer + BPP * (_pos)) = _p; } + +int mx; +int my; + +void update_display(DISPLAY *disp) { + for (int i = 0; i < 20; i++) { + place_pixel(0xFFFFFFFF, mx + i, my + i); + place_pixel(0xFFFFFFFF, mx, my + i / 2); + place_pixel(0xFFFFFFFF, mx + i / 2, my); + } + for (int i = 0; i < disp->size; i++) + disp->true_buffer[i] = disp->back_buffer[i]; + // memcpy(disp->true_buffer, disp->back_buffer, disp->size); +} + +void draw_wallpaper(DISPLAY *disp) { + for (int i = 0; i < disp->size / BPP; i++) { + place_pixel_pos(0xFF00FF, i); + } +} + +void draw_mouse(DISPLAY *disp, int mouse_x, int mouse_y) { + mx = mouse_x; + my = mouse_y; + update_full_display(disp, mouse_x, mouse_y); +} + +void draw_window(DISPLAY *disp, const WINDOW *w) { + int x, y; + uint8_t border_size = disp->border_size; + const int px = w->x + border_size; + const int py = w->y; + const int sx = w->sx; + const int sy = w->sy; + x = px; + y = py; + for (int i = 0; i < sy; i++) { + if((i+py)*WIDTH + px > HEIGHT*WIDTH) + break; + uint32_t *ptr = disp->back_buffer + BPP * ((i + py) * WIDTH) + px * BPP; + if(i*sx > HEIGHT*WIDTH) + break; + uint32_t *bm = &w->bitmap_ptr[i * sx]; + // ((uint8_t *)w->bitmap_ptr) + BPP * ((i + py) * WIDTH) + px * BPP; + for (int j = 0; j < sx; j++) { + ptr[j] = bm[j]; + } + } +} + +void update_active_window(DISPLAY *disp) { + for (int i = 0; i < 100; i++) { + if (!disp->clients[i]) + continue; + if (!disp->clients[i]->w) + continue; + draw_window(disp, disp->clients[i]->w); + } +} + +void update_full_display(DISPLAY *disp, int mouse_x, int mouse_y) { + draw_wallpaper(disp); /* + for (int i = 0; i < 100; i++) { + if (!disp->windows[i]) + continue; + draw_window(disp, disp->windows[i]); + }*/ + update_active_window(disp); + update_display(disp); +} diff --git a/userland/windowserver/draw.h b/userland/windowserver/draw.h new file mode 100644 index 0000000..bf9ff4f --- /dev/null +++ b/userland/windowserver/draw.h @@ -0,0 +1,13 @@ +#ifndef DRAW_H +#define DRAW_H +#include "ws.h" + +#define WIDTH 0x500 +#define HEIGHT 0x320 + +void draw_wallpaper(DISPLAY *disp); +void draw_window(DISPLAY *disp, const WINDOW *w); +void update_full_display(DISPLAY *disp, int mouse_x, int mouse_y); +void update_active_window(DISPLAY *disp); +void draw_mouse(DISPLAY *disp, int mouse_x, int mouse_y); +#endif diff --git a/userland/windowserver/font.h b/userland/windowserver/font.h new file mode 100644 index 0000000..ad63e41 --- /dev/null +++ b/userland/windowserver/font.h @@ -0,0 +1,133 @@ +#ifndef FONT_H +#define FONT_H +char font8x8_basic[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; +#endif diff --git a/userland/windowserver/ws.c b/userland/windowserver/ws.c new file mode 100644 index 0000000..e4f1a9e --- /dev/null +++ b/userland/windowserver/ws.c @@ -0,0 +1,375 @@ +#include <fcntl.h> +#include <poll.h> +#include <stddef.h> +#include <stdint.h> +//#include <sys/mman.h> +#include "draw.h" +#include "font.h" +#include "ws.h" +#include <assert.h> +#include <socket.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#define WINDOW_SERVER_SOCKET "/windowserver" + +CLIENT *clients[100]; +CLIENT *active_client; + +int mouse_x = 0; +int mouse_y = 0; + +// void *true_display; +// void *buffer_display; +// uint64_t display_size; +// int border_size; +// uint8_t border_color; +DISPLAY main_display; + +struct pollfd *fds; +uint64_t num_fds; + +uint64_t socket_fd_poll; +uint64_t keyboard_fd_poll; +uint64_t mouse_fd_poll; + +// Taken from drivers/keyboard.c +struct KEY_EVENT { + char c; + uint8_t mode; // (shift (0 bit)) (alt (1 bit)) + uint8_t release; // 0 pressed, 1 released +}; + +int create_socket(void) { + struct sockaddr_un address; + int fd = socket(AF_UNIX, 0, 0); + address.sun_family = AF_UNIX; + size_t str_len = strlen(WINDOW_SERVER_SOCKET); + address.sun_path = malloc(str_len + 1); + memcpy(address.sun_path, WINDOW_SERVER_SOCKET, str_len); + address.sun_path[str_len] = 0; + + bind(fd, (struct sockaddr *)(&address), sizeof(address)); + // for(;;); + /*free(address.sun_path);*/ + return fd; +} + +void setup_display(DISPLAY *disp, const char *path, uint64_t size) { + disp->wallpaper_color = 0x3; + disp->size = size; + disp->vga_fd = open(path, O_RDWR, 0); + if (-1 == disp->vga_fd) { + perror("open"); + for (;;) + ; + } + disp->true_buffer = mmap(NULL, size, 0, 0, disp->vga_fd, 0); + disp->back_buffer = malloc(size + 0x1000); + disp->clients = clients; +} + +void setup(void) { + setup_display(&main_display, "/dev/vbe", 0xBB8000); + draw_wallpaper(&main_display); + update_display(&main_display); + + main_display.border_size = 1; + main_display.border_color = 0xF; + active_client = NULL; + for (int i = 0; i < 100; i++) { + clients[i] = NULL; + } + + num_fds = 100; + fds = malloc(sizeof(struct pollfd[num_fds])); + memset(fds, 0, sizeof(struct pollfd[num_fds])); + for (size_t i = 0; i < num_fds; i++) + fds[i].fd = -1; + // Create socket + int socket_fd = create_socket(); + assert(socket_fd >= 0); + socket_fd_poll = 0; + fds[socket_fd_poll].fd = socket_fd; + fds[socket_fd_poll].events = POLLIN; + fds[socket_fd_poll].revents = 0; + int keyboard_fd = open("/dev/keyboard", O_RDONLY | O_NONBLOCK, 0); + assert(keyboard_fd >= 0); + keyboard_fd_poll = 1; + fds[keyboard_fd_poll].fd = keyboard_fd; + fds[keyboard_fd_poll].events = POLLIN; + fds[keyboard_fd_poll].revents = 0; + int mouse_fd = open("/dev/mouse", O_RDONLY, 0); + assert(mouse_fd >= 0); + mouse_fd_poll = 2; + fds[mouse_fd_poll].fd = mouse_fd; + fds[mouse_fd_poll].events = POLLIN; + fds[mouse_fd_poll].revents = 0; +} + +void reset_revents(struct pollfd *fds, size_t s) { + for (size_t i = 0; i < s - 1; i++) + fds[i].revents = 0; +} + +void add_fd(int fd) { + int i; + for (i = 0; i < num_fds; i++) + if (-1 == fds[i].fd) + break; + + fds[i].fd = fd; + fds[i].events = POLLIN | POLLHUP; + // fds[i].events = POLLIN; + fds[i].revents = 0; +} + +void add_client(int fd) { + int client_socket = accept(fd, NULL, NULL); + add_fd(client_socket); + int i; + for (i = 0; i < 100; i++) + if (!clients[i]) + break; + printf("adding client: %d\n", i); + CLIENT *c = clients[i] = malloc(sizeof(CLIENT)); + c->fd = client_socket; + active_client = c; + printf("clients[0]: %x\n", clients[0]); +} + +#define CLIENT_EVENT_CREATESCREEN 0 +#define CLIENT_EVENT_UPDATESCREEN 1 + +void add_window(CLIENT *c, int fd, int x, int y, int sx, int sy) { + WINDOW *w = malloc(sizeof(WINDOW)); + w->bitmap_fd = fd; + w->bitmap_ptr = mmap(NULL, sx * sy * sizeof(uint32_t), 0, 0, fd, 0); + w->x = x; + w->y = y; + w->sx = sx; + w->sy = sy; + c->w = w; +} + +typedef struct { + uint16_t px; + uint16_t py; + uint16_t sx; + uint16_t sy; + uint8_t name_len; +} WS_EVENT_CREATE; + +void parse_client_event(CLIENT *c) { + uint8_t event_type; + if (0 == read(c->fd, &event_type, sizeof(uint8_t))) { + printf("empty\n"); + return; + } + if (0 == event_type) { + update_full_display(&main_display, mouse_x, mouse_y); + return; + } + if (1 == event_type) { + WS_EVENT_CREATE e; + for (; 0 == read(c->fd, &e, sizeof(e));) + ; + uint8_t bitmap_name[e.name_len + 1]; + read(c->fd, bitmap_name, e.name_len); + bitmap_name[e.name_len] = '\0'; + int bitmap_fd = shm_open(bitmap_name, O_RDWR, O_CREAT); + add_window(c, bitmap_fd, e.px, e.py, e.sx, e.sy); + update_full_display(&main_display, mouse_x, mouse_y); + } +} + +typedef struct { + int type; + struct KEY_EVENT ev; +} WS_EVENT; + +void send_to_client(struct KEY_EVENT ev) { + WS_EVENT e = { + .type = 0, + .ev = ev, + }; + write(active_client->fd, &e, sizeof(e)); +} + +void clamp_screen_position(int *x, int *y) { + if (0 > *x) { + *x = 0; + } + if (0 > *y) { + *y = 0; + } + if (WIDTH < *x) { + *x = WIDTH; + } + if (HEIGHT < *y) { + *y = HEIGHT; + } +} + +int windowserver_key_events(struct KEY_EVENT ev, int *redraw) { + if (!(ev.mode & (1 << 1))) + return 0; + if (!active_client) + return 0; + int x = 0; + int y = 0; + switch (ev.c) { + case 'l': + x++; + break; + case 'h': + x--; + break; + case 'k': + y--; + break; + case 'j': + y++; + break; + } + if (x || y) { + active_client->w->x += x; + active_client->w->y += y; + clamp_screen_position(&active_client->w->x, &active_client->w->y); + *redraw = 1; + return 1; + } + return 0; +} + +struct mouse_event { + uint8_t buttons; + uint8_t x; + uint8_t y; +}; + +void update_mouse(void) { + draw_mouse(&main_display, mouse_x, mouse_y); + return; +} + +void parse_mouse_event(int fd) { + int16_t xc = 0; + int16_t yc = 0; + int middle_button = 0; + for (;;) { + struct mouse_event e[100]; + int rc = read(fd, e, sizeof(e)); + if (rc <= 0) + break; + + int n = rc / sizeof(e[0]); + for (int i = 0; i < n; i++) { + uint8_t xs = e[i].buttons & (1 << 4); + uint8_t ys = e[i].buttons & (1 << 5); + middle_button = e[i].buttons & (1 << 2); + int16_t x = e[i].x; + int16_t y = e[i].y; + if (xs) + x |= 0xFF00; + if (ys) + y |= 0xFF00; + xc += *(int16_t *)&x; + yc += *(int16_t *)&y; + } + } + mouse_x += xc; + mouse_y -= yc; + if (mouse_x < 0) + mouse_x = 0; + if (mouse_y < 0) + mouse_y = 0; + if (middle_button) { + active_client->w->x += xc; + active_client->w->y -= yc; + clamp_screen_position(&active_client->w->x, &active_client->w->y); + } + update_mouse(); +} + +void parse_keyboard_event(int fd) { + if (!active_client) { + return; + } + struct KEY_EVENT ev[250]; + int redraw = 0; + for (;;) { + int rc; + if (0 > (rc = read(fd, &ev[0], sizeof(ev)))) + break; + int n = rc / sizeof(ev[0]); + for (int i = 0; i < n; i++) { + if (windowserver_key_events(ev[i], &redraw)) + continue; + send_to_client(ev[i]); + } + } + if (redraw) + update_full_display(&main_display, mouse_x, mouse_y); +} + +CLIENT *get_client(int fd) { + for (int i = 0; i < 100; i++) { + if (!clients[i]) + continue; + if (clients[i]->fd == fd) + return clients[i]; + } + return NULL; +} + +void kill_client(CLIENT *c) { + c->w = NULL; + update_full_display(&main_display, mouse_x, mouse_y); + active_client = clients[0]; +} + +void parse_revents(struct pollfd *fds, size_t s) { + for (size_t i = 0; i < s - 1; i++) { + if (!fds[i].revents) + continue; + if (-1 == fds[i].fd) + continue; + if (socket_fd_poll == i && fds[i].revents & POLLIN) { + add_client(fds[i].fd); + continue; + } else if (keyboard_fd_poll == i) { + parse_keyboard_event(fds[i].fd); + continue; + } else if (mouse_fd_poll == i) { + parse_mouse_event(fds[i].fd); + continue; + } + CLIENT *c = get_client(fds[i].fd); + assert(c); + if (fds[i].revents & POLLHUP) { + kill_client(c); + fds[i].fd = -1; + } else { + parse_client_event(c); + } + } +} + +void run(void) { + for (;;) { + poll(fds, num_fds, 0); + parse_revents(fds, num_fds); + reset_revents(fds, num_fds); + } +} + +int main(void) { + open("/dev/serial", O_WRITE, 0); + open("/dev/serial", O_WRITE, 0); + setup(); + run(); + return 0; +} diff --git a/userland/windowserver/ws.h b/userland/windowserver/ws.h new file mode 100644 index 0000000..c4daf7b --- /dev/null +++ b/userland/windowserver/ws.h @@ -0,0 +1,30 @@ +#ifndef WS_H +#define WS_H +#include <stddef.h> +#include <stdint.h> + +typedef struct { + int bitmap_fd; + uint32_t *bitmap_ptr; + int x; + int y; + int sx; + int sy; +} WINDOW; + +typedef struct { + int fd; + WINDOW *w; +} CLIENT; + +typedef struct { + int vga_fd; + uint8_t *back_buffer; + uint8_t *true_buffer; + size_t size; + uint8_t border_size; + uint8_t border_color; + uint8_t wallpaper_color; + CLIENT **clients; +} DISPLAY; +#endif |