From: Zoltan Varga Date: Thu, 31 Mar 2016 17:18:26 +0000 (-0400) Subject: Merge pull request #2820 from kumpera/license-change-rebased X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=56ad8f4e5dfb8198e4671f631a3103b1e8b83dd3;hp=df9c98dda18083ec63171490267e08342621ef45;p=mono.git Merge pull request #2820 from kumpera/license-change-rebased Change license and publish xamarin mono extensions --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 230a4505f08..ed8d6fe7cc5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,29 +21,18 @@ investigate bugs, regressions and problems. License ======= -The Mono project uses the MIT X11, GNU LGPL version 2 and the Apache -License 2.0. We also imported some Microsoft code licensed under the -open source Microsoft Public License. +The Mono runtime, compilers, and tools and most of the class libraries +are licensed under the MIT license. But include some bits of code +licensed under different licenses. The exact list is [available here] (https://github.com/mono/mono/blob/master/LICENSE). Different parts of Mono use different licenses. The actual details of which licenses are used for which parts are detailed on the LICENSE file in this directory. -When contributing code, make sure that your contribution falls under -the appropriate license. For example, contributions to code licensed -under MIT/X11 code, should be MIT/X11 code. - -The runtime (`mono/...`) is a special case. The code is dual-licensed -by Xamarin under both the GNU LGPL v2 license and is also available -under commercial terms. For the runtime, you should either sign an -agreement that grants Xamarin the rights to relicense your code under -other licenses other than the LGPL v2 or your contribution must be -made as an MIT/X11 license which grants us the same rights, but -involves no paperwork. For the latter case, please specify on your -commit(s) that you are licensing the changes under MIT/X11. - -For other parts of the project that are dual-licensed, please state -on your commit(s) what license you are contributing the changes under. +CLA +======= + +Contributions are now taken under the [.NET Foundation CLA] (https://cla2.dotnetfoundation.org/). Testing ======= diff --git a/COPYING.LIB b/COPYING.LIB index 2f3b220f877..5fefc97aa29 100644 --- a/COPYING.LIB +++ b/COPYING.LIB @@ -1,501 +1 @@ - -The Mono runtime is licensed under the terms of the GNU -Library General Public License, version 2. - -The eglib directory is licensed under the terms of the MIT -X11 license and is a drop-in replacement for Mono's use of -glib 2.0 (which was LGPL). - -The Boehm licensing information is in the libgc directory - -The SGen Garbage Collector is under the terms of the MIT X11 -license - -The class libraries under mono/mcs are unless otherwise stated -under the MIT X11 license. - -Open source Microsoft code is licensed under the original terms -which is either MS-PL for older components, or dual licensed -MS-PL/Apache2 licensed. - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! +See LICENSE file in the project root for full license information. \ No newline at end of file diff --git a/LICENSE b/LICENSE index ad5cbb429ff..71bfc9eb4ce 100644 --- a/LICENSE +++ b/LICENSE @@ -1,138 +1,1442 @@ -Mono is made up of many pieces of code, all of them open source, but -different pieces of Mono use different licensing terms. +In general, the runtime and its class libraries are licensed under the +terms of the MIT license, and some third party code is licensed under +the 3-clause BSD license. See the file "PATENTS.TXT" for Microsoft's +patent grant on the Mono codebase. -For comments, corrections and updates, please contact mono@xamarin.com +The Mono distribution does include a handful of pieces of code that +are used during the build system and are covered under different +licenses, those include: -* Dual Licensing +Build Time Code +=============== - Parts of Mono are dual licensed, they are available to the - public in GPL or LGPL forms, but we also offer those pieces - under commercial terms from Xamarin for the cases where the - GPL and the LGPL are not suitable. +This is code that is used at build time, or during the maintenance of +Mono itself, and does not end up in the redistributable part of Mono: - We have tried to pick the licenses that will maximize adoption - of Mono, so we tend to use the MIT X11 or LGPL liceses. +* gettext - Contributions to dual-licensed module require that the author - contributes the code under the terms of the MIT X11 code, or - to sign an agreement that allows Novell to redistribute the - code under other licenses. + m4 source files used to probe features at build time: GPL - Contributions for other modules should be under the same license - terms as the rest of the module, or under MIT X11 terms. +* Benchmark Source Files - For the actual license links in the Mono distribution see the - bottom of this file. + Logic.cs and zipmark.cs are GPL source files. - If you need further information, please contact mono@xamarin.com +* mono/docs/HtmlAgilityPack -* The Modules + MS-PL licensed -** mono/mono: the Mono VM +* mcs/jay: 4-clause BSD licensed - This code is dual licensed under the LGPL or commercial licenses. +* mcs/nunit24: MS-PL - The LGPL ensures that Mono can be used in most scenarios, but - gives Xamarin the flexibility to relicense the code for - embedded systems, static linking or commercial settings where - the LGPL can not be used. +* mcs/class/I18N/mklist.sh, tools/cvt.sh: GNU GPLv2 - We consider non-LGPL use instances where you use this on an - embedded system where the end user is not able to upgrade the - Mono VM or Moonlight installation or distribution that is part - of your product (Section 6 and 7), you would have to obtain a - commercial license from Xamarin (consider software burned into - a ROM, systems where end users would not be able to upgrade, - an embedded console, a game console that imposes limitations - on the distribution and access to the code, a phone platform - that prevents end users from upgrading Moonlight). - - Contact mono@xamarin.com for details on obtaining the Mono - runtime under other terms. +Runtime Code +============ -** mono/support: MonoPosixHelper and support code +The following code is linked with the final Mono runtime, the libmono +embeddable runtime: - This code is dual licensed under the LGPL or commercial licenses, with - the same guidelines as mono/mono code. +* support/minizip: BSD license. - The ZLib files are included under a "new BSD"-style license. +* mono/utils/memcheck.h: BSD license, used on debug builds that use Valgrind. -** mono/eglib: Mono's X11 glib implementation +* mono/utils/freebsd-dwarf.h, freebsd-elf_common.h, freebsd-elf64.h freebsd-elf32.h: BSD license. - This is a minimal subset of glib that is to be licensed under - the terms of the MIT X11, this means that this code can be - used for any purposes by anyone. +* mono/utils/bsearch.c: BSD license. -** mono/arch/*/XXX-codegen.h +* mono/io-layer/wapi_glob.h, wapi_glob.c: BSD license - This are C macros that are useful when generating native - code on various platforms. This code is MIT X11 licensed. +Class Library code +================== -** mcs/mcs, mcs/gmcs +These are class libraries that can be loaded by your process: - The C# Compilers (1.0 and 2.0) +* mcs/class/RabbitMQ.Client: dual licensed in Apache v2, and Mozilla Public License 1.1 - These compilers are dual licensed under the GPL and MIT X11 - license terms. +* mcs/class/Compat.ICSharpCode.SharpZipLib and + mcs/class/ICSharpCode.SharpZipLib are GPL with class-path exception. + Originates with the SharpDevelop project. -** tests +* mcs/class/System.Core/System/TimeZoneInfo.Android.cs - Unless explicitly stated, the tests are under the MIT X11 license. + This is a port of Apache 2.0-licensed Android code, and thus is + licensed under the Apache 2.0 license -** mcs/class + http://www.apache.org/licenses/LICENSE-2.0 - The class libraries developed by the Mono team are licensed - under the MIT X11 terms. +API Documentation +================= - In addition to the class libraries developed by the Mono team, - there are a number of class libraries that we bundle as part - of the distribution that were integrated from third-parties or - that contain code that was originally licensed under different - terms, these are: +The API documentation is licensed under the terms of the Creative +Commons Attribution 4.0 International Public License - ByteFX.Data: LGPL - Npgsql: LGPL +The Licenses +============ - FirebirdSql.Data.Firebird: Firebird public license. - See: mcs/class/FirebirdSql.Data.Firebird/license.txt + These are the licenses used in Mono, the files are located: - ICSharpCode.SharpZipLib, GPL with exceptions. - See: mcs/class/ICSharpCode.SharpZipLib/README +### MIT X11 License -** mcs/class/System.Core/System/TimeZoneInfo.Android.cs +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: - This is a port of Apache 2.0-licensed Android code, and thus is - licensed under the Apache 2.0 license: +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. - http://www.apache.org/licenses/LICENSE-2.0 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -** mcs/tools - These are licensed under the MIT X11 license, except where the - GPL is explicitly used. +### Mozilla.MPL -** mcs/jay + MOZILLA PUBLIC LICENSE + Version 1.1 - This is a port of Berkeley yacc, so it is available under the BSD - license. See the license in the individual C files for details. + --------------- -** mono/man +1. Definitions. - Manual pages and Mono documentation are covered by the MIT X11 license. + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. -* samples + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. - The code in the "samples" directory is released under the MIT X11 license. + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. -* The Licenses + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. - These are the licenses used in Mono, the files are located: + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + +### Microsoft Public License + +Microsoft Permissive License (Ms-PL) + + This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + + The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the same meaning here as under U.S. copyright law. + A “contribution” is the original software, or any additions or changes to the software. + A “contributor” is any person that distributes its contribution under this license. + “Licensed patents” are a contributor’s patent claims that read directly on its contribution. + +2. Grant of Rights + + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + + (A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. + (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + (E) The software is licensed “as-is.” You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. + (F) If you distribute the software or derivative works with programs you develop, you agree to indemnify, defend, and hold harmless all contributors from any claims, including attorneys’ fees, related to the distribution or use of your programs. For clarity, you have no such obligations to a contributor for any claims based solely on the unmodified contributions of that contributor. + (G) If you make any additions or changes to the original software, you may only distribute them under a new namespace. In addition, you will clearly identify your changes or additions as your own. + +### Infozip BSD + +This is version 2009-Jan-02 of the Info-ZIP license. The definitive +version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and a +copy at http://www.info-zip.org/pub/infozip/license.html. + +Copyright (c) 1990-2009 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined +as the following set of individuals: Mark Adler, John Bush, Karl +Davis, Harald Denker, Jean-Michel Dubois, Jean-loup Gailly, Hunter +Goatley, Ed Gordon, Ian Gorman, Chris Herborth, Dirk Haase, Greg +Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, David +Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, Steve +P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, +Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, +Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, +Rich Wales, Mike White. + +This software is provided "as is," without warranty of any kind, +express or implied. In no event shall Info-ZIP or its contributors be +held liable for any direct, indirect, incidental, special or +consequential damages arising out of the use of or inability to use +this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the above disclaimer and the following +restrictions: + +Redistributions of source code (in whole or in part) must retain the +above copyright notice, definition, disclaimer, and this list of +conditions. + +Redistributions in binary form (compiled executables and libraries) +must reproduce the above copyright notice, definition, disclaimer, and +this list of conditions in documentation and/or other materials +provided with the distribution. Additional documentation is not needed +for executables where a command line license option provides these and +a note regarding this option is in the executable's startup +banner. The sole exception to this condition is redistribution of a +standard UnZipSFX binary (including SFXWiz) as part of a +self-extracting archive; that is permitted without inclusion of this +license, as long as the normal SFX banner has not been removed from +the binary or disabled. + +Altered versions--including, but not limited to, ports to new +operating systems, existing ports with new graphical interfaces, +versions with modified or added functionality, and dynamic, shared, or +static library versions not from Info-ZIP--must be plainly marked as +such and must not be misrepresented as being the original source or, +if binaries, compiled from the original source. Such altered versions +also must not be misrepresented as being Info-ZIP releases--including, +but not limited to, labeling of the altered versions with the names +"Info-ZIP" (or any variation thereof, including, but not limited to, +different capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without +the explicit permission of Info-ZIP. Such altered versions are further +prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP +e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP +will provide support for the altered versions. + +Info-ZIP retains the right to use the names "Info-ZIP," "Zip," +"UnZip," "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" +for its own source and binary releases. + +### License Creative Commons 2.5 + +// Copyright 2006 James Newton-King +// http://www.newtonsoft.com +// +// This work is licensed under the Creative Commons Attribution 2.5 License +// http://creativecommons.org/licenses/by/2.5/ +// +// You are free: +// * to copy, distribute, display, and perform the work +// * to make derivative works +// * to make commercial use of the work +// +// Under the following conditions: +// * For any reuse or distribution, you must make clear to others the license terms of this work. +// * Any of these conditions can be waived if you get permission from the copyright holder. + +From: james.newtonking@gmail.com [mailto:james.newtonking@gmail.com] On Behalf Of James Newton-King +Sent: Tuesday, June 05, 2007 6:36 AM +To: Konstantin Triger +Subject: Re: Support request by Konstantin Triger for Json.NET + +Hey Kosta + +I think it would be awesome to use Json.NET in Mono for System.Web.Extensions. + +The CC license has the following clause: Any of the above conditions can be waived if you get permission from the copyright holder. + +I can waive that statement for you and Mono. Would that be acceptable? + + +Regards, +James + +### Creative Commons Attribution 4.0 International Public License + +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + +### GPL version 2 + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. - GNU GPL: details avaliable in the file mcs/LICENSE.GPL - GNU LGPL: details available in the file mcs/LICENSE.LGPL - MIT X11: text available in the file mcs/MIT.X11 - MPL: text available in the file mcs/LICENSE.MPL + , 1 April 1989 + Ty Coon, President of Vice +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/PATENTS.TXT b/PATENTS.TXT new file mode 100644 index 00000000000..a868428bb19 --- /dev/null +++ b/PATENTS.TXT @@ -0,0 +1,44 @@ +Microsoft Patent Promise for Mono + +Microsoft Corporation and its affiliates (“Microsoft”) promise not to +assert any Applicable Patents against you for making, using, selling, +offering for sale, importing, or distributing Mono. + +If you file, maintain, or voluntarily participate in any claim in a +lawsuit alleging direct or contributory patent infringement by Mono, +or inducement of patent infringement by Mono, then your rights under +this promise will automatically terminate. + +This promise is not an assurance that (i) any Applicable Patents are +valid or enforceable or (ii) Mono does not infringe patents or other +intellectual property rights of any third party. No rights except +those expressly stated in this promise are granted, waived or received +by Microsoft, whether by implication, exhaustion, estoppel or +otherwise. This is a personal promise directly from Microsoft to you, +and you agree as a condition of benefitting from it that no Microsoft +rights are received from suppliers, distributors, or otherwise in +connection with this promise. + +Definitions: + +“Mono” means those portions of the software development technology, as +originally distributed by Xamarin, Inc. or the .NET Foundation under +the name “Mono,” that implement .NET Framework Functionality, provided +that such portions at a minimum implement all of the required parts of +the mandatory provisions of Standard ECMA-335 – Common Language +Infrastructure (CLI). + +“.NET Framework Functionality” means any functionality in Microsoft’s +.NET Framework as described in Microsoft’s API documentation on +Microsoft’s MSDN website, including the functionality in +Windowsbase.dll, but excluding all other functionality in the Windows +Presentation Foundation component of .NET Framework. + +“Applicable Patents” are those patent claims, currently owned by +Microsoft and acquired in the future, that are necessarily infringed +by Mono. For clarity, Applicable Patents do not include any patent +claims that are infringed (x) by any underlying or enabling technology +that may be used, combined, or distributed in connection with Mono +(such as hardware, operating systems, or applications that run on +Mono), (y) only as a consequence of modification of Mono, or (z) only +by the combination of Mono with third party code. diff --git a/README.md b/README.md index d3ff65bda20..5aad9440a06 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ create cross platform applications. It is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime. +The Mono project is part of the [.NET Foundation](http://www.dotnetfoundation.org/) + [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mono/mono?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 1. [Compilation and Installation](#compilation-and-installation) @@ -507,3 +509,15 @@ to do at all), first edit `.gitmodules` to point to the new location, then: The desired output diff is a change in `.gitmodules` to reflect the change in the remote URL, and a change in / where you see the desired change in the commit hash. + +License +======= + +See the LICENSE file for licensing information, and the PATENTS.TXT +file for information about Microsoft's patent grant. + +Mono Trademark Use Policy +======= + +The use of trademarks and logos for Mono can be found [here] (http://www.dotnetfoundation.org/legal/mono-tm). + diff --git a/configure.ac b/configure.ac index 7d6488d50a5..5957367b5a3 100644 --- a/configure.ac +++ b/configure.ac @@ -934,11 +934,6 @@ if test x$enable_gsharedvt = xyes; then AC_DEFINE(ENABLE_GSHAREDVT,1,[Gsharedvt]) fi -AC_ARG_ENABLE(native-types, [ --enable-native-types Enable native types], enable_native_types=$enableval, enable_native_types=no) -if test x$enable_native_types = xyes; then - AC_DEFINE(MONO_NATIVE_TYPES,1,[native types]) -fi - AC_MSG_CHECKING(for visibility __attribute__) AC_COMPILE_IFELSE([ AC_LANG_SOURCE([[ diff --git a/mcs/COPYING.LIB b/mcs/COPYING.LIB deleted file mode 100644 index 5bc8fb2c8f7..00000000000 --- a/mcs/COPYING.LIB +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/mcs/LICENSE b/mcs/LICENSE deleted file mode 100644 index ed2d1fc022c..00000000000 --- a/mcs/LICENSE +++ /dev/null @@ -1,36 +0,0 @@ - -The Mono code under the mcs/ directory is licensed under various -different licenses: - - GNU GPL: details avaliable in the file LICENSE.GPL - GNU LGPL: details available in the file LICENSE.LGPL - MIT X11: text available in the file MIT.X11 - MPL: text available in the file LICENSE.MPL - - For your convenience copies of the GNU GPL and GNU LGPL are - located in the file COPYING and COPYING.LIB. - - * Class Libraries: - - All of the core classes licensed under the terms of - the MIT X11 license. - - Third party libraries that we distribute for - convenience reasons are distributed under their own - terms (all of them allow development of proprietary - applications with them). - - Third party libraries include: ByteFX.Data, - ICSharpCode.SharpZipLib, Npgsql, MicrosoftAjaxLibrary. - - The Microsoft.JScript assembly is covered by the - MIT X11 and the Mozilla MPL license as it contains - ported pieces of code from Rhino, the Mozilla JavaScript - implementations - - * Mono C# compiler: Dual licensed MIT X11 and GNU GPL. - - * Mono Basic compiler: GNU GPL. - - * Various tools in the `tools' directory: GNU GPL. - diff --git a/mcs/LICENSE.CC b/mcs/LICENSE.CC deleted file mode 100644 index 61147536bad..00000000000 --- a/mcs/LICENSE.CC +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2006 James Newton-King -// http://www.newtonsoft.com -// -// This work is licensed under the Creative Commons Attribution 2.5 License -// http://creativecommons.org/licenses/by/2.5/ -// -// You are free: -// * to copy, distribute, display, and perform the work -// * to make derivative works -// * to make commercial use of the work -// -// Under the following conditions: -// * For any reuse or distribution, you must make clear to others the license terms of this work. -// * Any of these conditions can be waived if you get permission from the copyright holder. - -From: james.newtonking@gmail.com [mailto:james.newtonking@gmail.com] On Behalf Of James Newton-King -Sent: Tuesday, June 05, 2007 6:36 AM -To: Konstantin Triger -Subject: Re: Support request by Konstantin Triger for Json.NET - -Hey Kosta - -I think it would be awesome to use Json.NET in Mono for System.Web.Extensions. - -The CC license has the following clause: Any of the above conditions can be waived if you get permission from the copyright holder. - -I can waive that statement for you and Mono. Would that be acceptable? - - -Regards, -James diff --git a/mcs/LICENSE.GPL b/mcs/LICENSE.GPL deleted file mode 100644 index b236c5684dd..00000000000 --- a/mcs/LICENSE.GPL +++ /dev/null @@ -1,15 +0,0 @@ - Mono compilers and tools. - Copyright (C) 2001, 2002, 2003, Ximian and contributors. - - 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; - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA diff --git a/mcs/LICENSE.LGPL b/mcs/LICENSE.LGPL deleted file mode 100644 index 7447504f516..00000000000 --- a/mcs/LICENSE.LGPL +++ /dev/null @@ -1,15 +0,0 @@ - Mono class libraries - Copyright (C) Mono project (authors listed in individual ChangeLog entries) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/mcs/LICENSE.MPL b/mcs/LICENSE.MPL deleted file mode 100644 index 7714141d154..00000000000 --- a/mcs/LICENSE.MPL +++ /dev/null @@ -1,470 +0,0 @@ - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (the "License"); you may not use this file except in - compliance with the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] - diff --git a/mcs/LICENSE.MSPL b/mcs/LICENSE.MSPL deleted file mode 100644 index 79629b21e3a..00000000000 --- a/mcs/LICENSE.MSPL +++ /dev/null @@ -1,27 +0,0 @@ -Microsoft Permissive License (Ms-PL) - - This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. - -1. Definitions - - The terms “reproduce,” “reproduction,” “derivative works,” and “distribution” have the same meaning here as under U.S. copyright law. - A “contribution” is the original software, or any additions or changes to the software. - A “contributor” is any person that distributes its contribution under this license. - “Licensed patents” are a contributor’s patent claims that read directly on its contribution. - -2. Grant of Rights - - (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. - (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. - -3. Conditions and Limitations - - (A) No Trademark License- This license does not grant you rights to use any contributors’ name, logo, or trademarks. - (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. - (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. - (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. - (E) The software is licensed “as-is.” You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. - (F) If you distribute the software or derivative works with programs you develop, you agree to indemnify, defend, and hold harmless all contributors from any claims, including attorneys’ fees, related to the distribution or use of your programs. For clarity, you have no such obligations to a contributor for any claims based solely on the unmodified contributions of that contributor. - (G) If you make any additions or changes to the original software, you may only distribute them under a new namespace. In addition, you will clearly identify your changes or additions as your own. - - diff --git a/mcs/MIT.X11 b/mcs/MIT.X11 deleted file mode 100644 index cb4a84d096e..00000000000 --- a/mcs/MIT.X11 +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2001, 2002, 2003 Ximian, Inc and the individuals listed -on the ChangeLog entries. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mcs/Makefile b/mcs/Makefile index e31193319f1..1f4566b61c7 100644 --- a/mcs/Makefile +++ b/mcs/Makefile @@ -88,10 +88,6 @@ DISTFILES = \ COPYING \ COPYING.LIB \ INSTALL.txt \ - LICENSE \ - LICENSE.GPL \ - LICENSE.LGPL \ - LICENSE.MPL \ Makefile \ mkinstalldirs \ MIT.X11 \ diff --git a/mcs/README b/mcs/README index 2a64e0f6ef6..f23a12d69bf 100644 --- a/mcs/README +++ b/mcs/README @@ -85,46 +85,3 @@ If you want to only run the tests in a single fixture (say Thanks a lot to Sergey Chaban for his help during the development of the C# compiler. -* LICENSE -========= - -The mcs C# compiler and monoresgen are licensed to you under the GPL, version 2. -The complete text of the GPL is in the 'COPYING' file. - - Copyright (C) 2001-2002 Ximian, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -The class libraries are licensed according to the following license: - - Copyright (C) 2001-2002 Ximian, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - diff --git a/mcs/class/Mono.Security/monotouch_Mono.Security.dll.sources b/mcs/class/Mono.Security/monotouch_Mono.Security.dll.sources index 513dc61bd4f..17f56e3c405 100644 --- a/mcs/class/Mono.Security/monotouch_Mono.Security.dll.sources +++ b/mcs/class/Mono.Security/monotouch_Mono.Security.dll.sources @@ -1 +1,6 @@ #include mobile_Mono.Security.dll.sources +../corlib/CommonCrypto/CommonCrypto.cs +../corlib/CommonCrypto/RC4CommonCrypto.cs +../corlib/CommonCrypto/MD2Managed.g.cs +../corlib/CommonCrypto/MD4Managed.g.cs +../corlib/CommonCrypto/SHA224Managed.g.cs diff --git a/mcs/class/Mono.Security/monotouch_opt_Mono.Security.dll.sources b/mcs/class/Mono.Security/monotouch_opt_Mono.Security.dll.sources deleted file mode 100644 index e8464be185b..00000000000 --- a/mcs/class/Mono.Security/monotouch_opt_Mono.Security.dll.sources +++ /dev/null @@ -1,4 +0,0 @@ -./Mono.Security.Cryptography/ARC4Managed.cs -./Mono.Security.Cryptography/MD2Managed.cs -./Mono.Security.Cryptography/MD4Managed.cs -./Mono.Security.Cryptography/SHA224Managed.cs diff --git a/mcs/class/Mono.Security/xammac_Mono.Security.dll.sources b/mcs/class/Mono.Security/xammac_Mono.Security.dll.sources index 1379fa79d80..6c1b4dbef6f 100644 --- a/mcs/class/Mono.Security/xammac_Mono.Security.dll.sources +++ b/mcs/class/Mono.Security/xammac_Mono.Security.dll.sources @@ -1,2 +1,7 @@ #include monotouch_Mono.Security.dll.sources +../corlib/CommonCrypto/CommonCrypto.cs +../corlib/CommonCrypto/RC4CommonCrypto.cs +../corlib/CommonCrypto/MD2Managed.g.cs +../corlib/CommonCrypto/MD4Managed.g.cs +../corlib/CommonCrypto/SHA224Managed.g.cs diff --git a/mcs/class/Mono.Security/xammac_opt_Mono.Security.dll.sources b/mcs/class/Mono.Security/xammac_opt_Mono.Security.dll.sources deleted file mode 100644 index e8464be185b..00000000000 --- a/mcs/class/Mono.Security/xammac_opt_Mono.Security.dll.sources +++ /dev/null @@ -1,4 +0,0 @@ -./Mono.Security.Cryptography/ARC4Managed.cs -./Mono.Security.Cryptography/MD2Managed.cs -./Mono.Security.Cryptography/MD4Managed.cs -./Mono.Security.Cryptography/SHA224Managed.cs diff --git a/mcs/class/Mono.WebBrowser/tools/xpidl2cs/xpidl2cs.pl b/mcs/class/Mono.WebBrowser/tools/xpidl2cs/xpidl2cs.pl index 8aabd350f40..0e2a0119090 100755 --- a/mcs/class/Mono.WebBrowser/tools/xpidl2cs/xpidl2cs.pl +++ b/mcs/class/Mono.WebBrowser/tools/xpidl2cs/xpidl2cs.pl @@ -6,20 +6,7 @@ # # Copyright (c) 2007 Novell, Inc. # -# This program is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License as published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this program; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -############################################################## +# Licensed under the MIT license. See LICENSE file in the project root for full license information. diff --git a/mcs/class/System.Core/monotouch_System.Core.dll.sources b/mcs/class/System.Core/monotouch_System.Core.dll.sources index 7d32d44a88b..6b6d96c25a2 100644 --- a/mcs/class/System.Core/monotouch_System.Core.dll.sources +++ b/mcs/class/System.Core/monotouch_System.Core.dll.sources @@ -1,2 +1,4 @@ #include common_System.Core.dll.sources #include interpreter_System.Core.dll.sources +../corlib/CommonCrypto/AesManaged.g.cs +../corlib/CommonCrypto/AesCryptoServiceProvider.g.cs diff --git a/mcs/class/System.Core/xammac_System.Core.dll.sources b/mcs/class/System.Core/xammac_System.Core.dll.sources index 882476b4b5e..6ab44f0f8c2 100644 --- a/mcs/class/System.Core/xammac_System.Core.dll.sources +++ b/mcs/class/System.Core/xammac_System.Core.dll.sources @@ -1,4 +1,5 @@ #include common_System.Core.dll.sources #include dynamic_System.Core.dll.sources - +../corlib/CommonCrypto/AesManaged.g.cs +../corlib/CommonCrypto/AesCryptoServiceProvider.g.cs diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs new file mode 100644 index 00000000000..42f664c0ed3 --- /dev/null +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClient.mac.cs @@ -0,0 +1,23 @@ +using System; +using System.Reflection; + +[assembly:System.Runtime.CompilerServices.InternalsVisibleTo ("Xamarin.Mac, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")] + +namespace System.Net.Http { + public partial class HttpClient { + + public HttpClient () + : this (GetDefaultHandler (), true) + { + } + + // note: the linker will re-write ObjCRuntime.RuntimeOptions.GetHttpMessageHandler to return the correct type + // unlike, XI where this method itself gets rewritten during linking + static HttpMessageHandler GetDefaultHandler () + { + Type type = Type.GetType("ObjCRuntime.RuntimeOptions, Xamarin.Mac"); + var method = type.GetMethod ("GetHttpMessageHandler", BindingFlags.Static | BindingFlags.NonPublic); + return (HttpMessageHandler)method.Invoke (null, null); + } + } +} diff --git a/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources index fbffe9e7634..216e48da9cd 100644 --- a/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources +++ b/mcs/class/System.Net.Http/xammac_System.Net.Http.dll.sources @@ -1 +1,2 @@ #include System.Net.Http.dll.sources +System.Net.Http/HttpClient.mac.cs diff --git a/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources b/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources index fbffe9e7634..216e48da9cd 100644 --- a/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources +++ b/mcs/class/System.Net.Http/xammac_net_4_5_System.Net.Http.dll.sources @@ -1 +1,2 @@ #include System.Net.Http.dll.sources +System.Net.Http/HttpClient.mac.cs diff --git a/mcs/class/System/Assembly/AssemblyInfoEx.cs b/mcs/class/System/Assembly/AssemblyInfoEx.cs new file mode 100644 index 00000000000..22e5bcae292 --- /dev/null +++ b/mcs/class/System/Assembly/AssemblyInfoEx.cs @@ -0,0 +1,7 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo ("monotouch, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")] +[assembly: InternalsVisibleTo ("Xamarin.iOS, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")] +[assembly: InternalsVisibleTo ("Xamarin.Mac, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")] +[assembly: InternalsVisibleTo ("Xamarin.WatchOS, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")] +[assembly: InternalsVisibleTo ("Xamarin.TVOS, PublicKey=0024000004800000940000000602000000240000525341310004000011000000438ac2a5acfbf16cbd2b2b47a62762f273df9cb2795ceccdf77d10bf508e69e7a362ea7a45455bbf3ac955e1f2e2814f144e5d817efc4c6502cc012df310783348304e3ae38573c6d658c234025821fda87a0be8a0d504df564e2c93b2b878925f42503e9d54dfef9f9586d9e6f38a305769587b1de01f6c0410328b2c9733db")] diff --git a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.MonoTouch.opt.cs b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.MonoTouch.opt.cs deleted file mode 100644 index b8c5d6db3e1..00000000000 --- a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactory.MonoTouch.opt.cs +++ /dev/null @@ -1,15 +0,0 @@ -#if MONOTOUCH || XAMMAC - -// this file is a shim to enable compiling monotouch profiles without mono-extensions -namespace Mono.Net.Security -{ - static partial class MonoTlsProviderFactory - { - static IMonoTlsProvider CreateDefaultProvider () - { - throw new System.NotSupportedException (); - } - } -} - -#endif diff --git a/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactoryExt.cs b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactoryExt.cs new file mode 100644 index 00000000000..f9f939bb4d2 --- /dev/null +++ b/mcs/class/System/Mono.Net.Security/MonoTlsProviderFactoryExt.cs @@ -0,0 +1,22 @@ +// Copyright 2015 Xamarin Inc. All rights reserved. + +using System; +using MSI = Mono.Security.Interface; + +namespace Mono.Net.Security +{ + static partial class MonoTlsProviderFactory + { + static IMonoTlsProvider CreateDefaultProvider () + { + #if SECURITY_DEP + MSI.MonoTlsProvider provider = null; + if (MSI.MonoTlsProviderFactory._PrivateFactoryDelegate != null) + provider = MSI.MonoTlsProviderFactory._PrivateFactoryDelegate (); + if (provider != null) + return new Private.MonoTlsProviderWrapper (provider); + #endif + return null; + } + } +} diff --git a/mcs/class/System/Mono.Security.Interface/MonoTlsProviderFactoryExt.cs b/mcs/class/System/Mono.Security.Interface/MonoTlsProviderFactoryExt.cs new file mode 100644 index 00000000000..e902c802d36 --- /dev/null +++ b/mcs/class/System/Mono.Security.Interface/MonoTlsProviderFactoryExt.cs @@ -0,0 +1,9 @@ +namespace Mono.Security.Interface +{ + public delegate MonoTlsProvider MonoTlsProviderFactoryDelegate (); + + static partial class MonoTlsProviderFactory + { + public static MonoTlsProviderFactoryDelegate _PrivateFactoryDelegate; + } +} diff --git a/mcs/class/System/monotouch_System.dll.sources b/mcs/class/System/monotouch_System.dll.sources index 8dce31d234c..8f3de2eff5d 100644 --- a/mcs/class/System/monotouch_System.dll.sources +++ b/mcs/class/System/monotouch_System.dll.sources @@ -1,2 +1,5 @@ #include mobile_System.dll.sources MonoTouch/MonoPInvokeCallbackAttribute.cs +Assembly/AssemblyInfoEx.cs +Mono.Net.Security/MonoTlsProviderFactoryExt.cs +Mono.Security.Interface/MonoTlsProviderFactoryExt.cs diff --git a/mcs/class/System/monotouch_opt_System.dll.sources b/mcs/class/System/monotouch_opt_System.dll.sources deleted file mode 100644 index 68774577148..00000000000 --- a/mcs/class/System/monotouch_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -Mono.Net.Security/MonoTlsProviderFactory.MonoTouch.opt.cs diff --git a/mcs/class/System/monotouch_runtime_opt_System.dll.sources b/mcs/class/System/monotouch_runtime_opt_System.dll.sources deleted file mode 100644 index 54025c51efd..00000000000 --- a/mcs/class/System/monotouch_runtime_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_System.dll.sources diff --git a/mcs/class/System/monotouch_tv_opt_System.dll.sources b/mcs/class/System/monotouch_tv_opt_System.dll.sources deleted file mode 100644 index 54025c51efd..00000000000 --- a/mcs/class/System/monotouch_tv_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_System.dll.sources diff --git a/mcs/class/System/monotouch_tv_runtime_opt_System.dll.sources b/mcs/class/System/monotouch_tv_runtime_opt_System.dll.sources deleted file mode 100644 index 54025c51efd..00000000000 --- a/mcs/class/System/monotouch_tv_runtime_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_System.dll.sources diff --git a/mcs/class/System/monotouch_watch_opt_System.dll.sources b/mcs/class/System/monotouch_watch_opt_System.dll.sources deleted file mode 100644 index 54025c51efd..00000000000 --- a/mcs/class/System/monotouch_watch_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_System.dll.sources diff --git a/mcs/class/System/monotouch_watch_runtime_opt_System.dll.sources b/mcs/class/System/monotouch_watch_runtime_opt_System.dll.sources deleted file mode 100644 index 54025c51efd..00000000000 --- a/mcs/class/System/monotouch_watch_runtime_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_System.dll.sources diff --git a/mcs/class/System/xammac_System.dll.sources b/mcs/class/System/xammac_System.dll.sources index 70a77a6dbff..330f5106870 100644 --- a/mcs/class/System/xammac_System.dll.sources +++ b/mcs/class/System/xammac_System.dll.sources @@ -1 +1,4 @@ #include mobile_System.dll.sources +Assembly/AssemblyInfoEx.cs +Mono.Net.Security/MonoTlsProviderFactoryExt.cs +Mono.Security.Interface/MonoTlsProviderFactoryExt.cs diff --git a/mcs/class/System/xammac_net_4_5_System.dll.sources b/mcs/class/System/xammac_net_4_5_System.dll.sources index 3ff0aad1cfb..7e48f7ecc9d 100644 --- a/mcs/class/System/xammac_net_4_5_System.dll.sources +++ b/mcs/class/System/xammac_net_4_5_System.dll.sources @@ -1 +1,2 @@ #include System.dll.sources +Assembly/AssemblyInfoEx.cs diff --git a/mcs/class/System/xammac_net_4_5_opt_System.dll.sources b/mcs/class/System/xammac_net_4_5_opt_System.dll.sources deleted file mode 100644 index 86ff246428c..00000000000 --- a/mcs/class/System/xammac_net_4_5_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include xammac_opt_System.dll.sources diff --git a/mcs/class/System/xammac_opt_System.dll.sources b/mcs/class/System/xammac_opt_System.dll.sources deleted file mode 100644 index 68774577148..00000000000 --- a/mcs/class/System/xammac_opt_System.dll.sources +++ /dev/null @@ -1 +0,0 @@ -Mono.Net.Security/MonoTlsProviderFactory.MonoTouch.opt.cs diff --git a/mcs/class/corlib/CommonCrypto/.gitignore b/mcs/class/corlib/CommonCrypto/.gitignore new file mode 100644 index 00000000000..1252b936471 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/.gitignore @@ -0,0 +1,2 @@ +*.g.cs +generator.exe diff --git a/mcs/class/corlib/CommonCrypto/CommonCrypto.cs b/mcs/class/corlib/CommonCrypto/CommonCrypto.cs new file mode 100644 index 00000000000..c765b957352 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/CommonCrypto.cs @@ -0,0 +1,130 @@ +// CommonCrypto bindings for MonoMac and MonoTouch +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2014 Xamarin Inc. + +using System; +using System.Security.Cryptography; +using System.Runtime.InteropServices; + +namespace Crimson.CommonCrypto { + + // int32_t -> CommonCryptor.h + enum CCCryptorStatus { + Success = 0, + ParamError = -4300, + BufferTooSmall = -4301, + MemoryFailure = -4302, + AlignmentError = -4303, + DecodeError = -4304, + Unimplemented = -4305 + } + + // uint32_t -> CommonCryptor.h + // note: not exposed publicly so it can stay signed + enum CCOperation { + Encrypt = 0, + Decrypt, + } + + // uint32_t -> CommonCryptor.h + // note: not exposed publicly so it can stay signed + enum CCAlgorithm { + AES128 = 0, + DES, + TripleDES, + CAST, + RC4, + RC2, + Blowfish + } + + // uint32_t -> CommonCryptor.h + // note: not exposed publicly so it can stay signed + [Flags] + enum CCOptions { + None = 0, + PKCS7Padding = 1, + ECBMode = 2 + } + + static class Cryptor { + + const string libSystem = "/usr/lib/libSystem.dylib"; + + // size_t was changed to IntPtr for 32/64 bits size difference - even if mono is (moslty) used in 32bits only on OSX today + // not using `nint` to be able to resue this outside (if needed) + + [DllImport (libSystem)] + extern internal static CCCryptorStatus CCCryptorCreate (CCOperation op, CCAlgorithm alg, CCOptions options, /* const void* */ byte[] key, /* size_t */ IntPtr keyLength, /* const void* */ byte[] iv, /* CCCryptorRef* */ ref IntPtr cryptorRef); + + [DllImport (libSystem)] + extern internal static CCCryptorStatus CCCryptorRelease (/* CCCryptorRef */ IntPtr cryptorRef); + + [DllImport (libSystem)] + extern internal static CCCryptorStatus CCCryptorUpdate (/* CCCryptorRef */ IntPtr cryptorRef, /* const void* */ byte[] dataIn, /* size_t */ IntPtr dataInLength, /* void* */ byte[] dataOut, /* size_t */ IntPtr dataOutAvailable, /* size_t* */ ref IntPtr dataOutMoved); + + [DllImport (libSystem)] + extern internal static CCCryptorStatus CCCryptorUpdate (/* CCCryptorRef */ IntPtr cryptorRef, /* const void* */ IntPtr dataIn, /* size_t */ IntPtr dataInLength, /* void* */ IntPtr dataOut, /* size_t */ IntPtr dataOutAvailable, /* size_t* */ ref IntPtr dataOutMoved); + + [DllImport (libSystem)] + extern internal static CCCryptorStatus CCCryptorFinal (/* CCCryptorRef */ IntPtr cryptorRef, /* void* */ byte[] dataOut, /* size_t */ IntPtr dataOutAvailable, /* size_t* */ ref IntPtr dataOutMoved); + + [DllImport (libSystem)] + extern internal static int CCCryptorGetOutputLength (/* CCCryptorRef */ IntPtr cryptorRef, /* size_t */ IntPtr inputLength, bool final); + + [DllImport (libSystem)] + extern internal static CCCryptorStatus CCCryptorReset (/* CCCryptorRef */ IntPtr cryptorRef, /* const void* */ IntPtr iv); + + // helper method to reduce the amount of generate code for each cipher algorithm + static internal IntPtr Create (CCOperation operation, CCAlgorithm algorithm, CCOptions options, byte[] key, byte[] iv) + { + if (key == null) + throw new CryptographicException ("A null key was provided"); + + // unlike the .NET framework CommonCrypto does not support two-keys triple-des (128 bits) ref: #6967 + if ((algorithm == CCAlgorithm.TripleDES) && (key.Length == 16)) { + byte[] key3 = new byte [24]; + Buffer.BlockCopy (key, 0, key3, 0, 16); + Buffer.BlockCopy (key, 0, key3, 16, 8); + key = key3; + } + + IntPtr cryptor = IntPtr.Zero; + CCCryptorStatus status = Cryptor.CCCryptorCreate (operation, algorithm, options, key, (IntPtr) key.Length, iv, ref cryptor); + if (status != CCCryptorStatus.Success) + throw new CryptographicUnexpectedOperationException (); + return cryptor; + } + + // size_t was changed to IntPtr for 32/64 bits size difference - even if mono is (moslty) used in 32bits only on OSX today + [DllImport ("/System/Library/Frameworks/Security.framework/Security")] + extern internal static /* int */ int SecRandomCopyBytes (/* SecRandomRef */ IntPtr rnd, /* size_t */ IntPtr count, /* uint8_t* */ byte[] bytes); + + static internal void GetRandom (byte[] buffer) + { + if (SecRandomCopyBytes (IntPtr.Zero, (IntPtr) buffer.Length, buffer) != 0) + throw new CryptographicException (Marshal.GetLastWin32Error ()); // errno + } + } + +#if !MONOTOUCH && !XAMMAC + static class KeyBuilder { + static public byte[] Key (int size) + { + byte[] buffer = new byte [size]; + Cryptor.GetRandom (buffer); + return buffer; + } + + static public byte[] IV (int size) + { + byte[] buffer = new byte [size]; + Cryptor.GetRandom (buffer); + return buffer; + } + } +#endif +} diff --git a/mcs/class/corlib/CommonCrypto/CommonCryptorGenerator.cs b/mcs/class/corlib/CommonCrypto/CommonCryptorGenerator.cs new file mode 100644 index 00000000000..f177c17ef3a --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/CommonCryptorGenerator.cs @@ -0,0 +1,104 @@ +// +// CommonCrypto code generator for symmetric block cipher algorithms +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. +// + +using System; +using System.IO; + +namespace Xamarin { + + public static class CommonCryptor { + + static public void Generate (string namespaceName, string typeName, string baseTypeName, string ccAlgorithmName, string feedbackSize = "8", string ctorInitializers = null) + { + string template = @"// Generated file to bind CommonCrypto cipher algorithms - DO NOT EDIT +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2014 Xamarin Inc. + +using System; +using System.Security.Cryptography; + +using Mono.Security.Cryptography; +using Crimson.CommonCrypto; + +namespace %NAMESPACE% { + + public sealed partial class %TYPE% : %BASE% { + + public %TYPE% () + { + FeedbackSizeValue = %FEEDBACKSIZE%; + %CTOR_INIT% + } + + public override void GenerateIV () + { + IVValue = KeyBuilder.IV (BlockSizeValue >> 3); + } + + public override void GenerateKey () + { + KeyValue = KeyBuilder.Key (KeySizeValue >> 3); + } + + public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) + { + IntPtr decryptor = IntPtr.Zero; + switch (Mode) { + case CipherMode.CBC: + decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.None, rgbKey, rgbIV); + return new FastCryptorTransform (decryptor, this, false, rgbIV); + case CipherMode.ECB: + decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV); + return new FastCryptorTransform (decryptor, this, false, rgbIV); + case CipherMode.CFB: +#if MONOTOUCH || XAMMAC + IntPtr encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV); + decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV); + return new CryptorTransform (decryptor, encryptor, this, false, rgbIV); +#else + throw new CryptographicException (""CFB is not supported by Crimson.CommonCrypto""); +#endif + default: + throw new CryptographicException (String.Format (""{0} is not supported by the .NET framework"", Mode)); + } + } + + public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) + { + IntPtr encryptor = IntPtr.Zero; + switch (Mode) { + case CipherMode.CBC: + encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.None, rgbKey, rgbIV); + return new FastCryptorTransform (encryptor, this, true, rgbIV); + case CipherMode.ECB: + encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV); + return new FastCryptorTransform (encryptor, this, true, rgbIV); + case CipherMode.CFB: +#if MONOTOUCH || XAMMAC + encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.%CCALGORITHM%, CCOptions.ECBMode, rgbKey, rgbIV); + return new CryptorTransform (encryptor, IntPtr.Zero, this, true, rgbIV); +#else + throw new CryptographicException (""CFB is not supported by Crimson.CommonCrypto""); +#endif + default: + throw new CryptographicException (String.Format (""{0} is not supported by the .NET framework"", Mode)); + } + } + } +}"; + + File.WriteAllText (typeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName). + Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName).Replace("%FEEDBACKSIZE%", feedbackSize).Replace ("%CTOR_INIT%", ctorInitializers). + Replace ("%CCALGORITHM%", ccAlgorithmName.ToString ())); + } + } +} diff --git a/mcs/class/corlib/CommonCrypto/CommonDigestGenerator.cs b/mcs/class/corlib/CommonCrypto/CommonDigestGenerator.cs new file mode 100644 index 00000000000..1b729e376bf --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/CommonDigestGenerator.cs @@ -0,0 +1,167 @@ +// +// CommonCrypto code generator for digest algorithms +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2014 Xamarin Inc. +// + +using System; +using System.IO; + +namespace Xamarin { + + public static class CommonDigest { + +#if !MONOTOUCH && !XAMMAC + // we do not add anything in MonoTouch, just replacing, so this is not needed + // however we can avoid a dependency on Mono.Security for Crimson.CommonCrypto.dll by including the base classes + static public void GenerateBaseClass (string namespaceName, string typeName, string baseTypeName, int hashSize, + string visibilityStart = "", string visibilityEnd = "") + { + string template = @"// Generated file to bind CommonCrypto/CommonDigest - DO NOT EDIT +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012-2014 Xamarin Inc. + +using System; +using System.Security.Cryptography; +using System.Runtime.InteropServices; + +namespace %NAMESPACE% { + +%VISIBILITY_START% + public +%VISIBILITY_END% + abstract class %BASE% : HashAlgorithm { + + protected %BASE% () + { + HashSizeValue = %HASHSIZE%; + } + + public static new %BASE% Create () + { + return Create (""%BASE%""); + } + + public static new %BASE% Create (string hashName) + { + object o = CryptoConfig.CreateFromName (hashName); + return (%BASE%) o ?? new %TYPE% (); + } + } +}"; + + File.WriteAllText (baseTypeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName). + Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName). + Replace ("%VISIBILITY_START%", visibilityStart).Replace ("%VISIBILITY_END%", visibilityEnd). + Replace ("%HASHSIZE%", hashSize.ToString ())); + } +#endif + static public void Generate (string namespaceName, string typeName, string baseTypeName, int contextSize, + string visibilityStart = "", string visibilityEnd = "") + { + string template = @"// Generated file to bind CommonCrypto/CommonDigest - DO NOT EDIT +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2011-2014 Xamarin Inc. + +using System; +using System.Security.Cryptography; +using System.Runtime.InteropServices; + +using Mono.Security.Cryptography; + +namespace %NAMESPACE% { + +%VISIBILITY_START% + public +%VISIBILITY_END% + sealed class %TYPE% : %BASE% { + + IntPtr ctx; + + [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Init"")] + static extern int Init (/* CC_%BASE%_CTX */ IntPtr c); + + [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Update"")] + static extern int Update (/* CC_%BASE%_CTX */ IntPtr c, /* const void * */ IntPtr data, /* uint32_t */ uint len); + + [DllImport (""/usr/lib/libSystem.dylib"", EntryPoint=""CC_%BASE%_Final"")] + static extern int Final (/* unsigned char * */ byte [] md, /* CC_%BASE%_CTX */ IntPtr c); + + public %TYPE% () + { + ctx = IntPtr.Zero; + } + + ~%TYPE% () + { + Dispose (false); + } + + protected override void Dispose (bool disposing) + { + if (ctx != IntPtr.Zero) { + Marshal.FreeHGlobal (ctx); + ctx = IntPtr.Zero; + } + base.Dispose (disposing); + GC.SuppressFinalize (this); + } + + public override void Initialize () + { + if (ctx == IntPtr.Zero) + ctx = Marshal.AllocHGlobal (%CTX_SIZE%); + + int hr = Init (ctx); + if (hr != 1) + throw new CryptographicException (hr); + } + + protected override void HashCore (byte[] data, int start, int length) + { + if (ctx == IntPtr.Zero) + Initialize (); + + if (data.Length == 0) + return; + + unsafe { + fixed (byte* p = &data [0]) { + int hr = Update (ctx, (IntPtr) (p + start), (uint) length); + if (hr != 1) + throw new CryptographicException (hr); + } + } + } + + protected override byte[] HashFinal () + { + if (ctx == IntPtr.Zero) + Initialize (); + + byte[] data = new byte [HashSize >> 3]; + int hr = Final (data, ctx); + if (hr != 1) + throw new CryptographicException (hr); + + return data; + } + } +}"; + + File.WriteAllText (typeName + ".g.cs", template.Replace ("%NAMESPACE%", namespaceName). + Replace ("%TYPE%", typeName).Replace ("%BASE%", baseTypeName). + Replace ("%VISIBILITY_START%", visibilityStart).Replace ("%VISIBILITY_END%", visibilityEnd). + Replace ("%CTX_SIZE%", contextSize.ToString ())); + } + } +} diff --git a/mcs/class/corlib/CommonCrypto/CorlibExtras.cs b/mcs/class/corlib/CommonCrypto/CorlibExtras.cs new file mode 100644 index 00000000000..5bdc69a215e --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/CorlibExtras.cs @@ -0,0 +1,24 @@ +// +// CorlibExtras.cs: additional stuff not provided by autogenerated code +// +// Authors: +// Sebastien Pouliot (sebastien@xamarun.com) +// +// Copyright (C) 2012 Xamarin Inc. All rights reserved. +// + +namespace System.Security.Cryptography { + + // required to ensure compatibility with MS implementation + public sealed partial class RC2CryptoServiceProvider : RC2 { + + public override int EffectiveKeySize { + get { return base.EffectiveKeySize; } + set { + if (value != KeySizeValue) + throw new CryptographicUnexpectedOperationException ("Effective key size must match key size for compatibility"); + base.EffectiveKeySize = value; + } + } + } +} diff --git a/mcs/class/corlib/CommonCrypto/CryptorTransform.cs b/mcs/class/corlib/CommonCrypto/CryptorTransform.cs new file mode 100644 index 00000000000..10ca6fad8f6 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/CryptorTransform.cs @@ -0,0 +1,60 @@ +// ICryptoTransform implementation on top of CommonCrypto and SymmetricTransform +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. + +using System; +using System.Security.Cryptography; + +using Mono.Security.Cryptography; + +namespace Crimson.CommonCrypto { + + class CryptorTransform : SymmetricTransform { + + IntPtr handle; + IntPtr handle_e; + bool encryption; + + public CryptorTransform (IntPtr cryptor, IntPtr special, SymmetricAlgorithm algo, bool encryption, byte[] iv) + : base (algo, encryption, iv) + { + handle = cryptor; + // for CFB we need to encrypt data while decrypting + handle_e = special; + this.encryption = encryption; + } + + ~CryptorTransform () + { + Dispose (false); + } + + // PRO: doing this ensure all cipher modes and padding modes supported by .NET will be available with CommonCrypto (drop-in replacements) + // CON: doing this will only process one block at the time, so it's not ideal for performance, but still a lot better than managed + protected override void ECB (byte[] input, byte[] output) + { + IntPtr len = IntPtr.Zero; + CCCryptorStatus s = Cryptor.CCCryptorUpdate ((encrypt == encryption) ? handle : handle_e, + input, (IntPtr) input.Length, output, (IntPtr) output.Length, ref len); + if (((int) len != output.Length) || (s != CCCryptorStatus.Success)) + throw new CryptographicUnexpectedOperationException (s.ToString ()); + } + + protected override void Dispose (bool disposing) + { + if (handle != IntPtr.Zero) { + Cryptor.CCCryptorRelease (handle); + handle = IntPtr.Zero; + } + if (handle_e != IntPtr.Zero) { + Cryptor.CCCryptorRelease (handle_e); + handle_e = IntPtr.Zero; + } + base.Dispose (disposing); + GC.SuppressFinalize (this); + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/CommonCrypto/FastCryptorTransform.cs b/mcs/class/corlib/CommonCrypto/FastCryptorTransform.cs new file mode 100644 index 00000000000..9ff7a5a8563 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/FastCryptorTransform.cs @@ -0,0 +1,348 @@ +// Fast, multi-block, ICryptoTransform implementation on top of CommonCrypto +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. + +using System; +using System.Security.Cryptography; + +using Mono.Security.Cryptography; + +namespace Crimson.CommonCrypto { + + unsafe class FastCryptorTransform : ICryptoTransform { + + IntPtr handle; + bool encrypt; + int BlockSizeByte; + byte[] workBuff; + bool lastBlock; + PaddingMode padding; + + public FastCryptorTransform (IntPtr cryptor, SymmetricAlgorithm algo, bool encryption, byte[] iv) + { + BlockSizeByte = (algo.BlockSize >> 3); + + if (iv == null) { + iv = KeyBuilder.IV (BlockSizeByte); + } else if (iv.Length < BlockSizeByte) { + string msg = String.Format ("IV is too small ({0} bytes), it should be {1} bytes long.", + iv.Length, BlockSizeByte); + throw new CryptographicException (msg); + } + + handle = cryptor; + encrypt = encryption; + padding = algo.Padding; + // transform buffer + workBuff = new byte [BlockSizeByte]; + } + + ~FastCryptorTransform () + { + Dispose (false); + } + + public void Dispose () + { + Dispose (true); + } + + protected virtual void Dispose (bool disposing) + { + if (handle != IntPtr.Zero) { + Cryptor.CCCryptorRelease (handle); + handle = IntPtr.Zero; + } + GC.SuppressFinalize (this); + } + + public virtual bool CanTransformMultipleBlocks { + get { return true; } + } + + public virtual bool CanReuseTransform { + get { return false; } + } + + public virtual int InputBlockSize { + get { return BlockSizeByte; } + } + + public virtual int OutputBlockSize { + get { return BlockSizeByte; } + } + + int Transform (byte[] input, int inputOffset, byte[] output, int outputOffset, int length) + { + IntPtr len = IntPtr.Zero; + IntPtr in_len = (IntPtr) length; + IntPtr out_len = (IntPtr) (output.Length - outputOffset); + fixed (byte* inputBuffer = &input [0]) + fixed (byte* outputBuffer = &output [0]) { + CCCryptorStatus s = Cryptor.CCCryptorUpdate (handle, (IntPtr) (inputBuffer + inputOffset), in_len, (IntPtr) (outputBuffer + outputOffset), out_len, ref len); + if (s != CCCryptorStatus.Success) + throw new CryptographicException (s.ToString ()); + } + return (int) len; + } + + private void CheckInput (byte[] inputBuffer, int inputOffset, int inputCount) + { + if (inputBuffer == null) + throw new ArgumentNullException ("inputBuffer"); + if (inputOffset < 0) + throw new ArgumentOutOfRangeException ("inputOffset", "< 0"); + if (inputCount < 0) + throw new ArgumentOutOfRangeException ("inputCount", "< 0"); + // ordered to avoid possible integer overflow + if (inputOffset > inputBuffer.Length - inputCount) + throw new ArgumentException ("inputBuffer", "Overflow"); + } + + // this method may get called MANY times so this is the one to optimize + public virtual int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) + { + CheckInput (inputBuffer, inputOffset, inputCount); + // check output parameters + if (outputBuffer == null) + throw new ArgumentNullException ("outputBuffer"); + if (outputOffset < 0) + throw new ArgumentOutOfRangeException ("outputOffset", "< 0"); + + // ordered to avoid possible integer overflow + int len = outputBuffer.Length - inputCount - outputOffset; + if (!encrypt && (0 > len) && ((padding == PaddingMode.None) || (padding == PaddingMode.Zeros))) { + throw new CryptographicException ("outputBuffer", "Overflow"); + } else if (KeepLastBlock) { + if (0 > len + BlockSizeByte) { + throw new CryptographicException ("outputBuffer", "Overflow"); + } + } else { + if (0 > len) { + // there's a special case if this is the end of the decryption process + if (inputBuffer.Length - inputOffset - outputBuffer.Length == BlockSizeByte) + inputCount = outputBuffer.Length - outputOffset; + else + throw new CryptographicException ("outputBuffer", "Overflow"); + } + } + return InternalTransformBlock (inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset); + } + + private bool KeepLastBlock { + get { + return ((!encrypt) && (padding != PaddingMode.None) && (padding != PaddingMode.Zeros)); + } + } + + private int InternalTransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) + { + int offs = inputOffset; + int full; + + // this way we don't do a modulo every time we're called + // and we may save a division + if (inputCount != BlockSizeByte) { + if ((inputCount % BlockSizeByte) != 0) + throw new CryptographicException ("Invalid input block size."); + + full = inputCount / BlockSizeByte; + } else + full = 1; + + if (KeepLastBlock) + full--; + + int total = 0; + + if (lastBlock) { + Transform (workBuff, 0, outputBuffer, outputOffset, BlockSizeByte); + outputOffset += BlockSizeByte; + total += BlockSizeByte; + lastBlock = false; + } + + if (full > 0) { + int length = full * BlockSizeByte; + Transform (inputBuffer, offs, outputBuffer, outputOffset, length); + offs += length; + outputOffset += length; + total += length; + } + + if (KeepLastBlock) { + Buffer.BlockCopy (inputBuffer, offs, workBuff, 0, BlockSizeByte); + lastBlock = true; + } + + return total; + } + + private void Random (byte[] buffer, int start, int length) + { + byte[] random = new byte [length]; + Cryptor.GetRandom (random); + Buffer.BlockCopy (random, 0, buffer, start, length); + } + + private void ThrowBadPaddingException (PaddingMode padding, int length, int position) + { + string msg = String.Format ("Bad {0} padding.", padding); + if (length >= 0) + msg += String.Format (" Invalid length {0}.", length); + if (position >= 0) + msg += String.Format (" Error found at position {0}.", position); + throw new CryptographicException (msg); + } + + private byte[] FinalEncrypt (byte[] inputBuffer, int inputOffset, int inputCount) + { + // are there still full block to process ? + int full = (inputCount / BlockSizeByte) * BlockSizeByte; + int rem = inputCount - full; + int total = full; + + switch (padding) { + case PaddingMode.ANSIX923: + case PaddingMode.ISO10126: + case PaddingMode.PKCS7: + // we need to add an extra block for padding + total += BlockSizeByte; + break; + default: + if (inputCount == 0) + return new byte [0]; + if (rem != 0) { + if (padding == PaddingMode.None) + throw new CryptographicException ("invalid block length"); + // zero padding the input (by adding a block for the partial data) + byte[] paddedInput = new byte [full + BlockSizeByte]; + Buffer.BlockCopy (inputBuffer, inputOffset, paddedInput, 0, inputCount); + inputBuffer = paddedInput; + inputOffset = 0; + inputCount = paddedInput.Length; + total = inputCount; + } + break; + } + + byte[] res = new byte [total]; + int outputOffset = 0; + + // process all blocks except the last (final) block + if (total > BlockSizeByte) { + outputOffset = InternalTransformBlock (inputBuffer, inputOffset, total - BlockSizeByte, res, 0); + inputOffset += outputOffset; + } + + // now we only have a single last block to encrypt + byte pad = (byte) (BlockSizeByte - rem); + switch (padding) { + case PaddingMode.ANSIX923: + // XX 00 00 00 00 00 00 07 (zero + padding length) + res [res.Length - 1] = pad; + Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); + // the last padded block will be transformed in-place + InternalTransformBlock (res, full, BlockSizeByte, res, full); + break; + case PaddingMode.ISO10126: + // XX 3F 52 2A 81 AB F7 07 (random + padding length) + Random (res, res.Length - pad, pad - 1); + res [res.Length - 1] = pad; + Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); + // the last padded block will be transformed in-place + InternalTransformBlock (res, full, BlockSizeByte, res, full); + break; + case PaddingMode.PKCS7: + // XX 07 07 07 07 07 07 07 (padding length) + for (int i = res.Length; --i >= (res.Length - pad);) + res [i] = pad; + Buffer.BlockCopy (inputBuffer, inputOffset, res, full, rem); + // the last padded block will be transformed in-place + InternalTransformBlock (res, full, BlockSizeByte, res, full); + break; + default: + InternalTransformBlock (inputBuffer, inputOffset, BlockSizeByte, res, outputOffset); + break; + } + return res; + } + + private byte[] FinalDecrypt (byte[] inputBuffer, int inputOffset, int inputCount) + { + if ((inputCount % BlockSizeByte) > 0) + throw new CryptographicException ("Invalid input block size."); + + int total = inputCount; + if (lastBlock) + total += BlockSizeByte; + + byte[] res = new byte [total]; + int outputOffset = 0; + + if (inputCount > 0) + outputOffset = InternalTransformBlock (inputBuffer, inputOffset, inputCount, res, 0); + + if (lastBlock) { + Transform (workBuff, 0, res, outputOffset, BlockSizeByte); + outputOffset += BlockSizeByte; + lastBlock = false; + } + + // total may be 0 (e.g. PaddingMode.None) + byte pad = ((total > 0) ? res [total - 1] : (byte) 0); + switch (padding) { + case PaddingMode.ANSIX923: + if ((pad == 0) || (pad > BlockSizeByte)) + ThrowBadPaddingException (padding, pad, -1); + for (int i = pad - 1; i > 0; i--) { + if (res [total - 1 - i] != 0x00) + ThrowBadPaddingException (padding, -1, i); + } + total -= pad; + break; + case PaddingMode.ISO10126: + if ((pad == 0) || (pad > BlockSizeByte)) + ThrowBadPaddingException (padding, pad, -1); + total -= pad; + break; + case PaddingMode.PKCS7: + if ((pad == 0) || (pad > BlockSizeByte)) + ThrowBadPaddingException (padding, pad, -1); + for (int i = pad - 1; i > 0; i--) { + if (res [total - 1 - i] != pad) + ThrowBadPaddingException (padding, -1, i); + } + total -= pad; + break; + case PaddingMode.None: // nothing to do - it's a multiple of block size + case PaddingMode.Zeros: // nothing to do - user must unpad himself + break; + } + + // return output without padding + if (total > 0) { + byte[] data = new byte [total]; + Buffer.BlockCopy (res, 0, data, 0, total); + // zeroize decrypted data (copy with padding) + Array.Clear (res, 0, res.Length); + return data; + } + else + return new byte [0]; + } + + public virtual byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) + { + CheckInput (inputBuffer, inputOffset, inputCount); + + if (encrypt) + return FinalEncrypt (inputBuffer, inputOffset, inputCount); + else + return FinalDecrypt (inputBuffer, inputOffset, inputCount); + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/CommonCrypto/Makefile.include b/mcs/class/corlib/CommonCrypto/Makefile.include new file mode 100644 index 00000000000..25e13794998 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/Makefile.include @@ -0,0 +1,5 @@ +CommonCrypto/%.g.cs: CommonCrypto/generator.exe + cd CommonCrypto && mono --debug generator.exe + +CommonCrypto/generator.exe: CommonCrypto/generator.cs CommonCrypto/CommonDigestGenerator.cs CommonCrypto/CommonCryptorGenerator.cs + mcs CommonCrypto/generator.cs CommonCrypto/CommonDigestGenerator.cs CommonCrypto/CommonCryptorGenerator.cs -o $@ diff --git a/mcs/class/corlib/CommonCrypto/RC4CommonCrypto.cs b/mcs/class/corlib/CommonCrypto/RC4CommonCrypto.cs new file mode 100644 index 00000000000..1e5c4e2b29c --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/RC4CommonCrypto.cs @@ -0,0 +1,212 @@ +// A CommonCrypto-based implementation of RC4(tm) +// +// Authors: +// Sebastien Pouliot +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright 2012-2014 Xamarin Inc. + +using System; +using System.Security.Cryptography; + +using Crimson.CommonCrypto; + +#if MONOTOUCH || XAMMAC +using Mono.Security.Cryptography; + +namespace Mono.Security.Cryptography { + +#if !INSIDE_CORLIB + public +#endif + sealed partial class ARC4Managed : RC4, ICryptoTransform { + + IntPtr handle; + + public ARC4Managed () + { + } + + ~ARC4Managed () + { + Dispose (false); + } +#else +namespace Crimson.Security.Cryptography { + + public abstract class RC4 : SymmetricAlgorithm { + + private static KeySizes[] s_legalBlockSizes = { + new KeySizes (64, 64, 0) + }; + + private static KeySizes[] s_legalKeySizes = { + new KeySizes (40, 512, 8) + }; + + public RC4 () + { + KeySizeValue = 128; + BlockSizeValue = 64; + FeedbackSizeValue = BlockSizeValue; + LegalBlockSizesValue = s_legalBlockSizes; + LegalKeySizesValue = s_legalKeySizes; + } + + // required for compatibility with .NET 2.0 + public override byte[] IV { + get { return new byte [0]; } + set { ; } + } + + new static public RC4 Create() + { + return Create ("RC4"); + } + + new static public RC4 Create (string algName) + { + object o = CryptoConfig.CreateFromName (algName); + return (RC4) o ?? new RC4CommonCrypto (); + } + } + + public sealed class RC4CommonCrypto : RC4, ICryptoTransform { + + IntPtr handle; + + public RC4CommonCrypto () + { + } + + ~RC4CommonCrypto () + { + Dispose (false); + } +#endif + + public bool CanReuseTransform { + get { return false; } + } + + public bool CanTransformMultipleBlocks { + get { return true; } + } + + public int InputBlockSize { + get { return 1; } + } + + public int OutputBlockSize { + get { return 1; } + } + + public override byte[] Key { + get { + return base.Key; + } + set { + if (value == null) + throw new ArgumentNullException ("Key"); + + int length = (value.Length << 3); + KeySizeValue = length; + KeyValue = (byte[]) value.Clone (); + } + } + + protected override void Dispose (bool disposing) + { + if (handle != IntPtr.Zero) { + Cryptor.CCCryptorRelease (handle); + handle = IntPtr.Zero; + } + base.Dispose (disposing); + GC.SuppressFinalize (this); + } + + public override void GenerateIV () + { + // not used for a stream cipher + IVValue = new byte [0]; + } + + public override void GenerateKey () + { + KeyValue = KeyBuilder.Key (KeySizeValue >> 3); + } + + public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) + { + KeyValue = rgbKey; + IVValue = rgbIV; + return this; + } + + public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) + { + KeyValue = rgbKey; + IVValue = rgbIV; + return this; + } + + private void CheckInput (byte[] inputBuffer, int inputOffset, int inputCount) + { + if (inputBuffer == null) + throw new ArgumentNullException ("inputBuffer"); + if (inputOffset < 0) + throw new ArgumentOutOfRangeException ("inputOffset", "< 0"); + if (inputCount < 0) + throw new ArgumentOutOfRangeException ("inputCount", "< 0"); + // ordered to avoid possible integer overflow + if (inputOffset > inputBuffer.Length - inputCount) + throw new ArgumentException ("inputBuffer", "Overflow"); + } + + public unsafe int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) + { + CheckInput (inputBuffer, inputOffset, inputCount); + if (inputCount == 0) + return 0; + + // check output parameters + if (outputBuffer == null) + throw new ArgumentNullException ("outputBuffer"); + if (outputOffset < 0) + throw new ArgumentOutOfRangeException ("outputOffset", "< 0"); + // ordered to avoid possible integer overflow + if (outputOffset > outputBuffer.Length - inputCount) + throw new ArgumentException ("outputBuffer", "Overflow"); + if (outputBuffer.Length == 0) + throw new CryptographicException ("output buffer too small"); + + if (handle == IntPtr.Zero) + handle = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.RC4, CCOptions.None, KeyValue, IVValue); + + IntPtr len = IntPtr.Zero; + IntPtr in_len = (IntPtr) (inputBuffer.Length - inputOffset); + IntPtr out_len = (IntPtr) (outputBuffer.Length - outputOffset); + fixed (byte* input = &inputBuffer [0]) + fixed (byte* output = &outputBuffer [0]) { + CCCryptorStatus s = Cryptor.CCCryptorUpdate (handle, (IntPtr) (input + inputOffset), in_len, (IntPtr) (output + outputOffset), out_len, ref len); + if ((len != out_len) || (s != CCCryptorStatus.Success)) + throw new CryptographicUnexpectedOperationException (s.ToString ()); + } + return (int) out_len; + } + + public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) + { + CheckInput (inputBuffer, inputOffset, inputCount); + try { + byte[] output = new byte [inputCount]; + TransformBlock (inputBuffer, inputOffset, inputCount, output, 0); + return output; + } + finally { + Cryptor.CCCryptorRelease (handle); + handle = IntPtr.Zero; + } + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/CommonCrypto/RijndaelManaged.cs b/mcs/class/corlib/CommonCrypto/RijndaelManaged.cs new file mode 100644 index 00000000000..3d528d33a7f --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/RijndaelManaged.cs @@ -0,0 +1,119 @@ +// +// RijndaelManaged.cs: Use CommonCrypto AES when possible, +// fallback on RijndaelManagedTransform otherwise +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. +// + +using System; +using System.Security.Cryptography; + +using Mono.Security.Cryptography; +using Crimson.CommonCrypto; + +namespace System.Security.Cryptography { + + public sealed class RijndaelManaged : Rijndael { + + public RijndaelManaged () + { + } + + public override void GenerateIV () + { + IVValue = KeyBuilder.IV (BlockSizeValue >> 3); + } + + public override void GenerateKey () + { + KeyValue = KeyBuilder.Key (KeySizeValue >> 3); + } + + public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV) + { + // AES is Rijndael with a 128 bits block size, so we can use CommonCrypto in this case + if (BlockSize == 128) { + IntPtr decryptor = IntPtr.Zero; + switch (Mode) { + case CipherMode.CBC: + decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.AES128, CCOptions.None, rgbKey, rgbIV); + return new FastCryptorTransform (decryptor, this, false, rgbIV); + case CipherMode.ECB: + decryptor = Cryptor.Create (CCOperation.Decrypt, CCAlgorithm.AES128, CCOptions.ECBMode, rgbKey, rgbIV); + return new FastCryptorTransform (decryptor, this, false, rgbIV); + default: + // CFB cipher mode is not supported by the (old) API we used (for compatibility) so we fallback for them + // FIXME: benchmark if we're better with RijndaelManagedTransform or CryptorTransform for CFB mode + break; + } + } + + return NewEncryptor(rgbKey, + ModeValue, + rgbIV, + FeedbackSizeValue, + RijndaelManagedTransformMode.Decrypt); + } + + public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV) + { + if (BlockSize == 128) { + IntPtr encryptor = IntPtr.Zero; + switch (Mode) { + case CipherMode.CBC: + encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.AES128, CCOptions.None, rgbKey, rgbIV); + return new FastCryptorTransform (encryptor, this, true, rgbIV); + case CipherMode.ECB: + encryptor = Cryptor.Create (CCOperation.Encrypt, CCAlgorithm.AES128, CCOptions.ECBMode, rgbKey, rgbIV); + return new FastCryptorTransform (encryptor, this, true, rgbIV); + default: + // CFB cipher mode is not supported by the (old) API we used (for compatibility) so we fallback for them + // FIXME: benchmark if we're better with RijndaelManagedTransform or CryptorTransform for CFB mode + break; + } + } + + return NewEncryptor(rgbKey, + ModeValue, + rgbIV, + FeedbackSizeValue, + RijndaelManagedTransformMode.Encrypt); + } + + + private ICryptoTransform NewEncryptor (byte[] rgbKey, + CipherMode mode, + byte[] rgbIV, + int feedbackSize, + RijndaelManagedTransformMode encryptMode) { + // Build the key if one does not already exist + if (rgbKey == null) { + rgbKey = Utils.GenerateRandom(KeySizeValue / 8); + } + + // If not ECB mode, make sure we have an IV. In CoreCLR we do not support ECB, so we must have + // an IV in all cases. +#if !FEATURE_CRYPTO + if (mode != CipherMode.ECB) { +#endif // !FEATURE_CRYPTO + if (rgbIV == null) { + rgbIV = Utils.GenerateRandom(BlockSizeValue / 8); + } +#if !FEATURE_CRYPTO + } +#endif // !FEATURE_CRYPTO + + // Create the encryptor/decryptor object + return new RijndaelManagedTransform (rgbKey, + mode, + rgbIV, + BlockSizeValue, + feedbackSize, + PaddingValue, + encryptMode); + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/CommonCrypto/SecRandom.cs b/mcs/class/corlib/CommonCrypto/SecRandom.cs new file mode 100644 index 00000000000..a112faf5570 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/SecRandom.cs @@ -0,0 +1,81 @@ +// +// SecRandom.cs: based on Mono's System.Security.Cryptography.RNGCryptoServiceProvider +// +// Authors: +// Mark Crichton (crichton@gimp.org) +// Sebastien Pouliot (sebastien@xamarun.com) +// +// (C) 2002 +// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012-2014 Xamarin Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Crimson.CommonCrypto; + +// http://developer.apple.com/library/ios/#DOCUMENTATION/Security/Reference/RandomizationReference/Reference/reference.html +#if MONOTOUCH || XAMMAC +namespace System.Security.Cryptography { + public class RNGCryptoServiceProvider : RandomNumberGenerator { + public RNGCryptoServiceProvider () + { + } + + ~RNGCryptoServiceProvider () + { + } +#else +using System; +using System.Security.Cryptography; + +namespace Crimson.Security.Cryptography { + + public class SecRandom : RandomNumberGenerator { +#endif + + public override void GetBytes (byte[] data) + { + if (data == null) + throw new ArgumentNullException ("data"); + + Cryptor.GetRandom (data); + } + + public override void GetNonZeroBytes (byte[] data) + { + if (data == null) + throw new ArgumentNullException ("data"); + + byte[] random = new byte [data.Length * 2]; + int i = 0; + // one pass should be enough but hey this is random ;-) + while (i < data.Length) { + Cryptor.GetRandom (random); + for (int j=0; j < random.Length; j++) { + if (i == data.Length) + break; + if (random [j] != 0) + data [i++] = random [j]; + } + } + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/CommonCrypto/generator.cs b/mcs/class/corlib/CommonCrypto/generator.cs new file mode 100644 index 00000000000..a7d13c8cb80 --- /dev/null +++ b/mcs/class/corlib/CommonCrypto/generator.cs @@ -0,0 +1,57 @@ +// +// CommonCrypto Code Generator +// +// Authors: +// Sebastien Pouliot +// +// Copyright 2012 Xamarin Inc. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Xamarin { + + class Program { + static void Main (string [] args) + { + // mscorlib replacements + CommonDigest.Generate ("System.Security.Cryptography", "MD5CryptoServiceProvider", "MD5", 1000); + CommonDigest.Generate ("System.Security.Cryptography", "SHA1CryptoServiceProvider", "SHA1", 1000); + CommonDigest.Generate ("System.Security.Cryptography", "SHA1Managed", "SHA1", 1000); + CommonDigest.Generate ("System.Security.Cryptography", "SHA256Managed", "SHA256", 1000); + CommonDigest.Generate ("System.Security.Cryptography", "SHA384Managed", "SHA384", 1000); + CommonDigest.Generate ("System.Security.Cryptography", "SHA512Managed", "SHA512", 1000); + + // System.Core replacements - not yet in MT profile (4.0 - functional dupes anyway) + //CommonDigest.Generate ("System.Security.Cryptography", "MD5Cng", "MD5", 1000); + //CommonDigest.Generate ("System.Security.Cryptography", "SHA256Cng", "SHA256", 1000); + //CommonDigest.Generate ("System.Security.Cryptography", "SHA384Cng", "SHA384", 1000); + //CommonDigest.Generate ("System.Security.Cryptography", "SHA512Cng", "SHA512", 1000); + //CommonDigest.Generate ("System.Security.Cryptography", "SHA256CryptoServiceProvider", "SHA256", 1000); + //CommonDigest.Generate ("System.Security.Cryptography", "SHA384CryptoServiceProvider", "SHA384", 1000); + //CommonDigest.Generate ("System.Security.Cryptography", "SHA512CryptoServiceProvider", "SHA512", 1000); + + // Mono.Security replacements + CommonDigest.Generate ("Mono.Security.Cryptography", "MD2Managed", "MD2", 1000, "#if !INSIDE_CORLIB", "#endif"); + CommonDigest.Generate ("Mono.Security.Cryptography", "MD4Managed", "MD4", 1000, "#if !INSIDE_CORLIB", "#endif"); + CommonDigest.Generate ("Mono.Security.Cryptography", "SHA224Managed", "SHA224", 1000); + + // mscorlib replacements + CommonCryptor.Generate ("System.Security.Cryptography", "DESCryptoServiceProvider", "DES", "DES"); + CommonCryptor.Generate ("System.Security.Cryptography", "TripleDESCryptoServiceProvider", "TripleDES", "TripleDES"); + CommonCryptor.Generate ("System.Security.Cryptography", "RC2CryptoServiceProvider", "RC2", "RC2", ctorInitializers: "LegalKeySizesValue = new[] { new KeySizes(40, 128, 8) };"); + // Rijndael supports block sizes that are not available in AES - as such it does not use the same generated code + // but has it's own version, using AES (128 bits block size) and falling back to managed (192/256 bits block size) + + // System.Core replacements + CommonCryptor.Generate ("System.Security.Cryptography", "AesManaged", "Aes", "AES128", "128"); + CommonCryptor.Generate ("System.Security.Cryptography", "AesCryptoServiceProvider", "Aes", "AES128"); + + // Mono.Security replacements + // RC4 is a stream (not a block) cipher so it can not reuse the generated code + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/CoreFoundation/CFHelpers.cs b/mcs/class/corlib/CoreFoundation/CFHelpers.cs new file mode 100644 index 00000000000..7a765d35b55 --- /dev/null +++ b/mcs/class/corlib/CoreFoundation/CFHelpers.cs @@ -0,0 +1,110 @@ +using System; +using System.Runtime.InteropServices; + +namespace XamMac.CoreFoundation +{ + internal static class CFHelpers + { + internal const string CoreFoundationLibrary = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation"; + internal const string SecurityLibrary = "/System/Library/Frameworks/Security.framework/Security"; + + [DllImport (CoreFoundationLibrary)] + internal extern static void CFRelease (IntPtr obj); + + [DllImport (CoreFoundationLibrary)] + internal extern static IntPtr CFRetain (IntPtr obj); + + [StructLayout (LayoutKind.Sequential)] + struct CFRange { + public IntPtr loc; + public IntPtr len; + + public CFRange (int loc, int len) + : this ((long) loc, (long) len) + { + } + + public CFRange (long l, long len) + { + this.loc = (IntPtr) l; + this.len = (IntPtr) len; + } + } + + [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)] + extern static IntPtr CFStringCreateWithCharacters (IntPtr allocator, string str, IntPtr count); + + [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)] + extern static IntPtr CFStringGetLength (IntPtr handle); + + [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)] + extern static IntPtr CFStringGetCharactersPtr (IntPtr handle); + + [DllImport (CoreFoundationLibrary, CharSet=CharSet.Unicode)] + extern static IntPtr CFStringGetCharacters (IntPtr handle, CFRange range, IntPtr buffer); + + internal static string FetchString (IntPtr handle) + { + if (handle == IntPtr.Zero) + return null; + + string str; + + int l = (int)CFStringGetLength (handle); + IntPtr u = CFStringGetCharactersPtr (handle); + IntPtr buffer = IntPtr.Zero; + if (u == IntPtr.Zero){ + CFRange r = new CFRange (0, l); + buffer = Marshal.AllocCoTaskMem (l * 2); + CFStringGetCharacters (handle, r, buffer); + u = buffer; + } + unsafe { + str = new string ((char *) u, 0, l); + } + + if (buffer != IntPtr.Zero) + Marshal.FreeCoTaskMem (buffer); + + return str; + } + + [DllImport (CoreFoundationLibrary)] + extern static IntPtr CFDataGetLength (IntPtr handle); + + [DllImport (CoreFoundationLibrary)] + extern static IntPtr CFDataGetBytePtr (IntPtr handle); + + internal static byte[] FetchDataBuffer (IntPtr handle) + { + var length = (int)CFDataGetLength (handle); + var buffer = new byte [length]; + var ptr = CFDataGetBytePtr (handle); + Marshal.Copy (ptr, buffer, 0, buffer.Length); + return buffer; + } + + [DllImport (CoreFoundationLibrary)] + extern static IntPtr CFDataCreateWithBytesNoCopy (IntPtr allocator, IntPtr bytes, IntPtr length, IntPtr bytesDeallocator); + + [DllImport (CoreFoundationLibrary)] + extern static IntPtr CFDataCreate (IntPtr allocator, IntPtr bytes, IntPtr length); + + [DllImport (SecurityLibrary)] + extern static IntPtr SecCertificateCreateWithData (IntPtr allocator, IntPtr cfData); + + unsafe internal static IntPtr CreateCertificateFromData (byte[] data) + { + fixed (void *ptr = data) { + var cfdata = CFDataCreate (IntPtr.Zero, (IntPtr)ptr, new IntPtr (data.Length)); + if (cfdata == IntPtr.Zero) + return IntPtr.Zero; + + var certificate = SecCertificateCreateWithData (IntPtr.Zero, cfdata); + if (cfdata != IntPtr.Zero) + CFRelease (cfdata); + return certificate; + } + } + } +} diff --git a/mcs/class/corlib/Makefile b/mcs/class/corlib/Makefile index 2540e236031..aff30966f5a 100644 --- a/mcs/class/corlib/Makefile +++ b/mcs/class/corlib/Makefile @@ -1,6 +1,7 @@ thisdir = class/corlib SUBDIRS = include ../../build/rules.make +include CommonCrypto/Makefile.include export __SECURITY_BOOTSTRAP_DB=$(topdir)/class/corlib LIBRARY = corlib.dll diff --git a/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs b/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs new file mode 100644 index 00000000000..bca51601728 --- /dev/null +++ b/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs @@ -0,0 +1,193 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; +using XamMac.CoreFoundation; +using MX = Mono.Security.X509; + +namespace System.Security.Cryptography.X509Certificates +{ + class X509CertificateImplApple : X509CertificateImpl + { + IntPtr handle; + X509CertificateImpl fallback; + + public X509CertificateImplApple (IntPtr handle, bool owns) + { + this.handle = handle; + if (!owns) + CFHelpers.CFRetain (handle); + } + + public override bool IsValid { + get { return handle != IntPtr.Zero; } + } + + public override IntPtr Handle { + get { return handle; } + } + + public override X509CertificateImpl Clone () + { + ThrowIfContextInvalid (); + return new X509CertificateImplApple (handle, false); + } + + [DllImport (CFHelpers.SecurityLibrary)] + extern static IntPtr SecCertificateCopySubjectSummary (IntPtr cert); + + [DllImport (CFHelpers.SecurityLibrary)] + extern static IntPtr SecCertificateCopyData (IntPtr cert); + + public override byte[] GetRawCertData () + { + ThrowIfContextInvalid (); + var data = SecCertificateCopyData (handle); + if (data == IntPtr.Zero) + throw new ArgumentException ("Not a valid certificate"); + + try { + return CFHelpers.FetchDataBuffer (data); + } finally { + CFHelpers.CFRelease (data); + } + } + + public override string GetSubjectSummary () + { + ThrowIfContextInvalid (); + IntPtr cfstr = SecCertificateCopySubjectSummary (handle); + string ret = CFHelpers.FetchString (cfstr); + CFHelpers.CFRelease (cfstr); + return ret; + } + + protected override byte[] GetCertHash (bool lazy) + { + // FIXME: might just return 'null' when 'lazy' is true. + ThrowIfContextInvalid (); + SHA1 sha = SHA1.Create (); + return sha.ComputeHash (GetRawCertData ()); + } + + public override bool Equals (X509CertificateImpl other, out bool result) + { + var otherAppleImpl = other as X509CertificateImplApple; + if (otherAppleImpl != null && otherAppleImpl.handle == handle) { + result = true; + return true; + } + + result = false; + return false; + } + + void MustFallback () + { + ThrowIfContextInvalid (); + if (fallback != null) + return; + var mxCert = new MX.X509Certificate (GetRawCertData ()); + fallback = new X509CertificateImplMono (mxCert); + } + + public X509CertificateImpl FallbackImpl { + get { + MustFallback (); + return fallback; + } + } + + public override string GetSubjectName (bool legacyV1Mode) + { + return FallbackImpl.GetSubjectName (legacyV1Mode); + } + + public override string GetIssuerName (bool legacyV1Mode) + { + return FallbackImpl.GetIssuerName (legacyV1Mode); + } + + public override DateTime GetEffectiveDateString () + { + return FallbackImpl.GetEffectiveDateString (); + } + + public override DateTime GetExpirationDateString () + { + return FallbackImpl.GetExpirationDateString (); + } + + public override string GetKeyAlgorithm () + { + return FallbackImpl.GetKeyAlgorithm (); + } + + public override byte[] GetKeyAlgorithmParameters () + { + return FallbackImpl.GetKeyAlgorithmParameters (); + } + + public override byte[] GetPublicKey () + { + return FallbackImpl.GetPublicKey (); + } + + public override byte[] GetSerialNumber () + { + return FallbackImpl.GetSerialNumber (); + } + + public override byte[] Export (X509ContentType contentType, byte[] password) + { + ThrowIfContextInvalid (); + + switch (contentType) { + case X509ContentType.Cert: + return GetRawCertData (); + case X509ContentType.Pfx: // this includes Pkcs12 + // TODO + throw new NotSupportedException (); + case X509ContentType.SerializedCert: + // TODO + throw new NotSupportedException (); + default: + string msg = Locale.GetText ("This certificate format '{0}' cannot be exported.", contentType); + throw new CryptographicException (msg); + } + } + + public override string ToString (bool full) + { + ThrowIfContextInvalid (); + + if (!full || fallback == null) { + var summary = GetSubjectSummary (); + return string.Format ("[X509Certificate: {0}]", summary); + } + + string nl = Environment.NewLine; + StringBuilder sb = new StringBuilder (); + sb.AppendFormat ("[Subject]{0} {1}{0}{0}", nl, GetSubjectName (false)); + + sb.AppendFormat ("[Issuer]{0} {1}{0}{0}", nl, GetIssuerName (false)); + sb.AppendFormat ("[Not Before]{0} {1}{0}{0}", nl, GetEffectiveDateString ()); + sb.AppendFormat ("[Not After]{0} {1}{0}{0}", nl, GetExpirationDateString ()); + sb.AppendFormat ("[Thumbprint]{0} {1}{0}", nl, X509Helper.ToHexString (GetCertHash ())); + + sb.Append (nl); + return sb.ToString (); + } + + protected override void Dispose (bool disposing) + { + if (handle != IntPtr.Zero){ + CFHelpers.CFRelease (handle); + handle = IntPtr.Zero; + } + if (fallback != null) { + fallback.Dispose (); + fallback = null; + } + } + } +} diff --git a/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs b/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs new file mode 100644 index 00000000000..7068882bc9a --- /dev/null +++ b/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs @@ -0,0 +1,50 @@ +using System; +using System.Runtime.InteropServices; +using MX = Mono.Security.X509; +using XamMac.CoreFoundation; + +namespace System.Security.Cryptography.X509Certificates +{ + static partial class X509Helper + { + public static X509CertificateImpl InitFromHandle (IntPtr handle) + { + return new X509CertificateImplApple (handle, false); + } + + public static X509CertificateImpl Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) + { + MX.X509Certificate x509; + IntPtr handle; + if (password == null) { + handle = CFHelpers.CreateCertificateFromData (rawData); + if (handle != IntPtr.Zero) + return new X509CertificateImplApple (handle, true); + + try { + x509 = new MX.X509Certificate (rawData); + } catch (Exception e) { + try { + x509 = X509Helper.ImportPkcs12 (rawData, null); + } catch { + string msg = Locale.GetText ("Unable to decode certificate."); + // inner exception is the original (not second) exception + throw new CryptographicException (msg, e); + } + } + } else { + // try PKCS#12 + try { + x509 = X509Helper.ImportPkcs12 (rawData, password); + } + catch { + // it's possible to supply a (unrequired/unusued) password + // fix bug #79028 + x509 = new MX.X509Certificate (rawData); + } + } + + return new X509CertificateImplMono (x509); + } + } +} diff --git a/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Helper.MonoTouch.opt.cs b/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Helper.MonoTouch.opt.cs deleted file mode 100644 index 19f1c4eabb5..00000000000 --- a/mcs/class/corlib/System.Security.Cryptography.X509Certificates/X509Helper.MonoTouch.opt.cs +++ /dev/null @@ -1,20 +0,0 @@ -#if MONOTOUCH || XAMMAC - -// this file is a shim to enable compiling monotouch profiles without mono-extensions -namespace System.Security.Cryptography.X509Certificates -{ - static partial class X509Helper - { - public static X509CertificateImpl InitFromHandle (IntPtr handle) - { - throw new NotSupportedException (); - } - - public static X509CertificateImpl Import (byte[] rawData, string password, X509KeyStorageFlags keyStorageFlags) - { - throw new NotSupportedException (); - } - } -} - -#endif diff --git a/mcs/class/corlib/System.Text/EncodingHelper.MonoTouch.cs b/mcs/class/corlib/System.Text/EncodingHelper.MonoTouch.cs new file mode 100644 index 00000000000..554b2064a25 --- /dev/null +++ b/mcs/class/corlib/System.Text/EncodingHelper.MonoTouch.cs @@ -0,0 +1,30 @@ +using System; + +namespace System.Text { + + internal static partial class EncodingHelper { + + static volatile Encoding utf8Encoding; + + internal static Encoding UTF8 { + get { + if (utf8Encoding == null) { + lock (lockobj){ + if (utf8Encoding == null){ + utf8Encoding = new UTF8Encoding (true, false); + utf8Encoding.setReadOnly (); + } + } + } + + return utf8Encoding; + } + } + + // The mobile profile has been default'ing to UTF8 since it's creation + internal static Encoding GetDefaultEncoding () + { + return UTF8; + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/System.Text/EncodingHelper.MonoTouch.opt.cs b/mcs/class/corlib/System.Text/EncodingHelper.MonoTouch.opt.cs deleted file mode 100644 index 9aba0f63ba1..00000000000 --- a/mcs/class/corlib/System.Text/EncodingHelper.MonoTouch.opt.cs +++ /dev/null @@ -1,15 +0,0 @@ -#if MONOTOUCH - -// this file is a shim to enable compiling monotouch profiles without mono-extensions -namespace System.Text -{ - internal static partial class EncodingHelper - { - internal static Encoding GetDefaultEncoding () - { - throw new NotSupportedException (); - } - } -} - -#endif diff --git a/mcs/class/corlib/System/Environment.MonoTouch.opt.cs b/mcs/class/corlib/System/Environment.MonoTouch.opt.cs deleted file mode 100644 index d45de30c05a..00000000000 --- a/mcs/class/corlib/System/Environment.MonoTouch.opt.cs +++ /dev/null @@ -1,20 +0,0 @@ -#if MONOTOUCH - -// this file is a shim to enable compiling monotouch profiles without mono-extensions -namespace System -{ - public static partial class Environment - { - public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option) - { - throw new NotSupportedException (); - } - - internal static string UnixGetFolderPath (SpecialFolder folder, SpecialFolderOption option) - { - throw new NotSupportedException (); - } - } -} - -#endif diff --git a/mcs/class/corlib/System/Environment.iOS.cs b/mcs/class/corlib/System/Environment.iOS.cs new file mode 100644 index 00000000000..04ad76d43ed --- /dev/null +++ b/mcs/class/corlib/System/Environment.iOS.cs @@ -0,0 +1,148 @@ +// Copyright 2014 Xamarin Inc. + +// note: or older hack to give the Documents (or Library) directories + +using System.IO; +using System.Runtime.InteropServices; + +namespace System { + + public static partial class Environment { + + static string ns_document; + static string ns_library; + + [DllImport ("__Internal")] + extern static string xamarin_GetFolderPath (int folder); + + static string NSDocumentDirectory { + get { + if (ns_document == null) { +#if MONOTOUCH_TV + // The "normal" NSDocumentDirectory is a read-only directory on tvOS + // and that breaks a lot of assumptions in the runtime and the BCL + // to avoid this we relocate the Documents directory under Caches + ns_document = Path.Combine (NSLibraryDirectory, "Caches", "Documents"); + if (!Directory.Exists (ns_document)) + Directory.CreateDirectory (ns_document); +#else + ns_document = xamarin_GetFolderPath (/* NSDocumentDirectory */ 9); +#endif + } + return ns_document; + } + } + + // Various user-visible documentation, support, and configuration files + static string NSLibraryDirectory { + get { + if (ns_library == null) + ns_library = xamarin_GetFolderPath (/* NSLibraryDirectory */ 5); + return ns_library; + } + } + + public static string GetFolderPath (SpecialFolder folder, SpecialFolderOption option) + { + return UnixGetFolderPath (folder, option); + } + + // needed by our BCL, e.g. IsolatedStorageFile.cs + internal static string UnixGetFolderPath (SpecialFolder folder, SpecialFolderOption option) + { + var dir = iOSGetFolderPath (folder); + if ((option == SpecialFolderOption.Create) && !Directory.Exists (dir)) + Directory.CreateDirectory (dir); + return dir; + } + + internal static string iOSGetFolderPath (SpecialFolder folder) + { + switch (folder) { + case SpecialFolder.MyComputer: + case SpecialFolder.Programs: + case SpecialFolder.SendTo: + case SpecialFolder.StartMenu: + case SpecialFolder.Startup: + case SpecialFolder.Cookies: + case SpecialFolder.History: + case SpecialFolder.Recent: + case SpecialFolder.CommonProgramFiles: + case SpecialFolder.System: + case SpecialFolder.NetworkShortcuts: + case SpecialFolder.CommonStartMenu: + case SpecialFolder.CommonPrograms: + case SpecialFolder.CommonStartup: + case SpecialFolder.CommonDesktopDirectory: + case SpecialFolder.PrinterShortcuts: + case SpecialFolder.Windows: + case SpecialFolder.SystemX86: + case SpecialFolder.ProgramFilesX86: + case SpecialFolder.CommonProgramFilesX86: + case SpecialFolder.CommonDocuments: + case SpecialFolder.CommonAdminTools: + case SpecialFolder.AdminTools: + case SpecialFolder.CommonMusic: + case SpecialFolder.CommonPictures: + case SpecialFolder.CommonVideos: + case SpecialFolder.LocalizedResources: + case SpecialFolder.CommonOemLinks: + case SpecialFolder.CDBurning: + return String.Empty; + + // personal == ~ + case SpecialFolder.Personal: + case SpecialFolder.LocalApplicationData: + return NSDocumentDirectory; + + case SpecialFolder.ApplicationData: + // note: at first glance that looked like a good place to return NSLibraryDirectory + // but it would break isolated storage for existing applications + return Path.Combine (NSDocumentDirectory, ".config"); + + case SpecialFolder.Resources: + return NSLibraryDirectory; // older (8.2 and previous) would return String.Empty + + case SpecialFolder.Desktop: + case SpecialFolder.DesktopDirectory: + return Path.Combine (NSDocumentDirectory, "Desktop"); + + case SpecialFolder.MyMusic: + return Path.Combine (NSDocumentDirectory, "Music"); + + case SpecialFolder.MyPictures: + return Path.Combine (NSDocumentDirectory, "Pictures"); + + case SpecialFolder.Templates: + return Path.Combine (NSDocumentDirectory, "Templates"); + + case SpecialFolder.MyVideos: + return Path.Combine (NSDocumentDirectory, "Videos"); + + case SpecialFolder.CommonTemplates: + return "/usr/share/templates"; + + case SpecialFolder.Fonts: + return Path.Combine (NSDocumentDirectory, ".fonts"); + + case SpecialFolder.Favorites: + return Path.Combine (NSLibraryDirectory, "Favorites"); + + case SpecialFolder.ProgramFiles: + return "/Applications"; + + case SpecialFolder.InternetCache: + return Path.Combine (NSLibraryDirectory, "Caches"); + + case SpecialFolder.UserProfile: + return internalGetHome (); + + case SpecialFolder.CommonApplicationData: + return "/usr/share"; + + default: + throw new ArgumentException ("Invalid SpecialFolder"); + } + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/System/Guid.MonoTouch.cs b/mcs/class/corlib/System/Guid.MonoTouch.cs new file mode 100644 index 00000000000..714bdb6f86f --- /dev/null +++ b/mcs/class/corlib/System/Guid.MonoTouch.cs @@ -0,0 +1,25 @@ +#if MONOTOUCH && FULL_AOT_RUNTIME + +using Crimson.CommonCrypto; + +namespace System +{ + partial struct Guid + { + public static Guid NewGuid () + { + byte[] b = new byte [16]; + Cryptor.GetRandom (b); + + Guid res = new Guid (b); + // Mask in Variant 1-0 in Bit[7..6] + res._d = (byte) ((res._d & 0x3fu) | 0x80u); + // Mask in Version 4 (random based Guid) in Bits[15..13] + res._c = (short) ((res._c & 0x0fffu) | 0x4000u); + + return res; + } + } +} + +#endif \ No newline at end of file diff --git a/mcs/class/corlib/System/Guid.MonoTouch.opt.cs b/mcs/class/corlib/System/Guid.MonoTouch.opt.cs deleted file mode 100644 index beb6a3a08f1..00000000000 --- a/mcs/class/corlib/System/Guid.MonoTouch.opt.cs +++ /dev/null @@ -1,15 +0,0 @@ -#if MONOTOUCH && FULL_AOT_RUNTIME - -// this file is a shim to enable compiling monotouch profiles without mono-extensions -namespace System -{ - partial struct Guid - { - public static Guid NewGuid () - { - throw new NotSupportedException (); - } - } -} - -#endif diff --git a/mcs/class/corlib/System/NotSupportedException.iOS.cs b/mcs/class/corlib/System/NotSupportedException.iOS.cs new file mode 100644 index 00000000000..c18b3d677a4 --- /dev/null +++ b/mcs/class/corlib/System/NotSupportedException.iOS.cs @@ -0,0 +1,13 @@ +namespace System { + + public partial class NotSupportedException { + + // Avoid having the linker generate this method for every linked build + // It also fix #30075 where --linkskip=mscorlib means that method could not be added + // but still referenced from other assemblies + internal static Exception LinkedAway () + { + return new NotSupportedException ("Linked Away"); + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/monotouch_corlib.dll.exclude.sources b/mcs/class/corlib/monotouch_corlib.dll.exclude.sources new file mode 100644 index 00000000000..72871935f28 --- /dev/null +++ b/mcs/class/corlib/monotouch_corlib.dll.exclude.sources @@ -0,0 +1,15 @@ +System.Security.Cryptography/MD5CryptoServiceProvider.cs +System.Security.Cryptography/SHA1CryptoServiceProvider.cs +System.Security.Cryptography/SHA1CryptoServiceProvider.cs +../../../external/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs +../../../external/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs +../../../external/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha1managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha256managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha384managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha512managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs +System.Security.Cryptography/RNGCryptoServiceProvider.cs +../Mono.Security/Mono.Security.Cryptography/ARC4Managed.cs +../Mono.Security/Mono.Security.Cryptography/MD2Managed.cs +../Mono.Security/Mono.Security.Cryptography/MD4Managed.cs diff --git a/mcs/class/corlib/monotouch_corlib.dll.sources b/mcs/class/corlib/monotouch_corlib.dll.sources index da77893bcc5..e802a034dd6 100644 --- a/mcs/class/corlib/monotouch_corlib.dll.sources +++ b/mcs/class/corlib/monotouch_corlib.dll.sources @@ -1 +1,27 @@ #include corlib.dll.sources +CommonCrypto/CommonCrypto.cs +CommonCrypto/CryptorTransform.cs +CommonCrypto/FastCryptorTransform.cs +CommonCrypto/CorlibExtras.cs +CommonCrypto/MD5CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1Managed.g.cs +CommonCrypto/SHA256Managed.g.cs +CommonCrypto/SHA384Managed.g.cs +CommonCrypto/SHA512Managed.g.cs +CommonCrypto/TripleDESCryptoServiceProvider.g.cs +CommonCrypto/DESCryptoServiceProvider.g.cs +CommonCrypto/RC2CryptoServiceProvider.g.cs +CommonCrypto/RijndaelManaged.cs +CommonCrypto/SecRandom.cs +CommonCrypto/RC4CommonCrypto.cs +CommonCrypto/MD2Managed.g.cs +CommonCrypto/MD4Managed.g.cs +System/Environment.iOS.cs +System/Guid.MonoTouch.cs +System/NotSupportedException.iOS.cs +CoreFoundation/CFHelpers.cs +System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs +System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs +System.Text/EncodingHelper.MonoTouch.cs diff --git a/mcs/class/corlib/monotouch_opt_corlib.dll.sources b/mcs/class/corlib/monotouch_opt_corlib.dll.sources deleted file mode 100644 index be231efa3a5..00000000000 --- a/mcs/class/corlib/monotouch_opt_corlib.dll.sources +++ /dev/null @@ -1,4 +0,0 @@ -System/Environment.MonoTouch.opt.cs -System/Guid.MonoTouch.opt.cs -System.Text/EncodingHelper.MonoTouch.opt.cs -System.Security.Cryptography.X509Certificates/X509Helper.MonoTouch.opt.cs diff --git a/mcs/class/corlib/monotouch_runtime_corlib.dll.exclude.sources b/mcs/class/corlib/monotouch_runtime_corlib.dll.exclude.sources new file mode 100644 index 00000000000..53efeacceda --- /dev/null +++ b/mcs/class/corlib/monotouch_runtime_corlib.dll.exclude.sources @@ -0,0 +1 @@ +#include monotouch_corlib.dll.exclude.sources diff --git a/mcs/class/corlib/monotouch_runtime_corlib.dll.sources b/mcs/class/corlib/monotouch_runtime_corlib.dll.sources index da77893bcc5..e802a034dd6 100644 --- a/mcs/class/corlib/monotouch_runtime_corlib.dll.sources +++ b/mcs/class/corlib/monotouch_runtime_corlib.dll.sources @@ -1 +1,27 @@ #include corlib.dll.sources +CommonCrypto/CommonCrypto.cs +CommonCrypto/CryptorTransform.cs +CommonCrypto/FastCryptorTransform.cs +CommonCrypto/CorlibExtras.cs +CommonCrypto/MD5CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1Managed.g.cs +CommonCrypto/SHA256Managed.g.cs +CommonCrypto/SHA384Managed.g.cs +CommonCrypto/SHA512Managed.g.cs +CommonCrypto/TripleDESCryptoServiceProvider.g.cs +CommonCrypto/DESCryptoServiceProvider.g.cs +CommonCrypto/RC2CryptoServiceProvider.g.cs +CommonCrypto/RijndaelManaged.cs +CommonCrypto/SecRandom.cs +CommonCrypto/RC4CommonCrypto.cs +CommonCrypto/MD2Managed.g.cs +CommonCrypto/MD4Managed.g.cs +System/Environment.iOS.cs +System/Guid.MonoTouch.cs +System/NotSupportedException.iOS.cs +CoreFoundation/CFHelpers.cs +System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs +System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs +System.Text/EncodingHelper.MonoTouch.cs diff --git a/mcs/class/corlib/monotouch_runtime_opt_corlib.dll.sources b/mcs/class/corlib/monotouch_runtime_opt_corlib.dll.sources deleted file mode 100644 index d32b5060240..00000000000 --- a/mcs/class/corlib/monotouch_runtime_opt_corlib.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_corlib.dll.sources diff --git a/mcs/class/corlib/monotouch_tv_corlib.dll.exclude.sources b/mcs/class/corlib/monotouch_tv_corlib.dll.exclude.sources new file mode 100644 index 00000000000..53efeacceda --- /dev/null +++ b/mcs/class/corlib/monotouch_tv_corlib.dll.exclude.sources @@ -0,0 +1 @@ +#include monotouch_corlib.dll.exclude.sources diff --git a/mcs/class/corlib/monotouch_tv_corlib.dll.sources b/mcs/class/corlib/monotouch_tv_corlib.dll.sources index da77893bcc5..e802a034dd6 100644 --- a/mcs/class/corlib/monotouch_tv_corlib.dll.sources +++ b/mcs/class/corlib/monotouch_tv_corlib.dll.sources @@ -1 +1,27 @@ #include corlib.dll.sources +CommonCrypto/CommonCrypto.cs +CommonCrypto/CryptorTransform.cs +CommonCrypto/FastCryptorTransform.cs +CommonCrypto/CorlibExtras.cs +CommonCrypto/MD5CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1Managed.g.cs +CommonCrypto/SHA256Managed.g.cs +CommonCrypto/SHA384Managed.g.cs +CommonCrypto/SHA512Managed.g.cs +CommonCrypto/TripleDESCryptoServiceProvider.g.cs +CommonCrypto/DESCryptoServiceProvider.g.cs +CommonCrypto/RC2CryptoServiceProvider.g.cs +CommonCrypto/RijndaelManaged.cs +CommonCrypto/SecRandom.cs +CommonCrypto/RC4CommonCrypto.cs +CommonCrypto/MD2Managed.g.cs +CommonCrypto/MD4Managed.g.cs +System/Environment.iOS.cs +System/Guid.MonoTouch.cs +System/NotSupportedException.iOS.cs +CoreFoundation/CFHelpers.cs +System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs +System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs +System.Text/EncodingHelper.MonoTouch.cs diff --git a/mcs/class/corlib/monotouch_tv_opt_corlib.dll.sources b/mcs/class/corlib/monotouch_tv_opt_corlib.dll.sources deleted file mode 100644 index d32b5060240..00000000000 --- a/mcs/class/corlib/monotouch_tv_opt_corlib.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_corlib.dll.sources diff --git a/mcs/class/corlib/monotouch_tv_runtime_corlib.dll.exclude.sources b/mcs/class/corlib/monotouch_tv_runtime_corlib.dll.exclude.sources new file mode 100644 index 00000000000..53efeacceda --- /dev/null +++ b/mcs/class/corlib/monotouch_tv_runtime_corlib.dll.exclude.sources @@ -0,0 +1 @@ +#include monotouch_corlib.dll.exclude.sources diff --git a/mcs/class/corlib/monotouch_tv_runtime_opt_corlib.dll.sources b/mcs/class/corlib/monotouch_tv_runtime_opt_corlib.dll.sources deleted file mode 100644 index d32b5060240..00000000000 --- a/mcs/class/corlib/monotouch_tv_runtime_opt_corlib.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_corlib.dll.sources diff --git a/mcs/class/corlib/monotouch_watch_corlib.dll.exclude.sources b/mcs/class/corlib/monotouch_watch_corlib.dll.exclude.sources new file mode 100644 index 00000000000..53efeacceda --- /dev/null +++ b/mcs/class/corlib/monotouch_watch_corlib.dll.exclude.sources @@ -0,0 +1 @@ +#include monotouch_corlib.dll.exclude.sources diff --git a/mcs/class/corlib/monotouch_watch_corlib.dll.sources b/mcs/class/corlib/monotouch_watch_corlib.dll.sources index da77893bcc5..e802a034dd6 100644 --- a/mcs/class/corlib/monotouch_watch_corlib.dll.sources +++ b/mcs/class/corlib/monotouch_watch_corlib.dll.sources @@ -1 +1,27 @@ #include corlib.dll.sources +CommonCrypto/CommonCrypto.cs +CommonCrypto/CryptorTransform.cs +CommonCrypto/FastCryptorTransform.cs +CommonCrypto/CorlibExtras.cs +CommonCrypto/MD5CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1Managed.g.cs +CommonCrypto/SHA256Managed.g.cs +CommonCrypto/SHA384Managed.g.cs +CommonCrypto/SHA512Managed.g.cs +CommonCrypto/TripleDESCryptoServiceProvider.g.cs +CommonCrypto/DESCryptoServiceProvider.g.cs +CommonCrypto/RC2CryptoServiceProvider.g.cs +CommonCrypto/RijndaelManaged.cs +CommonCrypto/SecRandom.cs +CommonCrypto/RC4CommonCrypto.cs +CommonCrypto/MD2Managed.g.cs +CommonCrypto/MD4Managed.g.cs +System/Environment.iOS.cs +System/Guid.MonoTouch.cs +System/NotSupportedException.iOS.cs +CoreFoundation/CFHelpers.cs +System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs +System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs +System.Text/EncodingHelper.MonoTouch.cs diff --git a/mcs/class/corlib/monotouch_watch_opt_corlib.dll.sources b/mcs/class/corlib/monotouch_watch_opt_corlib.dll.sources deleted file mode 100644 index d32b5060240..00000000000 --- a/mcs/class/corlib/monotouch_watch_opt_corlib.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_corlib.dll.sources diff --git a/mcs/class/corlib/monotouch_watch_runtime_corlib.dll.exclude.sources b/mcs/class/corlib/monotouch_watch_runtime_corlib.dll.exclude.sources new file mode 100644 index 00000000000..53efeacceda --- /dev/null +++ b/mcs/class/corlib/monotouch_watch_runtime_corlib.dll.exclude.sources @@ -0,0 +1 @@ +#include monotouch_corlib.dll.exclude.sources diff --git a/mcs/class/corlib/monotouch_watch_runtime_opt_corlib.dll.sources b/mcs/class/corlib/monotouch_watch_runtime_opt_corlib.dll.sources deleted file mode 100644 index d32b5060240..00000000000 --- a/mcs/class/corlib/monotouch_watch_runtime_opt_corlib.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include monotouch_opt_corlib.dll.sources diff --git a/mcs/class/corlib/xammac_corlib.dll.exclude.sources b/mcs/class/corlib/xammac_corlib.dll.exclude.sources new file mode 100644 index 00000000000..86bb4049f5e --- /dev/null +++ b/mcs/class/corlib/xammac_corlib.dll.exclude.sources @@ -0,0 +1,14 @@ +System.Security.Cryptography/MD5CryptoServiceProvider.cs +System.Security.Cryptography/SHA1CryptoServiceProvider.cs +System.Security.Cryptography/SHA1CryptoServiceProvider.cs +../../../external/referencesource/mscorlib/system/security/cryptography/descryptoserviceprovider.cs +../../../external/referencesource/mscorlib/system/security/cryptography/rc2cryptoserviceprovider.cs +../../../external/referencesource/mscorlib/system/security/cryptography/rijndaelmanaged.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha1managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha256managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha384managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/sha512managed.cs +../../../external/referencesource/mscorlib/system/security/cryptography/tripledescryptoserviceprovider.cs +../Mono.Security/Mono.Security.Cryptography/ARC4Managed.cs +../Mono.Security/Mono.Security.Cryptography/MD2Managed.cs +../Mono.Security/Mono.Security.Cryptography/MD4Managed.cs diff --git a/mcs/class/corlib/xammac_corlib.dll.sources b/mcs/class/corlib/xammac_corlib.dll.sources index da77893bcc5..0dbb5163c70 100644 --- a/mcs/class/corlib/xammac_corlib.dll.sources +++ b/mcs/class/corlib/xammac_corlib.dll.sources @@ -1 +1,22 @@ #include corlib.dll.sources +CommonCrypto/CommonCrypto.cs +CommonCrypto/CryptorTransform.cs +CommonCrypto/FastCryptorTransform.cs +CommonCrypto/CorlibExtras.cs +CommonCrypto/MD5CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1CryptoServiceProvider.g.cs +CommonCrypto/SHA1Managed.g.cs +CommonCrypto/SHA256Managed.g.cs +CommonCrypto/SHA384Managed.g.cs +CommonCrypto/SHA512Managed.g.cs +CommonCrypto/TripleDESCryptoServiceProvider.g.cs +CommonCrypto/DESCryptoServiceProvider.g.cs +CommonCrypto/RC2CryptoServiceProvider.g.cs +CommonCrypto/RijndaelManaged.cs +CommonCrypto/RC4CommonCrypto.cs +CommonCrypto/MD2Managed.g.cs +CommonCrypto/MD4Managed.g.cs +CoreFoundation/CFHelpers.cs +System.Security.Cryptography.X509Certificates/X509CertificateImplApple.cs +System.Security.Cryptography.X509Certificates/X509Helper.Apple.cs diff --git a/mcs/class/corlib/xammac_opt_corlib.dll.sources b/mcs/class/corlib/xammac_opt_corlib.dll.sources deleted file mode 100644 index 449e2520dde..00000000000 --- a/mcs/class/corlib/xammac_opt_corlib.dll.sources +++ /dev/null @@ -1 +0,0 @@ -System.Security.Cryptography.X509Certificates/X509Helper.MonoTouch.opt.cs diff --git a/mcs/tools/mkbundle/mkbundle.cs b/mcs/tools/mkbundle/mkbundle.cs index 46c63cd9dfe..57bae7e4c1d 100755 --- a/mcs/tools/mkbundle/mkbundle.cs +++ b/mcs/tools/mkbundle/mkbundle.cs @@ -97,10 +97,6 @@ class MakeBundle { break; case "--static": static_link = true; - if (!quiet) { - Console.WriteLine ("Note that statically linking the LGPL Mono runtime has more licensing restrictions than dynamically linking."); - Console.WriteLine ("See http://www.mono-project.com/Licensing for details on licensing."); - } break; case "--config": if (i+1 == top) { diff --git a/mono/arch/amd64/amd64-codegen.h b/mono/arch/amd64/amd64-codegen.h index 181913f5751..fcdf30adbfd 100644 --- a/mono/arch/amd64/amd64-codegen.h +++ b/mono/arch/amd64/amd64-codegen.h @@ -11,6 +11,7 @@ * * Copyright (C) 2000 Intel Corporation. All rights reserved. * Copyright (C) 2001, 2002 Ximian, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef AMD64_H diff --git a/mono/arch/arm/arm-codegen.h b/mono/arch/arm/arm-codegen.h index 3ee083f8010..1af30c6b21b 100644 --- a/mono/arch/arm/arm-codegen.h +++ b/mono/arch/arm/arm-codegen.h @@ -3,6 +3,7 @@ * Copyright (c) 2002-2003 Sergey Chaban * Copyright 2005-2011 Novell Inc * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ diff --git a/mono/arch/arm/arm-vfp-codegen.h b/mono/arch/arm/arm-vfp-codegen.h index 8b56b00dbbe..edf558da299 100644 --- a/mono/arch/arm/arm-vfp-codegen.h +++ b/mono/arch/arm/arm-vfp-codegen.h @@ -1,6 +1,7 @@ // // Copyright 2011 Xamarin Inc // +// Licensed under the MIT license. See LICENSE file in the project root for full license information. #ifndef __MONO_ARM_VFP_CODEGEN_H__ #define __MONO_ARM_VFP_CODEGEN_H__ diff --git a/mono/arch/arm/arm-wmmx.h b/mono/arch/arm/arm-wmmx.h index 427c4fc9f60..e43ac7763f3 100644 --- a/mono/arch/arm/arm-wmmx.h +++ b/mono/arch/arm/arm-wmmx.h @@ -2,6 +2,7 @@ * ARM CodeGen * XScale WirelessMMX extensions * Copyright 2002 Wild West Software + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __WMMX_H__ diff --git a/mono/arch/arm64/arm64-codegen.h b/mono/arch/arm64/arm64-codegen.h index 259ff967407..6ca4da6d881 100644 --- a/mono/arch/arm64/arm64-codegen.h +++ b/mono/arch/arm64/arm64-codegen.h @@ -1,3 +1,852 @@ -#include "../../../../mono-extensions/mono/arch/arm64/arm64-codegen.h" +/* + * arm64-codegen.h: ARM64 code generation macros + * + * Author: + * Zoltan Varga (vargaz@gmail.com) + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#ifndef __ARM64_CODEGEN_H__ +#define __ARM64_CODEGEN_H__ +#include + +enum { + ARMREG_R0 = 0, + ARMREG_R1 = 1, + ARMREG_R2 = 2, + ARMREG_R3 = 3, + ARMREG_R4 = 4, + ARMREG_R5 = 5, + ARMREG_R6 = 6, + ARMREG_R7 = 7, + ARMREG_R8 = 8, + ARMREG_R9 = 9, + ARMREG_R10 = 10, + ARMREG_R11 = 11, + ARMREG_R12 = 12, + ARMREG_R13 = 13, + ARMREG_R14 = 14, + ARMREG_R15 = 15, + ARMREG_R16 = 16, + ARMREG_R17 = 17, + ARMREG_R18 = 18, + ARMREG_R19 = 19, + ARMREG_R20 = 20, + ARMREG_R21 = 21, + ARMREG_R22 = 22, + ARMREG_R23 = 23, + ARMREG_R24 = 24, + ARMREG_R25 = 25, + ARMREG_R26 = 26, + ARMREG_R27 = 27, + ARMREG_R28 = 28, + ARMREG_R29 = 29, + ARMREG_R30 = 30, + ARMREG_SP = 31, + ARMREG_RZR = 31, + + ARMREG_IP0 = ARMREG_R16, + ARMREG_IP1 = ARMREG_R17, + ARMREG_FP = ARMREG_R29, + ARMREG_LR = ARMREG_R30 +}; + +enum { + ARMREG_D0 = 0, + ARMREG_D1 = 1, + ARMREG_D2 = 2, + ARMREG_D3 = 3, + ARMREG_D4 = 4, + ARMREG_D5 = 5, + ARMREG_D6 = 6, + ARMREG_D7 = 7, + ARMREG_D8 = 8, + ARMREG_D9 = 9, + ARMREG_D10 = 10, + ARMREG_D11 = 11, + ARMREG_D12 = 12, + ARMREG_D13 = 13, + ARMREG_D14 = 14, + ARMREG_D15 = 15, + ARMREG_D16 = 16, + ARMREG_D17 = 17, + ARMREG_D18 = 18, + ARMREG_D19 = 19, + ARMREG_D20 = 20, + ARMREG_D21 = 21, + ARMREG_D22 = 22, + ARMREG_D23 = 23, + ARMREG_D24 = 24, + ARMREG_D25 = 25, + ARMREG_D26 = 26, + ARMREG_D27 = 27, + ARMREG_D28 = 28, + ARMREG_D29 = 29, + ARMREG_D30 = 30, + ARMREG_D31 = 31 +}; + +typedef enum { + ARMCOND_EQ = 0x0, /* Equal; Z = 1 */ + ARMCOND_NE = 0x1, /* Not equal, or unordered; Z = 0 */ + ARMCOND_CS = 0x2, /* Carry set; C = 1 */ + ARMCOND_HS = ARMCOND_CS, /* Unsigned higher or same; */ + ARMCOND_CC = 0x3, /* Carry clear; C = 0 */ + ARMCOND_LO = ARMCOND_CC, /* Unsigned lower */ + ARMCOND_MI = 0x4, /* Negative; N = 1 */ + ARMCOND_PL = 0x5, /* Positive or zero; N = 0 */ + ARMCOND_VS = 0x6, /* Overflow; V = 1 */ + ARMCOND_VC = 0x7, /* No overflow; V = 0 */ + ARMCOND_HI = 0x8, /* Unsigned higher; C = 1 && Z = 0 */ + ARMCOND_LS = 0x9, /* Unsigned lower or same; C = 0 || Z = 1 */ + ARMCOND_GE = 0xA, /* Signed greater than or equal; N = V */ + ARMCOND_LT = 0xB, /* Signed less than; N != V */ + ARMCOND_GT = 0xC, /* Signed greater than; Z = 0 && N = V */ + ARMCOND_LE = 0xD, /* Signed less than or equal; Z = 1 || N != V */ + ARMCOND_AL = 0xE, /* Always */ + ARMCOND_NV = 0xF, /* Never */ +} ARMCond; + +typedef enum { + ARMSHIFT_LSL = 0x0, + ARMSHIFT_LSR = 0x1, + ARMSHIFT_ASR = 0x2 +} ARMShift; + +typedef enum { + ARMSIZE_B = 0x0, + ARMSIZE_H = 0x1, + ARMSIZE_W = 0x2, + ARMSIZE_X = 0x3 +} ARMSize; + +#define arm_emit(p, ins) do { *(guint32*)(p) = (ins); (p) += 4; } while (0) + +/* Overwrite bits [offset,offset+nbits] with value */ +static G_GNUC_UNUSED inline void +arm_set_ins_bits (void *p, int offset, int nbits, guint32 value) +{ + *(guint32*)p = (*(guint32*)p & ~(((1 << nbits) - 1) << offset)) | (value << offset); +} + +/* + * Naming conventions for codegen macros: + * - 64 bit opcodes have an 'X' suffix + * - 32 bit opcodes have a 'W' suffix + * - the order of operands is the same as in assembly + */ + +/* + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a/index.html + */ + +/* Uncoditional branch (register) */ + +// 0b1101011 == 0x6b +#define arm_format_breg(p, opc, op2, op3, op4, rn) arm_emit ((p), (0x6b << 25) | ((opc) << 21) | ((op2) << 16) | ((op3) << 10) | ((rn) << 5) | ((op4) << 0)) + +// 0b0000 == 0x0, 0b11111 == 0x1f +#define arm_brx(p, reg) arm_format_breg ((p), 0x0, 0x1f, 0x0, 0x0, (reg)) + +// 0b0001 == 0x1 +#define arm_blrx(p, reg) arm_format_breg ((p), 0x1, 0x1f, 0x0, 0x0, (reg)) + +//0b0010 == 0x2 +#define arm_retx(p, reg) arm_format_breg ((p), 0x2, 0x1f, 0x0, 0x0, (reg)) + +/* Unconditional branch (immeditate) */ + +static G_GNUC_UNUSED inline gboolean +arm_is_bl_disp (void *code, void *target) +{ + gint64 disp = ((char*)(target) - (char*)(code)) / 4; + + return (disp > -(1 << 25)) && (disp < (1 << 25)); +} + +static G_GNUC_UNUSED inline unsigned int +arm_get_disp (void *p, void *target) +{ + unsigned int disp = ((char*)target - (char*)p) / 4; + + if (target) + g_assert (arm_is_bl_disp (p, target)); + + return (disp & 0x3ffffff); +} + +// 0b00101 == 0x5 +#define arm_b(p, target) arm_emit (p, (0x0 << 31) | (0x5 << 26) | ((arm_get_disp ((p), (target)) << 0))) + +#define arm_bl(p, target) arm_emit (p, (0x1 << 31) | (0x5 << 26) | ((arm_get_disp ((p), (target)) << 0))) + +/* Conditional branch */ + +static G_GNUC_UNUSED inline gboolean +arm_is_disp19 (void *code, void *target) +{ + gint64 disp = ((char*)(target) - (char*)(code)) / 4; + + return (disp > -(1 << 18)) && (disp < (1 << 18)); +} + +static G_GNUC_UNUSED inline unsigned int +arm_get_disp19 (void *p, void *target) +{ + unsigned int disp = ((char*)target - (char*)p) / 4; + + if (target) + g_assert (arm_is_disp19 (p, target)); + + return (disp & 0x7ffff); +} + +// 0b0101010 == 0x2a +#define arm_format_condbr(p, o1, o0, cond, disp) arm_emit ((p), (0x2a << 25) | ((o1) << 24) | ((disp) << 5) | ((o0) << 4) | ((cond) << 0)) +#define arm_get_bcc_cond(p) ((*(guint32*)p) & 0xf) + +#define arm_bcc(p, cond, target) arm_format_condbr ((p), 0x0, 0x0, (cond), arm_get_disp19 ((p), (target))) + +// 0b011010 == 0x1a +#define arm_format_cmpbr(p, sf, op, rt, target) arm_emit ((p), ((sf) << 31) | (0x1a << 25) | ((op) << 24) | (arm_get_disp19 ((p), (target)) << 5) | ((rt) << 0)) + +#define arm_set_cbz_target(p, target) arm_set_ins_bits (p, 5, 19, arm_get_disp19 ((p), (target))) + +#define arm_cbzx(p, rt, target) arm_format_cmpbr ((p), 0x1, 0x0, (rt), (target)) +#define arm_cbzw(p, rt, target) arm_format_cmpbr ((p), 0x0, 0x0, (rt), (target)) + +#define arm_cbnzx(p, rt, target) arm_format_cmpbr ((p), 0x1, 0x1, (rt), (target)) +#define arm_cbnzw(p, rt, target) arm_format_cmpbr ((p), 0x0, 0x1, (rt), (target)) + +static G_GNUC_UNUSED inline unsigned int +arm_get_disp15 (void *p, void *target) +{ + unsigned int disp = ((char*)target - (char*)p) / 4; + return (disp & 0x7fff); +} + +// 0b011011 == 0x1b +#define arm_format_tbimm(p, op, rt, bit, target) arm_emit ((p), ((((bit) >> 5) & 1) << 31) | (0x1b << 25) | ((op) << 24) | (((bit) & 0x1f) << 19) | (arm_get_disp15 ((p), (target)) << 5) | ((rt) << 0)) + +#define arm_tbz(p, rt, bit, target) arm_format_tbimm ((p), 0x0, (rt), (bit), (target)) +#define arm_tbnz(p, rt, bit, target) arm_format_tbimm ((p), 0x1, (rt), (bit), (target)) + +/* Memory access */ + +#define arm_is_pimm12_scaled(pimm,size) ((pimm) >= 0 && (pimm) / (size) <= 0xfff && ((pimm) % (size)) == 0) + +static G_GNUC_UNUSED unsigned int +arm_encode_pimm12 (int pimm, int size) +{ + g_assert (arm_is_pimm12_scaled (pimm, size)); + return ((unsigned int)(pimm / size)) & 0xfff; +} + +#define arm_is_strb_imm(pimm) arm_is_pimm12_scaled((pimm), 1) +#define arm_is_strh_imm(pimm) arm_is_pimm12_scaled((pimm), 2) +#define arm_is_strw_imm(pimm) arm_is_pimm12_scaled((pimm), 4) +#define arm_is_strx_imm(pimm) arm_is_pimm12_scaled((pimm), 8) + +/* Load/Store register + scaled immediate */ +/* No pre-index/post-index yet */ +#define arm_format_mem_imm(p, size, opc, rt, rn, pimm, scale) arm_emit ((p), ((size) << 30) | (0x39 << 24) | ((opc) << 22) | (arm_encode_pimm12 ((pimm), (scale)) << 10) | ((rn) << 5) | ((rt) << 0)) + +/* C5.6.83 LDR (immediate) */ +#define arm_ldrx(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_X, 0x1, (rt), (rn), (pimm), 8) +#define arm_ldrw(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_W, 0x1, (rt), (rn), (pimm), 4) +/* C5.6.86 LDRB (immediate) */ +#define arm_ldrb(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_B, 0x1, (rt), (rn), (pimm), 1) +/* C5.6.88 LDRH (immediate) */ +#define arm_ldrh(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_H, 0x1, (rt), (rn), (pimm), 2) +/* C5.6.90 LDRSB (immediate) */ +#define arm_ldrsbx(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_B, 0x2, (rt), (rn), (pimm), 1) +#define arm_ldrsbw(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_B, 0x3, (rt), (rn), (pimm), 1) +/* C5.6.92 LDRSH (immediate) */ +#define arm_ldrshx(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_H, 0x2, (rt), (rn), (pimm), 2) +#define arm_ldrshw(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_H, 0x3, (rt), (rn), (pimm), 2) +/* C5.6.94 LDRSW (immediate) */ +#define arm_ldrswx(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_W, 0x2, (rt), (rn), (pimm), 4) + +/* C5.6.178 STR (immediate) */ +#define arm_strx(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_X, 0x0, (rt), (rn), (pimm), 8) +#define arm_strw(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_W, 0x0, (rt), (rn), (pimm), 4) +/* C5.6.182 STR (immediate) */ +#define arm_strh(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_H, 0x0, (rt), (rn), (pimm), 2) +#define arm_strb(p, rt, rn, pimm) arm_format_mem_imm (p, ARMSIZE_B, 0x0, (rt), (rn), (pimm), 1) + +/* C3.3.9 Load/store register (immediate post-indexed) */ +static G_GNUC_UNUSED unsigned int +arm_encode_simm9 (int simm) +{ + g_assert (simm >= -256 && simm <= 255); + return ((unsigned int)simm) & 0x1ff; +} + +#define arm_format_mem_imm_post(p, size, V, opc, rt, rn, simm) arm_emit ((p), ((size) << 30) | (0x7 << 27) | ((V) << 26) | (0x0 << 24) | ((opc) << 22) | (arm_encode_simm9 ((simm)) << 12) | (0x1 << 10) | ((rn) << 5) | ((rt) << 0)) + +#define arm_ldrx_post(p, rt, rn, simm) arm_format_mem_imm_post (p, ARMSIZE_X, 0x0, 0x1, (rt), (rn), (simm)) +#define arm_ldrw_post(p, rt, rn, simm) arm_format_mem_imm_post (p, ARMSIZE_W, 0x0, 0x1, (rt), (rn), (simm)) + +#define arm_strx_post(p, rt, rn, simm) arm_format_mem_imm_post (p, ARMSIZE_X, 0x0, 0x0, (rt), (rn), (simm)) +#define arm_strw_post(p, rt, rn, simm) arm_format_mem_imm_post (p, ARMSIZE_W, 0x0, 0x0, (rt), (rn), (simm)) + +/* C3.3.9 Load/store register (immediate pre-indexed) */ +#define arm_format_mem_imm_pre(p, size, V, opc, rt, rn, simm) arm_emit ((p), ((size) << 30) | (0x7 << 27) | ((V) << 26) | (0x0 << 24) | ((opc) << 22) | (arm_encode_simm9 ((simm)) << 12) | (0x3 << 10) | ((rn) << 5) | ((rt) << 0)) + +#define arm_ldrx_pre(p, rt, rn, simm) arm_format_mem_imm_pre (p, ARMSIZE_X, 0x0, 0x1, (rt), (rn), (simm)) +#define arm_ldrw_pre(p, rt, rn, simm) arm_format_mem_imm_pre (p, ARMSIZE_W, 0x0, 0x1, (rt), (rn), (simm)) + +#define arm_strx_pre(p, rt, rn, simm) arm_format_mem_imm_pre (p, ARMSIZE_X, 0x0, 0x0, (rt), (rn), (simm)) +#define arm_strw_pre(p, rt, rn, simm) arm_format_mem_imm_pre (p, ARMSIZE_W, 0x0, 0x0, (rt), (rn), (simm)) + +/* Load/Store register + register */ +/* No extend/scale yet */ +#define arm_format_mem_reg(p, size, opc, rt, rn, rm) arm_emit ((p), ((size) << 30) | (0x38 << 24) | ((opc) << 22) | (0x1 << 21) | ((rm) << 16) | (0x3 << 13) | (0 << 12) | (0x2 << 10) | ((rn) << 5) | ((rt) << 0)) + +/* C5.6.85 LDR (register) */ +#define arm_ldrx_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_X, 0x1, (rt), (rn), (rm)) +#define arm_ldrw_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_W, 0x1, (rt), (rn), (rm)) +/* C5.6.87 LDRB (register) */ +#define arm_ldrb_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_B, 0x1, (rt), (rn), (rm)) +/* C5.6.88 LDRH (register) */ +#define arm_ldrh_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_H, 0x1, (rt), (rn), (rm)) +/* C5.6.91 LDRSB (register) */ +#define arm_ldrsbx_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_B, 0x2, (rt), (rn), (rm)) +#define arm_ldrsbw_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_B, 0x3, (rt), (rn), (rm)) +/* C5.6.93 LDRSH (register) */ +#define arm_ldrshx_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_H, 0x2, (rt), (rn), (rm)) +#define arm_ldrshw_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_H, 0x3, (rt), (rn), (rm)) +/* C5.6.96 LDRSW (register) */ +#define arm_ldrswx_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_W, 0x2, (rt), (rn), (rm)) + +/* C5.6.179 STR (register) */ +#define arm_strx_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_X, 0x0, (rt), (rn), (rm)) +#define arm_strw_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_W, 0x0, (rt), (rn), (rm)) +/* C5.6.181 STRB (register) */ +#define arm_strb_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_B, 0x0, (rt), (rn), (rm)) +/* C5.6.183 STRH (register) */ +#define arm_strh_reg(p, rt, rn, rm) arm_format_mem_reg ((p), ARMSIZE_H, 0x0, (rt), (rn), (rm)) + +/* PC relative */ + +/* C5.6.84 LDR (literal) */ + +#define arm_get_ldr_lit_reg(p) (*(guint32*)(p) & 0x1f) + +#define arm_ldrx_lit(p, rt, target) arm_emit ((p), (0x01 << 30) | (0x18 << 24) | (arm_get_disp19 ((p), (target)) << 5) | ((rt) << 0)) +#define arm_ldrw_lit(p, rt, target) arm_emit ((p), (0x00 << 30) | (0x18 << 24) | (arm_get_disp19 ((p), (target)) << 5) | ((rt) << 0)) +#define arm_ldrswx_lit(p, rt, target) arm_emit ((p), (0x2 << 30) | (0x18 << 24) | (arm_get_disp19 ((p), (target)) << 5) | ((rt) << 0)) + +/* Unscaled offset */ +/* FIXME: Not yet */ + +/* Load/Store Pair */ + +static G_GNUC_UNUSED unsigned int +arm_encode_imm7 (int imm, int size) +{ + g_assert (imm / size >= -64 && imm / size <= 63 && (imm % size) == 0); + return ((unsigned int)(imm / size)) & 0x7f; +} + +#define arm_is_imm7_scaled(imm, size) ((imm) / (size) >= -64 && (imm) / (size) <= 63 && ((imm) % (size)) == 0) + +#define arm_is_ldpx_imm(imm) arm_is_imm7_scaled ((imm), 8) + +/* C3.3.14 */ +#define arm_format_mem_p(p, size, opc, L, rt1, rt2, rn, imm) arm_emit ((p), (opc << 30) | (0x52 << 23) | ((L) << 22) | (arm_encode_imm7 (imm, size) << 15) | ((rt2) << 10) | ((rn) << 5) | ((rt1) << 0)) + +#define arm_ldpx(p, rt1, rt2, rn, imm) arm_format_mem_p ((p), 8, 0x2, 1, (rt1), (rt2), (rn), (imm)) +#define arm_ldpw(p, rt1, rt2, rn, imm) arm_format_mem_p ((p), 4, 0x0, 1, (rt1), (rt2), (rn), (imm)) +#define arm_ldpsw(p, rt1, rt2, rn, imm) arm_format_mem_p ((p), 4, 0x1, 1, (rt1), (rt2), (rn), (imm)) +#define arm_stpx(p, rt1, rt2, rn, imm) arm_format_mem_p ((p), 8, 0x2, 0, (rt1), (rt2), (rn), (imm)) +#define arm_stpw(p, rt1, rt2, rn, imm) arm_format_mem_p ((p), 4, 0x0, 0, (rt1), (rt2), (rn), (imm)) + +/* Load/Store Pair (Pre-indexed) */ +/* C3.3.16 */ +#define arm_format_mem_p_pre(p, size, opc, L, rt1, rt2, rn, imm) arm_emit ((p), (opc << 30) | (0x53 << 23) | ((L) << 22) | (arm_encode_imm7 (imm, size) << 15) | ((rt2) << 10) | ((rn) << 5) | ((rt1) << 0)) + +#define arm_ldpx_pre(p, rt1, rt2, rn, imm) arm_format_mem_p_pre ((p), 8, 0x2, 1, (rt1), (rt2), (rn), (imm)) +#define arm_ldpw_pre(p, rt1, rt2, rn, imm) arm_format_mem_p_pre ((p), 4, 0x0, 1, (rt1), (rt2), (rn), (imm)) +#define arm_ldpsw_pre(p, rt1, rt2, rn, imm) arm_format_mem_p_pre ((p), 4, 0x1, 1, (rt1), (rt2), (rn), (imm)) +#define arm_stpx_pre(p, rt1, rt2, rn, imm) arm_format_mem_p_pre ((p), 8, 0x2, 0, (rt1), (rt2), (rn), (imm)) +#define arm_stpw_pre(p, rt1, rt2, rn, imm) arm_format_mem_p_pre ((p), 4, 0x0, 0, (rt1), (rt2), (rn), (imm)) + +/* Not an official alias */ +#define arm_pushpx (p, rt1, rt2) arm_LDPX_pre (p, rt1, rt2, ARMREG_RSP, -8) + +/* Load/Store Pair (Post-indexed) */ +/* C3.3.15 */ +#define arm_format_mem_p_post(p, size, opc, L, rt1, rt2, rn, imm) arm_emit ((p), (opc << 30) | (0x51 << 23) | ((L) << 22) | (arm_encode_imm7 (imm, size) << 15) | ((rt2) << 10) | ((rn) << 5) | ((rt1) << 0)) + +#define arm_ldpx_post(p, rt1, rt2, rn, imm) arm_format_mem_p_post ((p), 8, 0x2, 1, (rt1), (rt2), (rn), (imm)) +#define arm_ldpw_post(p, rt1, rt2, rn, imm) arm_format_mem_p_post ((p), 4, 0x0, 1, (rt1), (rt2), (rn), (imm)) +#define arm_ldpsw_post(p, rt1, rt2, rn, imm) arm_format_mem_p_post ((p), 4, 0x1, 1, (rt1), (rt2), (rn), (imm)) +#define arm_stpx_post(p, rt1, rt2, rn, imm) arm_format_mem_p_post ((p), 8, 0x2, 0, (rt1), (rt2), (rn), (imm)) +#define arm_stpw_post(p, rt1, rt2, rn, imm) arm_format_mem_p_post ((p), 4, 0x0, 0, (rt1), (rt2), (rn), (imm)) + +/* Not an official alias */ +#define arm_poppx (p, rt1, rt2) arm_ldpx_post (p, rt1, rt2, ARMREG_RSP, 8) + +/* Load/Store Exclusive */ +#define arm_format_ldxr(p, size, rt, rn) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x0 << 23) | (0x1 << 22) | (0x0 << 21) | (0x1f << 16) | (0x0 << 15) | (0x1f << 10) | ((rn) << 5) | ((rt) << 0)) +#define arm_format_ldxp(p, size, rt1, rt2, rn) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x0 << 23) | (0x1 << 22) | (0x1 << 21) | (0x1f << 16) | (0x0 << 15) | ((rt2) << 10)| ((rn) << 5) | ((rt1) << 0)) +#define arm_format_stxr(p, size, rs, rt, rn) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x0 << 23) | (0x0 << 22) | (0x0 << 21) | ((rs) << 16) | (0x0 << 15) | (0x1f << 10) | ((rn) << 5) | ((rt) << 0)) +#define arm_format_stxp(p, size, rs, rt1, rt2, rn) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x0 << 23) | (0x0 << 22) | (0x1 << 21) | ((rs) << 16) | (0x0 << 15) | ((rt2) << 10)| ((rn) << 5) | ((rt1) << 0)) + +#define arm_ldxrx(p, rt, rn) arm_format_ldxr ((p), ARMSIZE_X, (rt), (rn)) +#define arm_ldxrw(p, rt, rn) arm_format_ldxr ((p), ARMSIZE_W, (rt), (rn)) +#define arm_ldxrh(p, rt, rn) arm_format_ldxr ((p), ARMSIZE_H, (rt), (rn)) +#define arm_ldxrb(p, rt, rn) arm_format_ldxr ((p), ARMSIZE_B, (rt), (rn)) +#define arm_ldxpx(p, rt1, rt2, rn) arm_format_ldxp ((p), ARMSIZE_X, (rt1), (rt2), (rn)) +#define arm_ldxpw(p, rt1, rt2, rn) arm_format_ldxp ((p), ARMSIZE_W, (rt1), (rt2), (rn)) +#define arm_stxrx(p, rs, rt, rn) arm_format_stxr ((p), ARMSIZE_X, (rs), (rt), (rn)) +#define arm_stxrw(p, rs, rt, rn) arm_format_stxr ((p), ARMSIZE_W, (rs), (rt), (rn)) +#define arm_stxrh(p, rs, rt, rn) arm_format_stxr ((p), ARMSIZE_H, (rs), (rt), (rn)) +#define arm_stxrb(p, rs, rt, rn) arm_format_stxr ((p), ARMSIZE_B, (rs), (rt), (rn)) +#define arm_stxpx(p, rs, rt1, rt2, rn) arm_format_stxp ((p), ARMSIZE_X, (rs), (rt1), (rt2), (rn)) +#define arm_stxpw(p, rs, rt1, rt2, rn) arm_format_stxp ((p), ARMSIZE_W, (rs), (rt1), (rt2), (rn)) + +/* C5.6.73 LDAR: Load-Acquire Register */ + +#define arm_format_ldar(p, size, rt, rn) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x1 << 23) | (0x1 << 22) | (0x0 << 21) | (0x1f << 16) | (0x1 << 15) | (0x1f << 10) | ((rn) << 5) | ((rt) << 0)) + +#define arm_ldarx(p, rt, rn) arm_format_ldar ((p), ARMSIZE_X, (rt), (rn)) +#define arm_ldarw(p, rt, rn) arm_format_ldar ((p), ARMSIZE_W, (rt), (rn)) +#define arm_ldarh(p, rt, rn) arm_format_ldar ((p), ARMSIZE_H, (rt), (rn)) +#define arm_ldarb(p, rt, rn) arm_format_ldar ((p), ARMSIZE_B, (rt), (rn)) + +/* C5.6.169 STLR: Store-Release Register */ + +#define arm_format_stlr(p, size, rt, rn) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x1 << 23) | (0x0 << 22) | (0x0 << 21) | (0x1f << 16) | (0x1 << 15) | (0x1f << 10) | ((rn) << 5) | ((rt) << 0)) + +#define arm_stlrx(p, rn, rt) arm_format_stlr ((p), ARMSIZE_X, (rt), (rn)) +#define arm_stlrw(p, rn, rt) arm_format_stlr ((p), ARMSIZE_W, (rt), (rn)) +#define arm_stlrh(p, rn, rt) arm_format_stlr ((p), ARMSIZE_H, (rt), (rn)) +#define arm_stlrb(p, rn, rt) arm_format_stlr ((p), ARMSIZE_B, (rt), (rn)) + +/* C5.6.77 LDAXR */ +#define arm_format_ldaxr(p, size, rn, rt) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x0 << 23) | (0x1 << 22) | (0x0 << 21) | (0x1f << 16) | (0x1 << 15) | (0x1f << 10) | ((rn) << 5) | ((rt) << 0)) + +#define arm_ldaxrx(p, rt, rn) arm_format_ldaxr ((p), 0x3, (rn), (rt)) +#define arm_ldaxrw(p, rt, rn) arm_format_ldaxr ((p), 0x2, (rn), (rt)) + +/* C5.6.173 STLXR */ +#define arm_format_stlxr(p, size, rs, rn, rt) arm_emit ((p), ((size) << 30) | (0x8 << 24) | (0x0 << 23) | (0x0 << 22) | (0x0 << 21) | ((rs) << 16) | (0x1 << 15) | (0x1f << 10) | ((rn) << 5) | ((rt) << 0)) + +#define arm_stlxrx(p, rs, rt, rn) arm_format_stlxr ((p), 0x3, (rs), (rn), (rt)) +#define arm_stlxrw(p, rs, rt, rn) arm_format_stlxr ((p), 0x2, (rs), (rn), (rt)) + +/* Load/Store SIMD&FP */ + +/* C6.3.285 STR (immediate, SIMD&FP) */ +#define arm_format_strfp_imm(p, size, opc, rt, rn, pimm, scale) arm_emit ((p), ((size) << 30) | (0xf << 26) | (0x1 << 24) | ((opc) << 22) | (arm_encode_pimm12 ((pimm), (scale)) << 10) | ((rn) << 5) | ((rt) << 0)) + +/* Store double */ +#define arm_strfpx(p, dt, xn, simm) arm_format_strfp_imm ((p), ARMSIZE_X, 0x0, (dt), (xn), (simm), 8) +/* Store single */ +#define arm_strfpw(p, st, xn, simm) arm_format_strfp_imm ((p), ARMSIZE_W, 0x0, (st), (xn), (simm), 4) + +/* C6.3.166 LDR (immediate, SIMD&FP) */ +#define arm_format_ldrfp_imm(p, size, opc, rt, rn, pimm, scale) arm_emit ((p), ((size) << 30) | (0xf << 26) | (0x1 << 24) | ((opc) << 22) | (arm_encode_pimm12 ((pimm), (scale)) << 10) | ((rn) << 5) | ((rt) << 0)) + +/* Load double */ +#define arm_ldrfpx(p, dt, xn, simm) arm_format_ldrfp_imm ((p), ARMSIZE_X, 0x1, dt, xn, simm, 8) +/* Load single */ +#define arm_ldrfpw(p, dt, xn, simm) arm_format_ldrfp_imm ((p), ARMSIZE_W, 0x1, dt, xn, simm, 4) + +/* Arithmetic (immediate) */ +static G_GNUC_UNUSED inline guint32 +arm_encode_arith_imm (int imm, guint32 *shift) +{ + // FIXME: + g_assert ((imm >= 0) && (imm < 0xfff)); + *shift = 0; + return (guint32)imm; +} + +// FIXME: +#define arm_is_arith_imm(imm) (((imm) >= 0) && ((imm) < 0xfff)) + +#define arm_format_alu_imm(p, sf, op, S, rd, rn, imm) do { \ + guint32 _imm12, _shift; \ + _imm12 = arm_encode_arith_imm ((imm), &_shift); arm_emit ((p), ((sf) << 31) | ((op) << 30) | ((S) << 29) | (0x11 << 24) | ((_shift) << 22) | ((_imm12) << 10) | ((rn) << 5) | ((rd) << 0)); \ +} while (0) + +/* rd/rn can be SP for addx/subx */ +#define arm_addx_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x1, 0x0, 0x0, (rd), (rn), (imm)) +#define arm_addw_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x0, 0x0, 0x0, (rd), (rn), (imm)) +#define arm_addsx_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x1, 0x0, 0x1, (rd), (rn), (imm)) +#define arm_addsw_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x0, 0x0, 0x1, (rd), (rn), (imm)) +#define arm_subx_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x1, 0x1, 0x0, (rd), (rn), (imm)) +#define arm_subw_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x0, 0x1, 0x0, (rd), (rn), (imm)) +#define arm_subsx_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x1, 0x1, 0x1, (rd), (rn), (imm)) +#define arm_subsw_imm(p, rd, rn, imm) arm_format_alu_imm ((p), 0x0, 0x1, 0x1, (rd), (rn), (imm)) + +#define arm_cmpx_imm(p, rn, imm) arm_subsx_imm ((p), ARMREG_RZR, (rn), (imm)) +#define arm_cmpw_imm(p, rn, imm) arm_subsw_imm ((p), ARMREG_RZR, (rn), (imm)) +#define arm_cmnx_imm(p, rn, imm) arm_addsx_imm ((p), ARMREG_RZR, (rn), (imm)) +#define arm_cmnw_imm(p, rn, imm) arm_addsw_imm ((p), ARMREG_RZR, (rn), (imm)) + +/* Logical (immediate) */ + +// FIXME: imm +#if 0 +#define arm_format_and(p, sf, opc, rd, rn, imm) arm_emit ((p), ((sf) << 31) | ((opc) << 29) | (0x24 << 23) | ((0) << 22) | ((imm) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_andx_imm(p, rd, rn, imm) arm_format_and ((p), 0x1, 0x0, (rd), (rn), (imm)) +#define arm_andw_imm(p, rd, rn, imm) arm_format_and ((p), 0x0, 0x0, (rd), (rn), (imm)) +#define arm_andsx_imm(p, rd, rn, imm) arm_format_and ((p), 0x1, 0x3, (rd), (rn), (imm)) +#define arm_andsw_imm(p, rd, rn, imm) arm_format_and ((p), 0x0, 0x3, (rd), (rn), (imm)) +#define arm_eorx_imm(p, rd, rn, imm) arm_format_and ((p), 0x1, 0x2, (rd), (rn), (imm)) +#define arm_eorw_imm(p, rd, rn, imm) arm_format_and ((p), 0x0, 0x2, (rd), (rn), (imm)) +#define arm_orrx_imm(p, rd, rn, imm) arm_format_and ((p), 0x1, 0x1, (rd), (rn), (imm)) +#define arm_orrw_imm(p, rd, rn, imm) arm_format_and ((p), 0x0, 0x1, (rd), (rn), (imm)) + +#define arm_tstx_imm(p, rn, imm) arm_andsx_imm ((p), ARMREG_RZR, (rn), (imm)) +#define arm_tstw_imm(p, rn, imm) arm_andsw_imm ((p), ARMREG_RZR, (rn), (imm)) +#endif + +/* Move (wide immediate) */ +#define arm_format_mov(p, sf, opc, hw, rd, imm16) arm_emit ((p), ((sf) << 31) | ((opc) << 29) | (0x25 << 23) | ((hw) << 21) | (((guint32)(imm16) & 0xffff) << 5) | ((rd) << 0)) + +#define arm_get_movzx_rd(p) ((*(guint32*)p) & 0x1f) + +#define arm_movzx(p, rd, imm, shift) do { g_assert ((shift) % 16 == 0); arm_format_mov ((p), 0x1, 0x2, (shift) / 16, (rd), (imm)); } while (0) +#define arm_movzw(p, rd, imm, shift) do { g_assert ((shift) % 16 == 0); arm_format_mov ((p), 0x0, 0x2, (shift) / 16, (rd), (imm)); } while (0) +#define arm_movnx(p, rd, imm, shift) do { g_assert ((shift) % 16 == 0); arm_format_mov ((p), 0x1, 0x0, (shift) / 16, (rd), (imm)); } while (0) +#define arm_movnw(p, rd, imm, shift) do { g_assert ((shift) % 16 == 0); arm_format_mov ((p), 0x0, 0x0, (shift) / 16, (rd), (imm)); } while (0) +#define arm_movkx(p, rd, imm, shift) do { g_assert ((shift) % 16 == 0); arm_format_mov ((p), 0x1, 0x3, (shift) / 16, (rd), (imm)); } while (0) +#define arm_movkw(p, rd, imm, shift) do { g_assert ((shift) % 16 == 0); arm_format_mov ((p), 0x0, 0x3, (shift) / 16, (rd), (imm)); } while (0) + +/* PC-relative address calculation */ +#define arm_format_adrp(p, op, rd, target) do { guint64 imm1 = (guint64)(target); guint64 imm2 = (guint64)(p); int _imm = imm1 - imm2; arm_emit ((p), ((op) << 31) | (((_imm) & 0x3) << 29) | (0x10 << 24) | (((_imm >> 2) & 0x7ffff) << 5) | ((rd) << 0)); } while (0) + +#define arm_adrpx(p, rd, target) arm_format_adrp ((p), 0x1, (rd), (target)) +#define arm_adrx(p, rd, target) arm_format_adrp ((p), 0x0, (rd), (target)) + +/* Bitfield move */ +#define arm_format_bfm(p, sf, opc, N, immr, imms, rn, rd) arm_emit ((p), ((sf) << 31) | ((opc) << 29) | (0x26 << 23) | ((N) << 22) | ((N) << 22) | ((immr) << 16) | ((imms) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_bfmx(p, rd, rn, immr, imms) arm_format_bfm ((p), 0x1, 0x1, 0x1, (immr), (imms), (rn), (rd)) +#define arm_bfmw(p, rd, rn, immr, imms) arm_format_bfm ((p), 0x0, 0x1, 0x0, (immr), (imms), (rn), (rd)) +#define arm_sbfmx(p, rd, rn, immr, imms) arm_format_bfm ((p), 0x1, 0x0, 0x1, (immr), (imms), (rn), (rd)) +#define arm_sbfmw(p, rd, rn, immr, imms) arm_format_bfm ((p), 0x0, 0x0, 0x0, (immr), (imms), (rn), (rd)) +#define arm_ubfmx(p, rd, rn, immr, imms) arm_format_bfm ((p), 0x1, 0x2, 0x1, (immr), (imms), (rn), (rd)) +#define arm_ubfmw(p, rd, rn, immr, imms) arm_format_bfm ((p), 0x0, 0x2, 0x0, (immr), (imms), (rn), (rd)) + +/* Sign extend and Zero-extend */ +#define arm_sxtbx(p, rd, rn) arm_sbfmx ((p), (rd), (rn), 0, 7) +#define arm_sxtbw(p, rd, rn) arm_sbfmw ((p), (rd), (rn), 0, 7) +#define arm_sxthx(p, rd, rn) arm_sbfmx ((p), (rd), (rn), 0, 15) +#define arm_sxthw(p, rd, rn) arm_sbfmw ((p), (rd), (rn), 0, 15) +#define arm_sxtwx(p, rd, rn) arm_sbfmx ((p), (rd), (rn), 0, 31) +#define arm_uxtbx(p, rd, rn) arm_ubfmx ((p), (rd), (rn), 0, 7) +#define arm_uxtbw(p, rd, rn) arm_ubfmw ((p), (rd), (rn), 0, 7) +#define arm_uxthx(p, rd, rn) arm_ubfmx ((p), (rd), (rn), 0, 15) +#define arm_uxthw(p, rd, rn) arm_ubfmw ((p), (rd), (rn), 0, 15) + +/* Extract register */ +#define arm_format_extr(p, sf, N, rd, rn, rm, imms) arm_emit ((p), ((sf) << 31) | (0x27 << 23) | ((N) << 22) | (0x0 << 21) | ((rm) << 16) | ((imms) << 10) | ((rn) << 5) | ((rd) << 0)) +#define arm_extrx(p, rd, rn, rm, lsb) arm_format_extr ((p), 0x1, 0x1, (rd), (rn), (rm), (lsb)) +#define arm_extrw(p, rd, rn, rm, lsb) arm_format_extr ((p), 0x0, 0x0, (rd), (rn), (rm), (lsb)) + +/* Shift (immediate) */ +#define arm_asrx(p, rd, rn, shift) arm_sbfmx ((p), (rd), (rn), (shift), 63) +#define arm_asrw(p, rd, rn, shift) arm_sbfmw ((p), (rd), (rn), (shift), 31) +#define arm_lslx(p, rd, rn, shift) arm_ubfmx ((p), (rd), (rn), 64 - ((shift) % 64), 63 - ((shift) % 64)) +#define arm_lslw(p, rd, rn, shift) arm_ubfmw ((p), (rd), (rn), 32 - ((shift) % 32), 31 - ((shift) % 32)) +#define arm_lsrx(p, rd, rn, shift) arm_ubfmx ((p), (rd), (rn), shift, 63) +#define arm_lsrw(p, rd, rn, shift) arm_ubfmw ((p), (rd), (rn), shift, 31) +#define arm_rorx(p, rd, rs, shift) arm_extrx ((p), (rd), (rs), (rs), (shift)) +#define arm_rorw(p, rd, rs, shift) arm_extrw ((p), (rd), (rs), (rs), (shift)) + +/* Arithmetic (shifted register) */ +#define arm_format_alu_shift(p, sf, op, S, rd, rn, rm, shift, imm6) arm_emit ((p), ((sf) << 31) | ((op) << 30) | ((S) << 29) | (0xb << 24) | ((shift) << 22) | (0x0 << 21) | ((rm) << 16) | ((imm6) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_addx_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x1, 0x0, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_addw_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x0, 0x0, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_addsx_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x1, 0x0, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_addsw_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x0, 0x0, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_subx_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x1, 0x1, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_subw_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x0, 0x1, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_subsx_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x1, 0x1, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_subsw_shift(p, rd, rn, rm, shift_type, amount) arm_format_alu_shift ((p), 0x0, 0x1, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_cmnx_shift(p, rn, rm, shift_type, amount) arm_addsx_shift ((p), ARMREG_RZR, (rn), (rm), (shift_type), (amount)) +#define arm_cmnw_shift(p, rn, rm, shift_type, amount) arm_addsw_shift ((p), ARMREG_RZR, (rn), (rm), (shift_type), (amount)) +#define arm_cmpx_shift(p, rn, rm, shift_type, amount) arm_subsx_shift ((p), ARMREG_RZR, (rn), (rm), (shift_type), (amount)) +#define arm_cmpw_shift(p, rn, rm, shift_type, amount) arm_subsw_shift ((p), ARMREG_RZR, (rn), (rm), (shift_type), (amount)) +#define arm_negx_shift(p, rd, rm, shift_type, amount) arm_subx_shift ((p), (rd), ARMREG_RZR, (rm), (shift_type), (amount)) +#define arm_negw_shift(p, rd, rm, shift_type, amount) arm_subw_shift ((p), (rd), ARMREG_RZR, (rm), (shift_type), (amount)) +#define arm_negsx_shift(p, rd, rm, shift_type, amount) arm_subsx_shift ((p), (rd), ARMREG_RZR, (rm), (shift_type), (amount)) +#define arm_negsw_shift(p, rd, rm, shift_type, amount) arm_subsw_shift ((p), (rd), ARMREG_RZR, (rm), (shift_type), (amount)) + +#define arm_addx(p, rd, rn, rm) arm_addx_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_addw(p, rd, rn, rm) arm_addw_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_subx(p, rd, rn, rm) arm_subx_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_subw(p, rd, rn, rm) arm_subw_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_addsx(p, rd, rn, rm) arm_addsx_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_addsw(p, rd, rn, rm) arm_addsw_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_subsx(p, rd, rn, rm) arm_subsx_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_subsw(p, rd, rn, rm) arm_subsw_shift ((p), (rd), (rn), (rm), 0, 0) +#define arm_cmpx(p, rd, rn) arm_cmpx_shift ((p), (rd), (rn), 0, 0) +#define arm_cmpw(p, rd, rn) arm_cmpw_shift ((p), (rd), (rn), 0, 0) +#define arm_negx(p, rd, rn) arm_negx_shift ((p), (rd), (rn), 0, 0) +#define arm_negw(p, rd, rn) arm_negw_shift ((p), (rd), (rn), 0, 0) + +/* Arithmetic with carry */ +#define arm_format_adc(p, sf, op, S, rd, rn, rm) arm_emit ((p), ((sf) << 31) | ((op) << 30) | ((S) << 29) | (0xd0 << 21) | ((rm) << 16) | (0x0 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_adcx(p, rd, rn, rm) arm_format_adc ((p), 0x1, 0x0, 0x0, (rd), (rn), (rm)) +#define arm_adcw(p, rd, rn, rm) arm_format_adc ((p), 0x0, 0x0, 0x0, (rd), (rn), (rm)) +#define arm_adcsx(p, rd, rn, rm) arm_format_adc ((p), 0x1, 0x0, 0x1, (rd), (rn), (rm)) +#define arm_adcsw(p, rd, rn, rm) arm_format_adc ((p), 0x0, 0x0, 0x1, (rd), (rn), (rm)) +#define arm_sbcx(p, rd, rn, rm) arm_format_adc ((p), 0x1, 0x1, 0x0, (rd), (rn), (rm)) +#define arm_sbcw(p, rd, rn, rm) arm_format_adc ((p), 0x0, 0x1, 0x0, (rd), (rn), (rm)) +#define arm_sbcsx(p, rd, rn, rm) arm_format_adc ((p), 0x1, 0x1, 0x1, (rd), (rn), (rm)) +#define arm_sbcsw(p, rd, rn, rm) arm_format_adc ((p), 0x0, 0x1, 0x1, (rd), (rn), (rm)) +#define arm_ngcx(p, rd, rm) arm_sbcx ((p), (rd), ARMREG_RZR, (rm)) +#define arm_ngcw(p, rd, rm) arm_sbcw ((p), (rd), ARMREG_RZR, (rm)) +#define arm_ngcsx(p, rd, rm) arm_sbcsx ((p), (rd), ARMREG_RZR, (rm)) +#define arm_ngcsw(p, rd, rm) arm_sbcsw ((p), (rd), ARMREG_RZR, (rm)) + +/* Logical (shifted register) */ +#define arm_format_logical_shift(p, sf, op, N, rd, rn, rm, shift, imm6) arm_emit ((p), ((sf) << 31) | ((op) << 29) | (0xa << 24) | ((shift) << 22) | ((N) << 21) | ((rm) << 16) | ((imm6) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_andx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x0, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_andw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x0, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_andsx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x3, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_andsw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x3, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_bicx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x0, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_bicw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x0, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_bicsx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x3, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_bicsw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x3, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_eonx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x2, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_eonw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x2, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_eorx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x2, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_eorw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x2, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_orrx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x1, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_orrw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x1, 0x0, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_ornx_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x1, 0x1, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_ornw_shift(p, rd, rn, rm, shift_type, amount) arm_format_logical_shift ((p), 0x0, 0x1, 0x1, (rd), (rn), (rm), (shift_type), (amount)) +#define arm_mvnx_shift(p, rd, rm, shift_type, amount) arm_ornx_shift ((p), (rd), ARMREG_RZR, (rm), (shift_type), (amount)) +#define arm_mvnw_shift(p, rd, rm, shift_type, amount) arm_ornw_shift ((p), (rd), ARMREG_RZR, (rm), (shift_type), (amount)) +#define arm_tstx_shift(p, rn, rm, shift_type, amount) arm_andsx_shift ((p), ARMREG_RZR, (rn), (rm), (shift_type), (amount)) +#define arm_tstw_shift(p, rn, rm, shift_type, amount) arm_andsw_shift ((p), ARMREG_RZR, (rn), (rm), (shift_type), (amount)) +/* Aliases */ +#define arm_andx(p, rd, rn, rm) arm_andx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_andw(p, rd, rn, rm) arm_andw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_andsx(p, rd, rn, rm) arm_andsx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_andsw(p, rd, rn, rm) arm_andsw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_bixx(p, rd, rn, rm) arm_bixx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_bixw(p, rd, rn, rm) arm_bixw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_bixsx(p, rd, rn, rm) arm_bixsx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_bixsw(p, rd, rn, rm) arm_bixsw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_eonx(p, rd, rn, rm) arm_eonx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_eonw(p, rd, rn, rm) arm_eonw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_eorx(p, rd, rn, rm) arm_eorx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_eorw(p, rd, rn, rm) arm_eorw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_orrx(p, rd, rn, rm) arm_orrx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_orrw(p, rd, rn, rm) arm_orrw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_ornx(p, rd, rn, rm) arm_ornx_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_ornw(p, rd, rn, rm) arm_ornw_shift(p, rd, rn, rm, ARMSHIFT_LSL, 0) +#define arm_mvnx(p, rd, rm) arm_mvnx_shift(p, rd, rm, ARMSHIFT_LSL, 0) +#define arm_mvnw(p, rd, rm) arm_mvnw_shift(p, rd, rm, ARMSHIFT_LSL, 0) +#define arm_tstx(p, rn, rm) arm_tstx_shift(p, rn, rm, ARMSHIFT_LSL, 0) +#define arm_tstw(p, rn, rm) arm_tstw_shift(p, rn, rm, ARMSHIFT_LSL, 0) + +/* Move (register) */ +#define arm_movx(p, rn, rm) arm_orrx_shift ((p), (rn), ARMREG_RZR, (rm), ARMSHIFT_LSL, 0) +#define arm_movw(p, rn, rm) arm_orrw_shift ((p), (rn), ARMREG_RZR, (rm), ARMSHIFT_LSL, 0) + +/* Not an official alias */ +#define arm_movspx(p, rn, rm) arm_addx_imm ((p), (rn), (rm), 0) + +/* Shift (register) */ +#define arm_format_shift_reg(p, sf, op2, rd, rn, rm) arm_emit ((p), ((sf) << 31) | (0xd6 << 21) | ((rm) << 16) | (0x2 << 12) | ((op2) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_asrvx(p, rd, rn, rm) arm_format_shift_reg ((p), 0x1, 0x2, (rd), (rn), (rm)) +#define arm_asrvw(p, rd, rn, rm) arm_format_shift_reg ((p), 0x0, 0x2, (rd), (rn), (rm)) +#define arm_lslvx(p, rd, rn, rm) arm_format_shift_reg ((p), 0x1, 0x0, (rd), (rn), (rm)) +#define arm_lslvw(p, rd, rn, rm) arm_format_shift_reg ((p), 0x0, 0x0, (rd), (rn), (rm)) +#define arm_lsrvx(p, rd, rn, rm) arm_format_shift_reg ((p), 0x1, 0x1, (rd), (rn), (rm)) +#define arm_lsrvw(p, rd, rn, rm) arm_format_shift_reg ((p), 0x0, 0x1, (rd), (rn), (rm)) +#define arm_rorvx(p, rd, rn, rm) arm_format_shift_reg ((p), 0x1, 0x3, (rd), (rn), (rm)) +#define arm_rorvw(p, rd, rn, rm) arm_format_shift_reg ((p), 0x0, 0x3, (rd), (rn), (rm)) + +/* Multiply */ +#define arm_format_mul(p, sf, o0, rd, rn, rm, ra) arm_emit ((p), ((sf) << 31) | (0x0 << 29) | (0x1b << 24) | (0x0 << 21) | ((rm) << 16) | ((o0) << 15) | ((ra) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_maddx(p, rd, rn, rm, ra) arm_format_mul((p), 0x1, 0x0, (rd), (rn), (rm), (ra)) +#define arm_maddw(p, rd, rn, rm, ra) arm_format_mul((p), 0x0, 0x0, (rd), (rn), (rm), (ra)) +#define arm_msubx(p, rd, rn, rm, ra) arm_format_mul((p), 0x1, 0x1, (rd), (rn), (rm), (ra)) +#define arm_msubw(p, rd, rn, rm, ra) arm_format_mul((p), 0x0, 0x1, (rd), (rn), (rm), (ra)) +#define arm_mnegx(p, rd, rn, rm) arm_msubx ((p), (rd), (rn), (rm), ARMREG_RZR) +#define arm_mnegw(p, rd, rn, rm) arm_msubw ((p), (rd), (rn), (rm), ARMREG_RZR) +#define arm_mulx(p, rd, rn, rm) arm_maddx ((p), (rd), (rn), (rm), ARMREG_RZR) +#define arm_mulw(p, rd, rn, rm) arm_maddw ((p), (rd), (rn), (rm), ARMREG_RZR) + +/* FIXME: Missing multiple opcodes */ + +/* Division */ +#define arm_format_div(p, sf, o1, rd, rn, rm) arm_emit ((p), ((sf) << 31) | (0xd6 << 21) | ((rm) << 16) | (0x1 << 11) | ((o1) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_sdivx(p, rd, rn, rm) arm_format_div ((p), 0x1, 0x1, (rd), (rn), (rm)) +#define arm_sdivw(p, rd, rn, rm) arm_format_div ((p), 0x0, 0x1, (rd), (rn), (rm)) +#define arm_udivx(p, rd, rn, rm) arm_format_div ((p), 0x1, 0x0, (rd), (rn), (rm)) +#define arm_udivw(p, rd, rn, rm) arm_format_div ((p), 0x0, 0x0, (rd), (rn), (rm)) + +/* Conditional select */ +#define arm_format_csel(p, sf, op, op2, cond, rd, rn, rm) arm_emit ((p), ((sf) << 31) | ((op) << 30) | (0xd4 << 21) | ((rm) << 16) | ((cond) << 12) | ((op2) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_cselx(p, cond, rd, rn, rm) arm_format_csel ((p), 0x1, 0x0, 0x0, (cond), (rd), (rn), (rm)) +#define arm_cselw(p, cond, rd, rn, rm) arm_format_csel ((p), 0x0, 0x0, 0x0, (cond), (rd), (rn), (rm)) +#define arm_csincx(p, cond, rd, rn, rm) arm_format_csel ((p), 0x1, 0x0, 0x1, (cond), (rd), (rn), (rm)) +#define arm_csincw(p, cond, rd, rn, rm) arm_format_csel ((p), 0x0, 0x0, 0x1, (cond), (rd), (rn), (rm)) +#define arm_csinvx(p, cond, rd, rn, rm) arm_format_csel ((p), 0x1, 0x1, 0x0, (cond), (rd), (rn), (rm)) +#define arm_csinvw(p, cond, rd, rn, rm) arm_format_csel ((p), 0x0, 0x1, 0x0, (cond), (rd), (rn), (rm)) +#define arm_csnegx(p, cond, rd, rn, rm) arm_format_csel ((p), 0x1, 0x1, 0x1, (cond), (rd), (rn), (rm)) +#define arm_csnegw(p, cond, rd, rn, rm) arm_format_csel ((p), 0x0, 0x1, 0x1, (cond), (rd), (rn), (rm)) + +#define arm_cset(p, cond, rd) arm_csincx ((p), ((cond) ^ 0x1), (rd), ARMREG_RZR, ARMREG_RZR) + +/* C5.6.68 (HINT) */ +#define arm_hint(p, imm) arm_emit ((p), (0xd5032 << 12) | ((imm) << 5) | (0x1f << 0)) +#define arm_nop(p) arm_hint ((p), 0x0) + +/* C5.6.29 BRK */ +#define arm_brk(p, imm) arm_emit ((p), (0xd4 << 24) | (0x1 << 21) | ((imm) << 5)) + +/* C6.3.114 FMOV (General) */ +#define arm_format_fmov_gr(p, sf, type, rmode, opcode, rn, rd) arm_emit ((p), ((sf) << 31) | (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rmode) << 19) | ((opcode) << 16) | ((rn) << 5) | ((rd) << 0)) + +/* Move gr->vfp */ +#define arm_fmov_rx_to_double(p, dd, xn) arm_format_fmov_gr ((p), 0x1, 0x1, 0x0, 0x7, (xn), (dd)) + +/* Move vfp->gr */ +#define arm_fmov_double_to_rx(p, xd, dn) arm_format_fmov_gr ((p), 0x1, 0x1, 0x0, 0x6, (dn), (xd)) + +/* C6.3.113 FMOV (register) */ +#define arm_format_fmov(p, type, rn, rd) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | (0x10 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fmovd(p, dd, dn) arm_format_fmov ((p), 0x1, (dn), (dd)) +#define arm_fmovs(p, dd, dn) arm_format_fmov ((p), 0x0, (dn), (dd)) + +/* C6.3.54 FCMP */ +#define arm_format_fcmp(p, type, opc, rn, rm) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rm) << 16) | (0x8 << 10) | ((rn) << 5) | ((opc) << 3)) + +#define arm_fcmpd(p, dn, dm) arm_format_fcmp (p, 0x1, 0x0, (dn), (dm)) +#define arm_fcmps(p, dn, dm) arm_format_fcmp (p, 0x0, 0x0, (dn), (dm)) + +/* Float precision */ +#define arm_format_fcvt(p, type, opc, rn, rd) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | (0x1 << 17) | ((opc) << 15) | (0x10 << 10) | ((rn) << 5) | ((rd) << 0)) + +/* C6.3.57 FCVT */ +/* single->double */ +#define arm_fcvt_sd(p, dd, sn) arm_format_fcvt ((p), 0x0, 0x1, (sn), (dd)) +/* double->single */ +#define arm_fcvt_ds(p, sd, dn) arm_format_fcvt ((p), 0x1, 0x0, (dn), (sd)) + +/* Float conversion to integer conversion */ +#define arm_format_fcvtz(p, sf, type, rmode, opcode, rn, rd) arm_emit ((p), ((sf) << 31) | (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rmode) << 19) | ((opcode) << 16) | ((rn) << 5) | ((rd) << 0)) + +/* C6.3.80 FCVTZS (scalar, integer) */ +#define arm_fcvtzs_dw(p, rd, rn) arm_format_fcvtz ((p), 0x0, 0x1, 0x3, 0x0, (rn), (rd)) +#define arm_fcvtzs_dx(p, rd, rn) arm_format_fcvtz ((p), 0x1, 0x1, 0x3, 0x0, (rn), (rd)) +#define arm_fcvtzs_sw(p, rd, rn) arm_format_fcvtz ((p), 0x0, 0x0, 0x3, 0x0, (rn), (rd)) +#define arm_fcvtzs_sx(p, rd, rn) arm_format_fcvtz ((p), 0x1, 0x0, 0x3, 0x0, (rn), (rd)) + +/* C6.3.84 FCVTZU (scalar, integer) */ +#define arm_fcvtzu_dw(p, rd, rn) arm_format_fcvtz ((p), 0x0, 0x1, 0x3, 0x1, (rn), (rd)) +#define arm_fcvtzu_dx(p, rd, rn) arm_format_fcvtz ((p), 0x1, 0x1, 0x3, 0x1, (rn), (rd)) +#define arm_fcvtzu_sw(p, rd, rn) arm_format_fcvtz ((p), 0x0, 0x0, 0x3, 0x1, (rn), (rd)) +#define arm_fcvtzu_sx(p, rd, rn) arm_format_fcvtz ((p), 0x1, 0x0, 0x3, 0x1, (rn), (rd)) + +/* C6.3.208 SCVTF (vector, integer) */ +#define arm_format_scvtf_vector(p, sz, rn, rd) arm_emit ((p), (0x1 << 30) | (0x0 << 29) | (0x1e << 24) | ((sz) << 22) | (0x10 << 17) | (0x1d << 12) | (0x2 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_scvtf_d(p, dd, dn) arm_format_scvtf_vector ((p), 0x1, (dn), (dd)) +#define arm_scvtf_s(p, sd, sn) arm_format_scvtf_vector ((p), 0x0, (sn), (sd)) + +/* C6.3.210 SCVTF (scalar, integer) */ +#define arm_format_scvtf_scalar(p, sf, type, rn, rd) arm_emit ((p), ((sf) << 31) | (0x1e << 24) | ((type) << 22) | (0x1 << 21) | (0x2 << 16) | (0x0 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_scvtf_rx_to_d(p, dd, rn) arm_format_scvtf_scalar ((p), 0x1, 0x1, rn, dd) +#define arm_scvtf_rw_to_d(p, dd, rn) arm_format_scvtf_scalar ((p), 0x0, 0x1, rn, dd) +#define arm_scvtf_rx_to_s(p, dd, rn) arm_format_scvtf_scalar ((p), 0x1, 0x0, rn, dd) +#define arm_scvtf_rw_to_s(p, dd, rn) arm_format_scvtf_scalar ((p), 0x0, 0x0, rn, dd) + +/* C6.3.306 UCVTF (vector, integer) */ +#define arm_format_ucvtf_vector(p, sz, rn, rd) arm_emit ((p), (0x1 << 30) | (0x1 << 29) | (0x1e << 24) | ((sz) << 22) | (0x10 << 17) | (0x1d << 12) | (0x2 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_ucvtf_d(p, dd, dn) arm_format_ucvtf_vector ((p), 0x1, (dn), (dd)) +#define arm_ucvtf_s(p, sd, sn) arm_format_ucvtf_vector ((p), 0x0, (sn), (sd)) + +/* C6.3.308 UCVTF (scalar, integer) */ +#define arm_format_ucvtf_scalar(p, sf, type, rn, rd) arm_emit ((p), ((sf) << 31) | (0x1e << 24) | ((type) << 22) | (0x1 << 21) | (0x3 << 16) | (0x0 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_ucvtf_rx_to_d(p, dd, rn) arm_format_ucvtf_scalar ((p), 0x1, 0x1, rn, dd) +#define arm_ucvtf_rw_to_d(p, dd, rn) arm_format_ucvtf_scalar ((p), 0x0, 0x1, rn, dd) + +/* C6.3.41 FADD (scalar) */ +#define arm_format_fadd_scalar(p, type, rd, rn, rm) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rm) << 16) | (0x1 << 13) | (0x2 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fadd_d(p, rd, rn, rm) arm_format_fadd_scalar ((p), 0x1, (rd), (rn), (rm)) +#define arm_fadd_s(p, rd, rn, rm) arm_format_fadd_scalar ((p), 0x0, (rd), (rn), (rm)) + +/* C6.3.149 FSUB (scalar) */ +#define arm_format_fsub_scalar(p, type, rd, rn, rm) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rm) << 16) | (0x1 << 13) | (0x1 << 12) | (0x2 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fsub_d(p, rd, rn, rm) arm_format_fsub_scalar ((p), 0x1, (rd), (rn), (rm)) +#define arm_fsub_s(p, rd, rn, rm) arm_format_fsub_scalar ((p), 0x0, (rd), (rn), (rm)) + +/* C6.3.119 FMUL (scalar) */ +#define arm_format_fmul_scalar(p, type, rd, rn, rm) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rm) << 16) | (0x2 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fmul_d(p, rd, rn, rm) arm_format_fmul_scalar ((p), 0x1, (rd), (rn), (rm)) +#define arm_fmul_s(p, rd, rn, rm) arm_format_fmul_scalar ((p), 0x0, (rd), (rn), (rm)) + +/* C6.3.86 FDIV (scalar) */ +#define arm_format_fdiv_scalar(p, type, rd, rn, rm) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((rm) << 16) | (0x1 << 12) | (0x2 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fdiv_d(p, rd, rn, rm) arm_format_fdiv_scalar ((p), 0x1, (rd), (rn), (rm)) +#define arm_fdiv_s(p, rd, rn, rm) arm_format_fdiv_scalar ((p), 0x0, (rd), (rn), (rm)) + +/* C6.3.116 FMSUB */ +#define arm_format_fmsub(p, type, rd, rn, rm, ra) arm_emit ((p), (0x1f << 24) | ((type) << 22) | (0x0 << 21) | ((rm) << 16) | (0x1 << 15) | ((ra) << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fmsub_d(p, rd, rn, rm, ra) arm_format_fmsub ((p), 0x1, (rd), (rn), (rm), (ra)) + +/* C6.3.123 FNEG */ +#define arm_format_fneg(p, type, rd, rn) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | (0x2 << 15) | (0x10 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fneg_d(p, rd, rn) arm_format_fneg ((p), 0x1, (rd), (rn)) +#define arm_fneg_s(p, rd, rn) arm_format_fneg ((p), 0x0, (rd), (rn)) + +/* C6.3.37 FABS (scalar) */ +#define arm_format_fabs(p, type, opc, rd, rn) arm_emit ((p), (0x1e << 24) | ((type) << 22) | (0x1 << 21) | ((opc) << 15) | (0x10 << 10) | ((rn) << 5) | ((rd) << 0)) + +#define arm_fabs_d(p, rd, rn) arm_format_fabs ((p), 0x1, 0x1, (rd), (rn)) + +/* C5.6.60 DMB */ +#define arm_format_dmb(p, opc, CRm) arm_emit ((p), (0x354 << 22) | (0x3 << 16) | (0x3 << 12) | ((CRm) << 8) | (0x1 << 7) | ((opc) << 5) | (0x1f << 0)) + +#define ARM_DMB_LD 0x1 +#define ARM_DMB_ST 0x2 +#define ARM_DMB_ALL 0x3 +#define ARM_DMB_SY 0xc + +#define arm_dmb(p, imm) arm_format_dmb ((p), 0x1, (imm)) + +/* C5.6.129 MRS */ + +#define ARM_MRS_REG_TPIDR_EL0 0x5e82 + +#define arm_format_mrs(p, sysreg, rt) arm_emit ((p), (0x354 << 22) | (0x1 << 21) | (0x1 << 20) | ((sysreg) << 5) | ((rt) << 0)) + +#define arm_mrs(p, rt, sysreg) arm_format_mrs ((p), (sysreg), (rt)) + +#endif /* __arm_CODEGEN_H__ */ diff --git a/mono/arch/mips/mips-codegen.h b/mono/arch/mips/mips-codegen.h index 1dbd1c6e279..c579c88a9b3 100644 --- a/mono/arch/mips/mips-codegen.h +++ b/mono/arch/mips/mips-codegen.h @@ -4,6 +4,7 @@ * Copyright (c) 2004 Novell, Inc * Author: Paolo Molaro (lupus@ximian.com) * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* registers */ diff --git a/mono/arch/ppc/ppc-codegen.h b/mono/arch/ppc/ppc-codegen.h index d4d25a254f9..869365b4bcc 100644 --- a/mono/arch/ppc/ppc-codegen.h +++ b/mono/arch/ppc/ppc-codegen.h @@ -8,6 +8,7 @@ Copyright (C) 2007-2008 Andreas Faerber for testing do the following: ./test | as -o test.o + Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_PPC_CODEGEN_H__ diff --git a/mono/arch/s390x/s390x-codegen.h b/mono/arch/s390x/s390x-codegen.h index 4c3cd243520..97db6ce6eb9 100644 --- a/mono/arch/s390x/s390x-codegen.h +++ b/mono/arch/s390x/s390x-codegen.h @@ -1,5 +1,6 @@ /* Copyright (C) 2001 Radek Doulik + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef S390X_H diff --git a/mono/arch/x86/x86-codegen.h b/mono/arch/x86/x86-codegen.h index ff3fe325a79..6c9d63f37e9 100644 --- a/mono/arch/x86/x86-codegen.h +++ b/mono/arch/x86/x86-codegen.h @@ -10,6 +10,7 @@ * * Copyright (C) 2000 Intel Corporation. All rights reserved. * Copyright (C) 2001, 2002 Ximian, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef X86_H diff --git a/mono/dis/declsec.c b/mono/dis/declsec.c index 3d6cd252366..eb0f168850a 100755 --- a/mono/dis/declsec.c +++ b/mono/dis/declsec.c @@ -6,6 +6,7 @@ * Sebastien Pouliot * * Copyright (C) 2005 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/dis/declsec.h b/mono/dis/declsec.h index fd9a5cb3615..a0e621f7cb0 100644 --- a/mono/dis/declsec.h +++ b/mono/dis/declsec.h @@ -6,6 +6,7 @@ * Sebastien Pouliot * * Copyright (C) 2005 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONODIS_DECLSEC_H__ diff --git a/mono/dis/get.c b/mono/dis/get.c index 24df084d6e3..f3724e4384d 100755 --- a/mono/dis/get.c +++ b/mono/dis/get.c @@ -6,6 +6,7 @@ * * (C) 2001 Ximian, Inc. * Copyright 2012 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/dis/main.c b/mono/dis/main.c index d8f6f8558fa..d1b85c5509a 100644 --- a/mono/dis/main.c +++ b/mono/dis/main.c @@ -11,6 +11,7 @@ * Structs are not being labeled as `valuetype' classes * * How are fields with literals mapped to constants? + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/io-layer/handles.c b/mono/io-layer/handles.c index 3cb0a73d578..f31d6cbfb4e 100644 --- a/mono/io-layer/handles.c +++ b/mono/io-layer/handles.c @@ -6,6 +6,7 @@ * * (C) 2002-2011 Novell, Inc. * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/io-layer/io-portability.c b/mono/io-layer/io-portability.c index 8838c304e9c..282cbe93a29 100644 --- a/mono/io-layer/io-portability.c +++ b/mono/io-layer/io-portability.c @@ -6,6 +6,7 @@ * Dick Porter (dick@ximian.com) * * Copyright (c) 2006 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/io-layer/io-portability.h b/mono/io-layer/io-portability.h index 8beb367f2e6..d7e9dba666d 100644 --- a/mono/io-layer/io-portability.h +++ b/mono/io-layer/io-portability.h @@ -6,6 +6,7 @@ * Dick Porter (dick@ximian.com) * * Copyright (C) 2006 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _WAPI_IO_PORTABILITY_H_ diff --git a/mono/io-layer/io-private.h b/mono/io-layer/io-private.h index fad582754fd..9af4b1f0a11 100644 --- a/mono/io-layer/io-private.h +++ b/mono/io-layer/io-private.h @@ -6,6 +6,7 @@ * * (C) 2002 Ximian, Inc. * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _WAPI_IO_PRIVATE_H_ diff --git a/mono/io-layer/io-trace.h b/mono/io-layer/io-trace.h index 51f60f45334..f67ff65f842 100644 --- a/mono/io-layer/io-trace.h +++ b/mono/io-layer/io-trace.h @@ -5,6 +5,7 @@ * Marek Habersack * * Copyright 2016 Xamarin, Inc (http://xamarin.com/) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __IO_TRACE_H diff --git a/mono/io-layer/io.c b/mono/io-layer/io.c index b751134d704..11b5f8f2fbb 100644 --- a/mono/io-layer/io.c +++ b/mono/io-layer/io.c @@ -7,6 +7,7 @@ * (C) 2002 Ximian, Inc. * Copyright (c) 2002-2006 Novell, Inc. * Copyright 2011 Xamarin Inc (http://www.xamarin.com). + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/io-layer/locking.c b/mono/io-layer/locking.c index 305c0ab4852..c014a2d3dc4 100644 --- a/mono/io-layer/locking.c +++ b/mono/io-layer/locking.c @@ -6,6 +6,7 @@ * * (C) 2002 Ximian, Inc. * Copyright (c) 2002-2009 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/io-layer/posix.c b/mono/io-layer/posix.c index 3cd41f67fe3..2856d4fcd61 100644 --- a/mono/io-layer/posix.c +++ b/mono/io-layer/posix.c @@ -7,6 +7,7 @@ * (C) 2002 Ximian, Inc. * Copyright (c) 2002-2009 Novell, Inc. * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c index d54f84bd324..7e46c31ba3e 100644 --- a/mono/io-layer/processes.c +++ b/mono/io-layer/processes.c @@ -6,6 +6,7 @@ * * (C) 2002-2011 Novell, Inc. * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/io-layer/wthreads.c b/mono/io-layer/wthreads.c index bb65b5f799c..304fd35adf8 100644 --- a/mono/io-layer/wthreads.c +++ b/mono/io-layer/wthreads.c @@ -7,6 +7,7 @@ * (C) 2002-2006 Ximian, Inc. * Copyright 2003-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/abi-details.h b/mono/metadata/abi-details.h index cb0fb34bf95..3f61191b314 100644 --- a/mono/metadata/abi-details.h +++ b/mono/metadata/abi-details.h @@ -1,5 +1,6 @@ /* * Copyright 2014 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_ABI_DETAILS_H__ #define __MONO_METADATA_ABI_DETAILS_H__ diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index e7a0db8eb2a..93169cda59d 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -9,6 +9,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2012 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #undef ASSEMBLY_LOAD_DEBUG #include diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c index 275bcbb2343..9bc8b09e270 100644 --- a/mono/metadata/assembly.c +++ b/mono/metadata/assembly.c @@ -7,6 +7,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/metadata/attach.c b/mono/metadata/attach.c index 45c3da53594..9e54462633c 100644 --- a/mono/metadata/attach.c +++ b/mono/metadata/attach.c @@ -5,6 +5,7 @@ * Zoltan Varga (vargaz@gmail.com) * * Copyright 2007-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c index 4834da608e1..43844ad9830 100644 --- a/mono/metadata/boehm-gc.c +++ b/mono/metadata/boehm-gc.c @@ -4,6 +4,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2011 Novell, Inc (http://www.novell.com) * Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index 14e50f56b68..b86e7eda40e 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -1,5 +1,6 @@ /* * Copyright 2012 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_CLASS_INTERNALS_H__ #define __MONO_METADATA_CLASS_INTERNALS_H__ diff --git a/mono/metadata/class.c b/mono/metadata/class.c index 49225c652e6..f7b36279f4a 100644 --- a/mono/metadata/class.c +++ b/mono/metadata/class.c @@ -7,6 +7,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #ifdef HAVE_ALLOCA_H diff --git a/mono/metadata/console-io.h b/mono/metadata/console-io.h index fdca4871eeb..54ee8820463 100644 --- a/mono/metadata/console-io.h +++ b/mono/metadata/console-io.h @@ -5,6 +5,7 @@ * Gonzalo Paniagua Javier (gonzalo@ximian.com) * * Copyright (c) 2005 Novell, Inc. (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_METADATA_CONSOLEIO_H diff --git a/mono/metadata/console-null.c b/mono/metadata/console-null.c index 7c778bfacd1..b8367e888f7 100644 --- a/mono/metadata/console-null.c +++ b/mono/metadata/console-null.c @@ -5,6 +5,7 @@ * Gonzalo Paniagua Javier (gonzalo@ximian.com) * * Copyright (C) 2005-2009 Novell, Inc. (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/console-unix.c b/mono/metadata/console-unix.c index 43c97c7cfef..5c46a85a941 100644 --- a/mono/metadata/console-unix.c +++ b/mono/metadata/console-unix.c @@ -5,6 +5,7 @@ * Gonzalo Paniagua Javier (gonzalo@ximian.com) * * Copyright (C) 2005-2009 Novell, Inc. (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #if defined(__native_client__) #include "console-null.c" diff --git a/mono/metadata/console-win32.c b/mono/metadata/console-win32.c index ff703808c3d..c7c8c49017b 100644 --- a/mono/metadata/console-win32.c +++ b/mono/metadata/console-win32.c @@ -5,6 +5,7 @@ * Gonzalo Paniagua Javier (gonzalo@ximian.com) * * Copyright (C) 2005-2009 Novell, Inc. (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/coree.c b/mono/metadata/coree.c index c2e47b9ca7b..326251cc140 100644 --- a/mono/metadata/coree.c +++ b/mono/metadata/coree.c @@ -5,6 +5,7 @@ * Kornel Pal * * Copyright (C) 2008 Kornel Pal + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/coree.h b/mono/metadata/coree.h index a9c6a7cb76a..ade821af5e3 100644 --- a/mono/metadata/coree.h +++ b/mono/metadata/coree.h @@ -5,6 +5,7 @@ * Kornel Pal * * Copyright (C) 2008 Kornel Pal + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_COREE_H__ diff --git a/mono/metadata/debug-helpers.c b/mono/metadata/debug-helpers.c index 2553361c14d..baf79f6be97 100644 --- a/mono/metadata/debug-helpers.c +++ b/mono/metadata/debug-helpers.c @@ -5,6 +5,7 @@ * Mono Project (http://www.mono-project.com) * * Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/debug-mono-ppdb.c b/mono/metadata/debug-mono-ppdb.c index fcbfd9d817f..e6d9cc95e2f 100644 --- a/mono/metadata/debug-mono-ppdb.c +++ b/mono/metadata/debug-mono-ppdb.c @@ -7,6 +7,7 @@ * Mono Project (http://www.mono-project.com) * * Copyright 2015 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/debug-mono-ppdb.h b/mono/metadata/debug-mono-ppdb.h index e23b279cd94..decf5e8d04b 100644 --- a/mono/metadata/debug-mono-ppdb.h +++ b/mono/metadata/debug-mono-ppdb.h @@ -7,6 +7,7 @@ * Mono Project (http://www.mono-project.com) * * Copyright 2015 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_DEBUG_MONO_PPDB_H__ diff --git a/mono/metadata/debug-mono-symfile.c b/mono/metadata/debug-mono-symfile.c index 8df4c0f9026..f418b2078ce 100644 --- a/mono/metadata/debug-mono-symfile.c +++ b/mono/metadata/debug-mono-symfile.c @@ -6,6 +6,7 @@ * * Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com) * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/debug-mono-symfile.h b/mono/metadata/debug-mono-symfile.h index 684168994b4..3b3459f3258 100644 --- a/mono/metadata/debug-mono-symfile.h +++ b/mono/metadata/debug-mono-symfile.h @@ -2,6 +2,7 @@ * This header is only installed for use by the debugger: * the structures and the API declared here are not supported. * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_DEBUG_MONO_SYMFILE_H__ diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h index dfd65e48a21..5e3adb36a48 100644 --- a/mono/metadata/domain-internals.h +++ b/mono/metadata/domain-internals.h @@ -1,6 +1,7 @@ /* * Appdomain-related internal data structures and functions. * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_DOMAIN_INTERNALS_H__ #define __MONO_METADATA_DOMAIN_INTERNALS_H__ diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c index ab021003394..da3b6930aaf 100644 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/environment.c b/mono/metadata/environment.c index e0d1970f612..4726f9ba703 100644 --- a/mono/metadata/environment.c +++ b/mono/metadata/environment.c @@ -7,6 +7,7 @@ * * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index e2c45aca38b..332ac557d1e 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -9,6 +9,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/file-io.c b/mono/metadata/file-io.c index 71a956679d1..c0d0f1c11e3 100644 --- a/mono/metadata/file-io.c +++ b/mono/metadata/file-io.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/file-io.h b/mono/metadata/file-io.h index 2974bd49949..ab10f929173 100644 --- a/mono/metadata/file-io.h +++ b/mono/metadata/file-io.h @@ -7,6 +7,7 @@ * * (C) 2001 Ximian, Inc. * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_METADATA_FILEIO_H_ diff --git a/mono/metadata/file-mmap-posix.c b/mono/metadata/file-mmap-posix.c index aca3e7fb49c..efa5547f6e4 100644 --- a/mono/metadata/file-mmap-posix.c +++ b/mono/metadata/file-mmap-posix.c @@ -5,6 +5,7 @@ * Rodrigo Kumpera * * Copyright 2014 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/file-mmap-windows.c b/mono/metadata/file-mmap-windows.c index 56d598ee7f2..dba37472c34 100644 --- a/mono/metadata/file-mmap-windows.c +++ b/mono/metadata/file-mmap-windows.c @@ -5,6 +5,7 @@ * Rodrigo Kumpera * * Copyright 2014 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/file-mmap.h b/mono/metadata/file-mmap.h index 0e391ff1d40..cef862e3bea 100644 --- a/mono/metadata/file-mmap.h +++ b/mono/metadata/file-mmap.h @@ -5,6 +5,7 @@ * Rodrigo Kumpera * * Copyright 2014 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_METADATA_FILE_MMAP_H_ diff --git a/mono/metadata/filewatcher.c b/mono/metadata/filewatcher.c index def11d9856d..eb1827a0c60 100644 --- a/mono/metadata/filewatcher.c +++ b/mono/metadata/filewatcher.c @@ -5,6 +5,7 @@ * Gonzalo Paniagua Javier (gonzalo@ximian.com) * * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifdef HAVE_CONFIG_H diff --git a/mono/metadata/gc-internals.h b/mono/metadata/gc-internals.h index bc13b1ea269..52d950d8cca 100644 --- a/mono/metadata/gc-internals.h +++ b/mono/metadata/gc-internals.h @@ -5,6 +5,7 @@ * * (C) 2002 Ximian, Inc. * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_GC_INTERNAL_H__ diff --git a/mono/metadata/gc-stats.c b/mono/metadata/gc-stats.c index ff442e43f6a..ef232a93e5e 100644 --- a/mono/metadata/gc-stats.c +++ b/mono/metadata/gc-stats.c @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/sgen/gc-internal-agnostic.h" diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 3e56e77a821..172660d1b55 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -6,6 +6,7 @@ * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/handle.c b/mono/metadata/handle.c index c962bda7c7f..6c266259508 100644 --- a/mono/metadata/handle.c +++ b/mono/metadata/handle.c @@ -5,6 +5,7 @@ * - Ludovic Henry * * Copyright 2015 Xamarin, Inc. (www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/handle.h b/mono/metadata/handle.h index e5807a1796c..99a04282903 100644 --- a/mono/metadata/handle.h +++ b/mono/metadata/handle.h @@ -5,6 +5,7 @@ * - Ludovic Henry * * Copyright 2015 Xamarin, Inc. (www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_HANDLE_H__ diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index f1b296b8eac..cea8809e84f 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -11,6 +11,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com). + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/image-internals.h b/mono/metadata/image-internals.h index e5211176d8e..959575f6a0a 100644 --- a/mono/metadata/image-internals.h +++ b/mono/metadata/image-internals.h @@ -1,5 +1,6 @@ /* * Copyright 2015 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_IMAGE_INTERNALS_H__ #define __MONO_METADATA_IMAGE_INTERNALS_H__ diff --git a/mono/metadata/image.c b/mono/metadata/image.c index b16cd7cc2e8..7b1b4278315 100644 --- a/mono/metadata/image.c +++ b/mono/metadata/image.c @@ -9,6 +9,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/metadata/jit-info.c b/mono/metadata/jit-info.c index 2f4be6663ff..c8d5f588322 100644 --- a/mono/metadata/jit-info.c +++ b/mono/metadata/jit-info.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index 2195d22618f..56992b36127 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -17,6 +17,7 @@ * TODO: * This should keep track of the assembly versions that we are loading. * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/metadata/locales.c b/mono/metadata/locales.c index 18b52ae2b82..2adadc6ed6e 100644 --- a/mono/metadata/locales.c +++ b/mono/metadata/locales.c @@ -10,6 +10,7 @@ * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * (C) 2003 PT Cakram Datalingga Duaribu http://www.cdl2000.com * Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/marshal.c b/mono/metadata/marshal.c index 9b7eca1ffce..18f93d260e3 100644 --- a/mono/metadata/marshal.c +++ b/mono/metadata/marshal.c @@ -8,6 +8,7 @@ * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/mempool.c b/mono/metadata/mempool.c index abbdbdbace3..60d36ae2ad1 100644 --- a/mono/metadata/mempool.c +++ b/mono/metadata/mempool.c @@ -10,6 +10,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc. (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/metadata-cross-helpers.c b/mono/metadata/metadata-cross-helpers.c index 59536914010..90a4d332bd1 100644 --- a/mono/metadata/metadata-cross-helpers.c +++ b/mono/metadata/metadata-cross-helpers.c @@ -1,6 +1,137 @@ +#include + #include "config.h" +#include + +#include +#include +#include +#ifdef HAVE_SGEN_GC +#include +#endif + +static int +dump_arch (void) +{ +#if defined (TARGET_X86) + g_print ("#ifdef TARGET_X86\n"); +#elif defined (TARGET_AMD64) + g_print ("#ifdef TARGET_AMD64\n"); +#elif defined (TARGET_ARM) + g_print ("#ifdef TARGET_ARM\n"); +#elif defined (TARGET_ARM64) + g_print ("#ifdef TARGET_ARM64\n"); +#else + return 0; +#endif + return 1; +} + +static int +dump_os (void) +{ +#if defined (PLATFORM_WIN32) + g_print ("#ifdef TARGET_WIN32\n"); +#elif defined (PLATFORM_ANDROID) + g_print ("#ifdef TARGET_ANDROID\n"); +#elif defined (PLATFORM_MACOSX) + g_print ("#ifdef TARGET_OSX\n"); +#elif defined (PLATFORM_IOS) + g_print ("#ifdef TARGET_IOS\n"); +#else + return 0; +#endif + return 1; +} + +void +mono_dump_metadata_offsets (void); + +void +mono_dump_metadata_offsets (void) +{ +#ifdef USED_CROSS_COMPILER_OFFSETS + g_print ("not using native offsets\n"); +#else + g_print ("#ifndef USED_CROSS_COMPILER_OFFSETS\n"); + + if (!dump_arch ()) { + g_print ("#error failed to figure out the current arch\n"); + return; + } + + if (!dump_os ()) { + g_print ("#error failed to figure out the current OS\n"); + return; + } + +#ifdef HAVE_SGEN_GC + g_print ("#ifndef HAVE_BOEHM_GC\n"); +#elif HAVE_BOEHM_GC + g_print ("#ifndef HAVE_SGEN_GC\n"); +#else + g_print ("#error no gc conf not supported\n"); + return; +#endif + + g_print ("#define HAS_CROSS_COMPILER_OFFSETS\n"); + g_print ("#if defined (USE_CROSS_COMPILE_OFFSETS) || defined (MONO_CROSS_COMPILE)\n"); + g_print ("#if !defined (DISABLE_METADATA_OFFSETS)\n"); + g_print ("#define USED_CROSS_COMPILER_OFFSETS\n"); + +#define DISABLE_JIT_OFFSETS +#define DECL_OFFSET2(struct,field,offset) this_should_not_happen +#define DECL_ALIGN2(type,size) this_should_not_happen + +#define DECL_OFFSET(struct,field) g_print ("DECL_OFFSET2(%s,%s,%d)\n", #struct, #field, (int)MONO_STRUCT_OFFSET (struct, field)); +#define DECL_ALIGN(type) g_print ("DECL_ALIGN2(%s,%d)\n", #type, (int)MONO_ABI_ALIGNOF (type)); +#define DECL_SIZE(type) g_print ("DECL_SIZE2(%s,%d)\n", #type, (int)MONO_ABI_SIZEOF (type)); +#include + + g_print ("#endif //disable metadata check\n"); + g_print ("#endif //gc check\n"); +#endif +} + +void +mono_metadata_cross_helpers_run (void); + +void +mono_metadata_cross_helpers_run (void) +{ +#if defined (HAS_CROSS_COMPILER_OFFSETS) && !defined (MONO_CROSS_COMPILE) + gboolean is_broken = FALSE; + +#define DISABLE_JIT_OFFSETS +#define USE_CROSS_COMPILE_OFFSETS +#define DECL_OFFSET(struct,field) this_should_not_happen_for_cross_fields +#define DECL_OFFSET2(struct,field,offset) \ + if ((int)G_STRUCT_OFFSET (struct, field) != offset) { \ + g_print (#struct ":" #field " invalid struct offset %d (expected %d)\n", \ + offset, \ + (int)G_STRUCT_OFFSET (struct, field)); \ + is_broken = TRUE; \ + } +#define DECL_ALIGN(type) this_should_not_happen_for_cross_align +#define DECL_ALIGN2(name,size) \ + if (MONO_ALIGN_ ## name != size) { \ + g_print (#name ": invalid alignment %d (expected %d)\n", \ + size, \ + MONO_ALIGN_ ## name); \ + is_broken = TRUE; \ + } +#define DECL_SIZE(type) this_should_not_happen_for_cross_size +#define DECL_SIZE2(name,size) \ + if (MONO_SIZEOF_ ## name != size) { \ + g_print (#name ": invalid size %d (expected %d)\n", \ + size, \ + MONO_SIZEOF_ ## name); \ + is_broken = TRUE; \ + } + +#include -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/metadata/metadata-cross-helpers.c" + g_assert (!is_broken); #endif +} diff --git a/mono/metadata/metadata-verify.c b/mono/metadata/metadata-verify.c index 753e5269e92..287c68fbfb7 100644 --- a/mono/metadata/metadata-verify.c +++ b/mono/metadata/metadata-verify.c @@ -5,6 +5,7 @@ * Mono Project (http://www.mono-project.com) * * Copyright (C) 2005-2008 Novell, Inc. (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c index d4e404554a0..b778e3964c6 100644 --- a/mono/metadata/metadata.c +++ b/mono/metadata/metadata.c @@ -7,6 +7,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/method-builder.c b/mono/metadata/method-builder.c index 3b04c246494..98431f7d64a 100644 --- a/mono/metadata/method-builder.c +++ b/mono/metadata/method-builder.c @@ -6,6 +6,7 @@ * * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/monitor.c b/mono/metadata/monitor.c index b068745dff6..45c13be4e0f 100644 --- a/mono/metadata/monitor.c +++ b/mono/metadata/monitor.c @@ -6,6 +6,7 @@ * * Copyright 2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/mono-basic-block.c b/mono/metadata/mono-basic-block.c index 5f9aa0736f4..53f21530024 100644 --- a/mono/metadata/mono-basic-block.c +++ b/mono/metadata/mono-basic-block.c @@ -5,6 +5,7 @@ * Rodrigo Kumpera (rkumpera@novell.com) * * Copyright 2010 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/mono-config-dirs.c b/mono/metadata/mono-config-dirs.c index 01e2773a9b8..ece67d1286c 100644 --- a/mono/metadata/mono-config-dirs.c +++ b/mono/metadata/mono-config-dirs.c @@ -2,6 +2,7 @@ * mono-config-dirs.c: * * Copyright 2015 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/metadata/mono-config.c b/mono/metadata/mono-config.c index 2eba9e86d4b..80261f2b62e 100644 --- a/mono/metadata/mono-config.c +++ b/mono/metadata/mono-config.c @@ -7,6 +7,7 @@ * * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" #include diff --git a/mono/metadata/mono-debug.c b/mono/metadata/mono-debug.c index 09c55b3bcc8..b88b20e0381 100644 --- a/mono/metadata/mono-debug.c +++ b/mono/metadata/mono-debug.c @@ -7,6 +7,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/mono-endian.c b/mono/metadata/mono-endian.c index 23b6fe7b3ca..a4c48f1413d 100644 --- a/mono/metadata/mono-endian.c +++ b/mono/metadata/mono-endian.c @@ -6,6 +6,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include "mono-endian.h" diff --git a/mono/metadata/mono-hash.h b/mono/metadata/mono-hash.h index e07f8fadb83..60c3328a238 100644 --- a/mono/metadata/mono-hash.h +++ b/mono/metadata/mono-hash.h @@ -5,6 +5,7 @@ * Paolo Molaro (lupus@xamarin.com) * * Copyright 2013 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_G_HASH_H__ diff --git a/mono/metadata/mono-mlist.c b/mono/metadata/mono-mlist.c index 7e90b652dd5..657800afbe3 100644 --- a/mono/metadata/mono-mlist.c +++ b/mono/metadata/mono-mlist.c @@ -5,6 +5,7 @@ * Paolo Molaro (lupus@ximian.com) * * Copyright 2006-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/metadata/mono-mlist.h" diff --git a/mono/metadata/mono-perfcounters.c b/mono/metadata/mono-perfcounters.c index 267f87d4735..445df5c8334 100644 --- a/mono/metadata/mono-perfcounters.c +++ b/mono/metadata/mono-perfcounters.c @@ -7,6 +7,7 @@ * * Copyright 2008-2009 Novell, Inc (http://www.novell.com) * 2011 Xamarin, Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/mono-security.c b/mono/metadata/mono-security.c index b9293154ab1..d59d624782a 100644 --- a/mono/metadata/mono-security.c +++ b/mono/metadata/mono-security.c @@ -5,6 +5,7 @@ * Sebastien Pouliot * * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifdef HAVE_CONFIG_H diff --git a/mono/metadata/null-gc.c b/mono/metadata/null-gc.c index f933e11276f..7f904f3dec7 100644 --- a/mono/metadata/null-gc.c +++ b/mono/metadata/null-gc.c @@ -4,6 +4,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/number-ms.c b/mono/metadata/number-ms.c index b296ca2e37d..48084d143eb 100644 --- a/mono/metadata/number-ms.c +++ b/mono/metadata/number-ms.c @@ -5,6 +5,7 @@ * Ludovic Henry (ludovic@xamarin.com) * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ // diff --git a/mono/metadata/object-offsets.h b/mono/metadata/object-offsets.h index a79e3508e0f..36763dd311c 100644 --- a/mono/metadata/object-offsets.h +++ b/mono/metadata/object-offsets.h @@ -17,17 +17,22 @@ Output defines: HAS_CROSS_COMPILER_OFFSETS - if set, it means we found some cross offsets, it doesnt mean we'll use it. USED_CROSS_COMPILER_OFFSETS - if set, it means we used the cross offsets + +Environment defines (from config.h and CFLAGS): + +MONO_GENERATING_OFFSETS - Set by an offsets generating tool to disable the usage of any (possibly non-existing) generated header. +MONO_OFFSETS_FILE - Name of the header file containing the offsets to be used. + */ #undef HAS_CROSS_COMPILER_OFFSETS #undef USED_CROSS_COMPILER_OFFSETS -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/metadata/object-offsets.h" +#if !defined (MONO_GENERATING_OFFSETS) && defined (MONO_OFFSETS_FILE) +#include MONO_OFFSETS_FILE #endif - #ifndef USED_CROSS_COMPILER_OFFSETS DECL_ALIGN(gint8) @@ -225,6 +230,18 @@ DECL_OFFSET(DynCallArgs, res2) #if defined(TARGET_ARM) DECL_OFFSET(MonoLMF, method) +DECL_OFFSET(GSharedVtCallInfo, stack_usage) +DECL_OFFSET(GSharedVtCallInfo, vret_arg_reg) +DECL_OFFSET(GSharedVtCallInfo, ret_marshal) +DECL_OFFSET(GSharedVtCallInfo, vret_slot) +DECL_OFFSET(GSharedVtCallInfo, gsharedvt_in) +#endif + +#if defined(TARGET_ARM64) +DECL_OFFSET(GSharedVtCallInfo, stack_usage) +DECL_OFFSET(GSharedVtCallInfo, gsharedvt_in) +DECL_OFFSET(GSharedVtCallInfo, ret_marshal) +DECL_OFFSET(GSharedVtCallInfo, vret_slot) #endif #if defined(TARGET_AMD64) || defined(TARGET_ARM64) diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 92a733b34bd..dc20b4e8321 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2011 Novell, Inc (http://www.novell.com) * Copyright 2001 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #ifdef HAVE_ALLOCA_H diff --git a/mono/metadata/opcodes.c b/mono/metadata/opcodes.c index 6cfbe5cbcce..838142e253f 100644 --- a/mono/metadata/opcodes.c +++ b/mono/metadata/opcodes.c @@ -6,6 +6,7 @@ * * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include /* for NULL */ diff --git a/mono/metadata/pedump.c b/mono/metadata/pedump.c index 19ebb958b24..3af4153a867 100644 --- a/mono/metadata/pedump.c +++ b/mono/metadata/pedump.c @@ -6,6 +6,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/metadata/process.c b/mono/metadata/process.c index dd4ac82ee77..3cd38789d3c 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -6,6 +6,7 @@ * * Copyright 2002 Ximian, Inc. * Copyright 2002-2006 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/profiler.c b/mono/metadata/profiler.c index cdd11fda385..b2620ecf030 100644 --- a/mono/metadata/profiler.c +++ b/mono/metadata/profiler.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com). + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/rand.c b/mono/metadata/rand.c index 422bda1d1bc..87d2d104790 100644 --- a/mono/metadata/rand.c +++ b/mono/metadata/rand.c @@ -8,6 +8,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/rand.h b/mono/metadata/rand.h index 15af782fdc6..563b3748359 100644 --- a/mono/metadata/rand.h +++ b/mono/metadata/rand.h @@ -7,6 +7,7 @@ * * (C) 2001 Ximian, Inc. * Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_METADATA_RAND_H_ diff --git a/mono/metadata/reflection-internals.h b/mono/metadata/reflection-internals.h index 04417c82b71..600f2c6d268 100644 --- a/mono/metadata/reflection-internals.h +++ b/mono/metadata/reflection-internals.h @@ -1,5 +1,6 @@ /* * Copyright 2014 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_REFLECTION_INTERNALS_H__ #define __MONO_METADATA_REFLECTION_INTERNALS_H__ diff --git a/mono/metadata/reflection.c b/mono/metadata/reflection.c index c49153f85a1..200c41e5f80 100644 --- a/mono/metadata/reflection.c +++ b/mono/metadata/reflection.c @@ -8,6 +8,7 @@ * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Rodrigo Kumpera * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include "mono/utils/mono-digest.h" diff --git a/mono/metadata/remoting.c b/mono/metadata/remoting.c index 9c329f49342..6555cdec7a0 100644 --- a/mono/metadata/remoting.c +++ b/mono/metadata/remoting.c @@ -5,6 +5,7 @@ * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011-2014 Xamarin, Inc (http://www.xamarin.com) * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/runtime.c b/mono/metadata/runtime.c index fcd87823876..1c41c797db4 100644 --- a/mono/metadata/runtime.c +++ b/mono/metadata/runtime.c @@ -5,6 +5,7 @@ * Jonathan Pryor * * Copyright 2010 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/security-core-clr.c b/mono/metadata/security-core-clr.c index 235b9bec417..f874043e15b 100644 --- a/mono/metadata/security-core-clr.c +++ b/mono/metadata/security-core-clr.c @@ -6,6 +6,7 @@ * Sebastien Pouliot * * Copyright 2007-2010 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/security-manager.c b/mono/metadata/security-manager.c index e3c3cbc82d5..0dfb927bc29 100644 --- a/mono/metadata/security-manager.c +++ b/mono/metadata/security-manager.c @@ -5,6 +5,7 @@ * Sebastien Pouliot * * Copyright 2005-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "security-manager.h" diff --git a/mono/metadata/security-manager.h b/mono/metadata/security-manager.h index 98fbbfd6521..19ac3e8f82c 100644 --- a/mono/metadata/security-manager.h +++ b/mono/metadata/security-manager.h @@ -5,6 +5,7 @@ * Sebastien Pouliot * * Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_METADATA_SECURITY_MANAGER_H_ diff --git a/mono/metadata/seq-points-data.h b/mono/metadata/seq-points-data.h index 3f72f3f338a..afd19549824 100644 --- a/mono/metadata/seq-points-data.h +++ b/mono/metadata/seq-points-data.h @@ -1,5 +1,6 @@ /* * Copyright 2015 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SEQ_POINTS_DATA_H__ diff --git a/mono/metadata/sgen-bridge-internals.h b/mono/metadata/sgen-bridge-internals.h index ac7dfb97599..df6a4bb8cde 100644 --- a/mono/metadata/sgen-bridge-internals.h +++ b/mono/metadata/sgen-bridge-internals.h @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGENBRIDGEINTERNAL_H__ diff --git a/mono/metadata/sgen-bridge.c b/mono/metadata/sgen-bridge.c index 93d5b0858a9..3b0487c9243 100644 --- a/mono/metadata/sgen-bridge.c +++ b/mono/metadata/sgen-bridge.c @@ -3,38 +3,10 @@ * * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-bridge.h b/mono/metadata/sgen-bridge.h index 28bf2caf759..38dc44637cc 100644 --- a/mono/metadata/sgen-bridge.h +++ b/mono/metadata/sgen-bridge.h @@ -1,24 +1,7 @@ /* * Copyright 2011 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/metadata/sgen-client-mono.h b/mono/metadata/sgen-client-mono.h index d0eaa26e14e..54630c6ee03 100644 --- a/mono/metadata/sgen-client-mono.h +++ b/mono/metadata/sgen-client-mono.h @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifdef SGEN_DEFINE_OBJECT_VTABLE diff --git a/mono/metadata/sgen-mono.c b/mono/metadata/sgen-mono.c index efa0e892ecc..2956d95420a 100644 --- a/mono/metadata/sgen-mono.c +++ b/mono/metadata/sgen-mono.c @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-new-bridge.c b/mono/metadata/sgen-new-bridge.c index a4f05e63ac9..462680a63fe 100644 --- a/mono/metadata/sgen-new-bridge.c +++ b/mono/metadata/sgen-new-bridge.c @@ -3,38 +3,10 @@ * * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-old-bridge.c b/mono/metadata/sgen-old-bridge.c index f8437fe4810..a93cc7734ad 100644 --- a/mono/metadata/sgen-old-bridge.c +++ b/mono/metadata/sgen-old-bridge.c @@ -3,38 +3,9 @@ * * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * - * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-os-coop.c b/mono/metadata/sgen-os-coop.c index fb6fc13bc45..90c8266b341 100644 --- a/mono/metadata/sgen-os-coop.c +++ b/mono/metadata/sgen-os-coop.c @@ -5,18 +5,7 @@ * João Matos (joao.matos@xamarin.com) * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" @@ -78,4 +67,4 @@ mono_gc_get_restart_signal (void) } #endif -#endif \ No newline at end of file +#endif diff --git a/mono/metadata/sgen-os-mach.c b/mono/metadata/sgen-os-mach.c index 666ef3ce8cf..10ac567111e 100644 --- a/mono/metadata/sgen-os-mach.c +++ b/mono/metadata/sgen-os-mach.c @@ -9,18 +9,7 @@ * Copyright 2010 Novell, Inc (http://www.novell.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-os-posix.c b/mono/metadata/sgen-os-posix.c index 37979a497d4..dc9d29ff139 100644 --- a/mono/metadata/sgen-os-posix.c +++ b/mono/metadata/sgen-os-posix.c @@ -9,18 +9,7 @@ * Copyright 2010 Novell, Inc (http://www.novell.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-stw.c b/mono/metadata/sgen-stw.c index 15eb283ee13..4185ce07b8a 100644 --- a/mono/metadata/sgen-stw.c +++ b/mono/metadata/sgen-stw.c @@ -10,18 +10,7 @@ * Copyright 2011 Xamarin, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-tarjan-bridge.c b/mono/metadata/sgen-tarjan-bridge.c index e6bd1f17aa7..764d9d72626 100644 --- a/mono/metadata/sgen-tarjan-bridge.c +++ b/mono/metadata/sgen-tarjan-bridge.c @@ -4,37 +4,11 @@ * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2014 Xamarin Inc (http://www.xamarin.com) * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - * * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-toggleref.c b/mono/metadata/sgen-toggleref.c index d9afbfa868d..5ca66e738af 100644 --- a/mono/metadata/sgen-toggleref.c +++ b/mono/metadata/sgen-toggleref.c @@ -7,18 +7,7 @@ * Copyright 2011 Xamarin, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/metadata/sgen-toggleref.h b/mono/metadata/sgen-toggleref.h index e7c4b91b740..917323c575a 100644 --- a/mono/metadata/sgen-toggleref.h +++ b/mono/metadata/sgen-toggleref.h @@ -7,24 +7,7 @@ * Author: * Rodrigo Kumpera (kumpera@gmail.com) * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_SGEN_TOGGLEREF_H_ diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index 7f8c7beaa2c..4bf721f9a06 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -10,6 +10,7 @@ * * This file has been re-licensed under the MIT License: * http://opensource.org/licenses/MIT + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/string-icalls.c b/mono/metadata/string-icalls.c index 1594cc52bfc..be330aa413a 100644 --- a/mono/metadata/string-icalls.c +++ b/mono/metadata/string-icalls.c @@ -7,6 +7,7 @@ * * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/metadata/sysmath.c b/mono/metadata/sysmath.c index eadb052ccd1..8d55a552f84 100644 --- a/mono/metadata/sysmath.c +++ b/mono/metadata/sysmath.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2015 Xamarin, Inc (https://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ // diff --git a/mono/metadata/sysmath.h b/mono/metadata/sysmath.h index bb3cf92bfd5..85d3234dfdb 100644 --- a/mono/metadata/sysmath.h +++ b/mono/metadata/sysmath.h @@ -7,6 +7,7 @@ * * (C) Ximian, Inc. 2002 * Copyright 2015 Xamarin, Inc (https://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __METADATA_SYSMATH_H__ diff --git a/mono/metadata/threadpool-ms-io.c b/mono/metadata/threadpool-ms-io.c index 30e34e50a3c..5f4f36a193f 100644 --- a/mono/metadata/threadpool-ms-io.c +++ b/mono/metadata/threadpool-ms-io.c @@ -5,6 +5,7 @@ * Ludovic Henry (ludovic.henry@xamarin.com) * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/threadpool-ms.c b/mono/metadata/threadpool-ms.c index d495d45d99f..62fc34aef3f 100644 --- a/mono/metadata/threadpool-ms.c +++ b/mono/metadata/threadpool-ms.c @@ -5,6 +5,7 @@ * Ludovic Henry (ludovic.henry@xamarin.com) * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ // diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h index b097a377fe6..b970e96e038 100644 --- a/mono/metadata/threads-types.h +++ b/mono/metadata/threads-types.h @@ -7,6 +7,7 @@ * * (C) 2001 Ximian, Inc * (C) Copyright 2002-2006 Novell, Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _MONO_METADATA_THREADS_TYPES_H_ diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 68c4b9025c0..5884d0270e5 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -9,6 +9,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/metadata/verify.c b/mono/metadata/verify.c index 383ced4f1bf..1d291ddb459 100644 --- a/mono/metadata/verify.c +++ b/mono/metadata/verify.c @@ -7,6 +7,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Rodrigo Kumpera + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/Makefile.am.in b/mono/mini/Makefile.am.in index f75db695f35..98fbf90fede 100755 --- a/mono/mini/Makefile.am.in +++ b/mono/mini/Makefile.am.in @@ -304,13 +304,18 @@ x86_sources = \ mini-x86.c \ mini-x86.h \ exceptions-x86.c \ - tramp-x86.c + tramp-x86.c \ + mini-x86-gsharedvt.c \ + tramp-x86-gsharedvt.c amd64_sources = \ mini-amd64.c \ mini-amd64.h \ exceptions-amd64.c \ - tramp-amd64.c + tramp-amd64.c \ + mini-amd64-gsharedvt.c \ + mini-amd64-gsharedvt.h \ + tramp-amd64-gsharedvt.c ppc_sources = \ mini-ppc.c \ @@ -324,13 +329,17 @@ arm_sources = \ mini-arm.h \ mini-arm-tls.h \ exceptions-arm.c \ - tramp-arm.c + tramp-arm.c \ + mini-arm-gsharedvt.c \ + tramp-arm-gsharedvt.c arm64_sources = \ mini-arm64.c \ mini-arm64.h \ exceptions-arm64.c \ - tramp-arm64.c + tramp-arm64.c \ + mini-arm64-gsharedvt.c \ + tramp-arm64-gsharedvt.c mips_sources = \ mini-mips.c \ @@ -425,9 +434,11 @@ common_sources = \ graph.c \ mini-codegen.c \ mini-exceptions.c \ + mini-exceptions-native-unwinder.c \ mini-trampolines.c \ branch-opts.c \ mini-generic-sharing.c \ + mini-generic-sharing-gsharedvt.c \ simd-methods.h \ tasklets.c \ tasklets.h \ diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index b74b1107fbf..dd2780edac9 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -8,6 +8,7 @@ * (C) 2002 Ximian, Inc. * Copyright 2003-2011 Novell, Inc * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" @@ -857,7 +858,331 @@ arch_init (MonoAotCompile *acfg) #ifdef TARGET_ARM64 -#include "../../../mono-extensions/mono/mini/aot-compiler-arm64.c" + +/* Load the contents of GOT_SLOT into dreg, clobbering ip0 */ +static void +arm64_emit_load_got_slot (MonoAotCompile *acfg, int dreg, int got_slot) +{ + int offset; + + g_assert (acfg->fp); + emit_unset_mode (acfg); + /* r16==ip0 */ + offset = (int)(got_slot * sizeof (gpointer)); +#ifdef TARGET_MACH + /* clang's integrated assembler */ + fprintf (acfg->fp, "adrp x16, %s@PAGE+%d\n", acfg->got_symbol, offset & 0xfffff000); + fprintf (acfg->fp, "add x16, x16, %s@PAGEOFF\n", acfg->got_symbol); + fprintf (acfg->fp, "ldr x%d, [x16, #%d]\n", dreg, offset & 0xfff); +#else + /* Linux GAS */ + fprintf (acfg->fp, "adrp x16, %s+%d\n", acfg->got_symbol, offset & 0xfffff000); + fprintf (acfg->fp, "add x16, x16, :lo12:%s\n", acfg->got_symbol); + fprintf (acfg->fp, "ldr x%d, [x16, %d]\n", dreg, offset & 0xfff); +#endif +} + +static void +arm64_emit_objc_selector_ref (MonoAotCompile *acfg, guint8 *code, int index, int *code_size) +{ + int reg; + + g_assert (acfg->fp); + emit_unset_mode (acfg); + + /* ldr rt, target */ + reg = arm_get_ldr_lit_reg (code); + + fprintf (acfg->fp, "adrp x%d, L_OBJC_SELECTOR_REFERENCES_%d@PAGE\n", reg, index); + fprintf (acfg->fp, "add x%d, x%d, L_OBJC_SELECTOR_REFERENCES_%d@PAGEOFF\n", reg, reg, index); + fprintf (acfg->fp, "ldr x%d, [x%d]\n", reg, reg); + + *code_size = 12; +} + +static void +arm64_emit_direct_call (MonoAotCompile *acfg, const char *target, gboolean external, gboolean thumb, MonoJumpInfo *ji, int *call_size) +{ + g_assert (acfg->fp); + emit_unset_mode (acfg); + if (ji && ji->relocation == MONO_R_ARM64_B) { + fprintf (acfg->fp, "b %s\n", target); + } else { + if (ji) + g_assert (ji->relocation == MONO_R_ARM64_BL); + fprintf (acfg->fp, "bl %s\n", target); + } + *call_size = 4; +} + +static void +arm64_emit_got_access (MonoAotCompile *acfg, guint8 *code, int got_slot, int *code_size) +{ + int reg; + + /* ldr rt, target */ + reg = arm_get_ldr_lit_reg (code); + arm64_emit_load_got_slot (acfg, reg, got_slot); + *code_size = 12; +} + +static void +arm64_emit_plt_entry (MonoAotCompile *acfg, const char *got_symbol, int offset, int info_offset) +{ + arm64_emit_load_got_slot (acfg, ARMREG_R16, offset / sizeof (gpointer)); + fprintf (acfg->fp, "br x16\n"); + /* Used by mono_aot_get_plt_info_offset () */ + fprintf (acfg->fp, "%s %d\n", acfg->inst_directive, info_offset); +} + +static void +arm64_emit_tramp_page_common_code (MonoAotCompile *acfg, int pagesize, int arg_reg, int *size) +{ + guint8 buf [256]; + guint8 *code; + int imm; + + /* The common code */ + code = buf; + imm = pagesize; + /* The trampoline address is in IP0 */ + arm_movzx (code, ARMREG_IP1, imm & 0xffff, 0); + arm_movkx (code, ARMREG_IP1, (imm >> 16) & 0xffff, 16); + /* Compute the data slot address */ + arm_subx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); + /* Trampoline argument */ + arm_ldrx (code, arg_reg, ARMREG_IP0, 0); + /* Address */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 8); + arm_brx (code, ARMREG_IP0); + + /* Emit it */ + emit_code_bytes (acfg, buf, code - buf); + + *size = code - buf; +} + +static void +arm64_emit_tramp_page_specific_code (MonoAotCompile *acfg, int pagesize, int common_tramp_size, int specific_tramp_size) +{ + guint8 buf [256]; + guint8 *code; + int i, count; + + count = (pagesize - common_tramp_size) / specific_tramp_size; + for (i = 0; i < count; ++i) { + code = buf; + arm_adrx (code, ARMREG_IP0, code); + /* Branch to the generic code */ + arm_b (code, code - 4 - (i * specific_tramp_size) - common_tramp_size); + /* This has to be 2 pointers long */ + arm_nop (code); + arm_nop (code); + g_assert (code - buf == specific_tramp_size); + emit_code_bytes (acfg, buf, code - buf); + } +} + +static void +arm64_emit_specific_trampoline_pages (MonoAotCompile *acfg) +{ + guint8 buf [128]; + guint8 *code; + guint8 *labels [16]; + int common_tramp_size; + int specific_tramp_size = 2 * 8; + int imm, pagesize; + char symbol [128]; + + if (!acfg->aot_opts.use_trampolines_page) + return; + +#ifdef TARGET_MACH + /* Have to match the target pagesize */ + pagesize = 16384; +#else + pagesize = mono_pagesize (); +#endif + acfg->tramp_page_size = pagesize; + + /* The specific trampolines */ + sprintf (symbol, "%sspecific_trampolines_page", acfg->user_symbol_prefix); + emit_alignment (acfg, pagesize); + emit_global (acfg, symbol, TRUE); + emit_label (acfg, symbol); + + /* The common code */ + arm64_emit_tramp_page_common_code (acfg, pagesize, ARMREG_IP1, &common_tramp_size); + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_SPECIFIC] = common_tramp_size; + + arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size); + + /* The rgctx trampolines */ + /* These are the same as the specific trampolines, but they load the argument into MONO_ARCH_RGCTX_REG */ + sprintf (symbol, "%srgctx_trampolines_page", acfg->user_symbol_prefix); + emit_alignment (acfg, pagesize); + emit_global (acfg, symbol, TRUE); + emit_label (acfg, symbol); + + /* The common code */ + arm64_emit_tramp_page_common_code (acfg, pagesize, MONO_ARCH_RGCTX_REG, &common_tramp_size); + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_STATIC_RGCTX] = common_tramp_size; + + arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size); + + /* The gsharedvt arg trampolines */ + /* These are the same as the specific trampolines */ + sprintf (symbol, "%sgsharedvt_arg_trampolines_page", acfg->user_symbol_prefix); + emit_alignment (acfg, pagesize); + emit_global (acfg, symbol, TRUE); + emit_label (acfg, symbol); + + arm64_emit_tramp_page_common_code (acfg, pagesize, ARMREG_IP1, &common_tramp_size); + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_GSHAREDVT_ARG] = common_tramp_size; + + arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size); + + /* The IMT trampolines */ + sprintf (symbol, "%simt_trampolines_page", acfg->user_symbol_prefix); + emit_alignment (acfg, pagesize); + emit_global (acfg, symbol, TRUE); + emit_label (acfg, symbol); + + code = buf; + imm = pagesize; + /* The trampoline address is in IP0 */ + arm_movzx (code, ARMREG_IP1, imm & 0xffff, 0); + arm_movkx (code, ARMREG_IP1, (imm >> 16) & 0xffff, 16); + /* Compute the data slot address */ + arm_subx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); + /* Trampoline argument */ + arm_ldrx (code, ARMREG_IP1, ARMREG_IP0, 0); + + /* Same as arch_emit_imt_thunk () */ + labels [0] = code; + arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 0); + arm_cmpx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG); + labels [1] = code; + arm_bcc (code, ARMCOND_EQ, 0); + + /* End-of-loop check */ + labels [2] = code; + arm_cbzx (code, ARMREG_IP0, 0); + + /* Loop footer */ + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 2 * 8); + arm_b (code, labels [0]); + + /* Match */ + mono_arm_patch (labels [1], code, MONO_R_ARM64_BCC); + /* Load vtable slot addr */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8); + /* Load vtable slot */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); + arm_brx (code, ARMREG_IP0); + + /* No match */ + mono_arm_patch (labels [2], code, MONO_R_ARM64_CBZ); + /* Load fail addr */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8); + arm_brx (code, ARMREG_IP0); + + emit_code_bytes (acfg, buf, code - buf); + + common_tramp_size = code - buf; + acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_IMT_THUNK] = common_tramp_size; + + arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size); +} + +static void +arm64_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size) +{ + /* Load argument from second GOT slot */ + arm64_emit_load_got_slot (acfg, ARMREG_R17, offset + 1); + /* Load generic trampoline address from first GOT slot */ + arm64_emit_load_got_slot (acfg, ARMREG_R16, offset); + fprintf (acfg->fp, "br x16\n"); + *tramp_size = 7 * 4; +} + +static void +arm64_emit_unbox_trampoline (MonoAotCompile *acfg, MonoCompile *cfg, MonoMethod *method, const char *call_target) +{ + emit_unset_mode (acfg); + fprintf (acfg->fp, "add x0, x0, %d\n", (int)(sizeof (MonoObject))); + fprintf (acfg->fp, "b %s\n", call_target); +} + +static void +arm64_emit_static_rgctx_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size) +{ + /* Similar to the specific trampolines, but use the rgctx reg instead of ip1 */ + + /* Load argument from first GOT slot */ + g_assert (MONO_ARCH_RGCTX_REG == 27); + arm64_emit_load_got_slot (acfg, ARMREG_R27, offset); + /* Load generic trampoline address from second GOT slot */ + arm64_emit_load_got_slot (acfg, ARMREG_R16, offset + 1); + fprintf (acfg->fp, "br x16\n"); + *tramp_size = 7 * 4; +} + +static void +arm64_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size) +{ + guint8 buf [128]; + guint8 *code, *labels [16]; + + /* Load parameter from GOT slot into ip1 */ + arm64_emit_load_got_slot (acfg, ARMREG_R17, offset); + + code = buf; + labels [0] = code; + arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 0); + arm_cmpx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG); + labels [1] = code; + arm_bcc (code, ARMCOND_EQ, 0); + + /* End-of-loop check */ + labels [2] = code; + arm_cbzx (code, ARMREG_IP0, 0); + + /* Loop footer */ + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 2 * 8); + arm_b (code, labels [0]); + + /* Match */ + mono_arm_patch (labels [1], code, MONO_R_ARM64_BCC); + /* Load vtable slot addr */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8); + /* Load vtable slot */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); + arm_brx (code, ARMREG_IP0); + + /* No match */ + mono_arm_patch (labels [2], code, MONO_R_ARM64_CBZ); + /* Load fail addr */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8); + arm_brx (code, ARMREG_IP0); + + emit_code_bytes (acfg, buf, code - buf); + + *tramp_size = code - buf + (3 * 4); +} + +static void +arm64_emit_gsharedvt_arg_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size) +{ + /* Similar to the specific trampolines, but the address is in the second slot */ + /* Load argument from first GOT slot */ + arm64_emit_load_got_slot (acfg, ARMREG_R17, offset); + /* Load generic trampoline address from second GOT slot */ + arm64_emit_load_got_slot (acfg, ARMREG_R16, offset + 1); + fprintf (acfg->fp, "br x16\n"); + *tramp_size = 7 * 4; +} + #endif @@ -10116,7 +10441,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) //acfg->aot_opts.print_skipped_methods = TRUE; -#if !defined(ENABLE_GSHAREDVT) +#if !defined(MONO_ARCH_GSHAREDVT_SUPPORTED) if (opts & MONO_OPT_GSHAREDVT) { aot_printerrf (acfg, "-O=gsharedvt not supported on this platform.\n"); return 1; @@ -10131,13 +10456,13 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) #endif if (acfg->aot_opts.llvm_only) { -#ifndef ENABLE_GSHAREDVT - aot_printerrf (acfg, "--aot=llvmonly requires a runtime compiled with --enable-gsharedvt.\n"); +#ifndef MONO_ARCH_GSHAREDVT_SUPPORTED + aot_printerrf (acfg, "--aot=llvmonly requires a runtime that supports gsharedvt.\n"); return 1; #endif } -#if defined(ENABLE_GSHAREDVT) && defined(MONO_ARCH_GSHAREDVT_SUPPORTED) +#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) acfg->opts |= MONO_OPT_GSHAREDVT; opts |= MONO_OPT_GSHAREDVT; #endif diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 4f633c190af..2d789a2f176 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -8,6 +8,7 @@ * (C) 2002 Ximian, Inc. * Copyright 2003-2011 Novell, Inc. * Copyright 2011 Xamarin, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/mini/arch-stubs.c b/mono/mini/arch-stubs.c index a75bab23586..cad20a06b24 100644 --- a/mono/mini/arch-stubs.c +++ b/mono/mini/arch-stubs.c @@ -33,23 +33,6 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) #endif -#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) && !defined(ENABLE_GSHAREDVT) - -gboolean -mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig) -{ - return FALSE; -} - -gpointer -mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) -{ - NOT_IMPLEMENTED; - return NULL; -} - -#endif - #ifndef MONO_ARCH_HAVE_DECOMPOSE_OPTS void mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins) diff --git a/mono/mini/bench.cs b/mono/mini/bench.cs index c6a23620c56..15cd67d60c6 100644 --- a/mono/mini/bench.cs +++ b/mono/mini/bench.cs @@ -2,6 +2,7 @@ using System; using System.Reflection; /* + * Licensed under the MIT license. See LICENSE file in the project root for full license information. * Regression tests for the mono JIT. * * Each test needs to be of the form: diff --git a/mono/mini/branch-opts.c b/mono/mini/branch-opts.c index 1a4ea53fe1f..7b2bedd5647 100644 --- a/mono/mini/branch-opts.c +++ b/mono/mini/branch-opts.c @@ -6,6 +6,7 @@ * * (C) 2005 Ximian, Inc. http://www.ximian.com * Copyright 2011 Xamarin Inc. http://www.xamarin.com + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" diff --git a/mono/mini/cpu-arm.md b/mono/mini/cpu-arm.md index cd51ad72c94..24694376aac 100644 --- a/mono/mini/cpu-arm.md +++ b/mono/mini/cpu-arm.md @@ -1,5 +1,6 @@ # Copyright 2003-2011 Novell, Inc (http://www.novell.com) # Copyright 2011 Xamarin, Inc (http://www.xamarin.com) +# Licensed under the MIT license. See LICENSE file in the project root for full license information. # arm cpu description file # this file is read by genmdesc to pruduce a table with all the relevant information # about the cpu instructions that may be used by the regsiter allocator, the scheduler diff --git a/mono/mini/cpu-arm64.md b/mono/mini/cpu-arm64.md index 440e6a69e14..a8eea0965d5 100644 --- a/mono/mini/cpu-arm64.md +++ b/mono/mini/cpu-arm64.md @@ -1,5 +1,6 @@ # Copyright 2011-2013 Xamarin, Inc (http://www.xamarin.com) # Copyright 2003-2011 Novell, Inc (http://www.novell.com) +# Licensed under the MIT license. See LICENSE file in the project root for full license information. # arm64 cpu description file # this file is read by genmdesc to pruduce a table with all the relevant information # about the cpu instructions that may be used by the regsiter allocator, the scheduler diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index e69085073ec..b2712b486eb 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -6,6 +6,7 @@ * * Copyright 2009-2010 Novell, Inc. * Copyright 2011 Xamarin Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c index 10c8c75e134..10a5bdfd5b4 100644 --- a/mono/mini/decompose.c +++ b/mono/mini/decompose.c @@ -6,6 +6,7 @@ * * (C) 2002 Ximian, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" diff --git a/mono/mini/dominators.c b/mono/mini/dominators.c index ab3ba6333cc..b4c8dc39056 100644 --- a/mono/mini/dominators.c +++ b/mono/mini/dominators.c @@ -7,6 +7,7 @@ * * (C) 2003 Ximian, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/driver.c b/mono/mini/driver.c index 5b717fcd5e0..a84cd2f6ab0 100644 --- a/mono/mini/driver.c +++ b/mono/mini/driver.c @@ -7,6 +7,7 @@ * * (C) 2002-2003 Ximian, Inc. * (C) 2003-2006 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index cab03fc0f2e..06c0fd710fc 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -6,6 +6,7 @@ * * (C) 2001 Ximian, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/exceptions-arm64.c b/mono/mini/exceptions-arm64.c index 333fd13b754..5737edebf23 100644 --- a/mono/mini/exceptions-arm64.c +++ b/mono/mini/exceptions-arm64.c @@ -1 +1,595 @@ -#include "../../../mono-extensions/mono/mini/exceptions-arm64.c" +/* + * exceptions-arm64.c: exception support for ARM64 + * + * Copyright 2013 Xamarin Inc + * + * Based on exceptions-arm.c: + * + * Authors: + * Dietmar Maurer (dietmar@ximian.com) + * Paolo Molaro (lupus@ximian.com) + * + * (C) 2001 Ximian, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +#include "mini.h" + +#include +#include + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +#ifndef DISABLE_JIT + +gpointer +mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) +{ + guint8 *start, *code; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + int i, ctx_reg, size; + + size = 256; + code = start = mono_global_codeman_reserve (size); + + arm_movx (code, ARMREG_IP0, ARMREG_R0); + ctx_reg = ARMREG_IP0; + /* Restore fregs */ + for (i = 0; i < 32; ++i) + arm_ldrfpx (code, i, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, fregs) + (i * 8)); + /* Restore gregs */ + // FIXME: Restore less registers + // FIXME: fp should be restored later + code = mono_arm_emit_load_regarray (code, 0xffffffff & ~(1 << ctx_reg) & ~(1 << ARMREG_SP), ctx_reg, MONO_STRUCT_OFFSET (MonoContext, regs)); + /* ip0/ip1 doesn't need to be restored */ + /* ip1 = pc */ + arm_ldrx (code, ARMREG_IP1, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, pc)); + /* ip0 = sp */ + arm_ldrx (code, ARMREG_IP0, ctx_reg, MONO_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_SP * 8)); + /* Restore sp, ctx is no longer valid */ + arm_movspx (code, ARMREG_SP, ARMREG_IP0); + /* Branch to pc */ + arm_brx (code, ARMREG_IP1); + /* Not reached */ + arm_brk (code, 0); + + g_assert ((code - start) < size); + mono_arch_flush_icache (start, code - start); + mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); + + if (info) + *info = mono_tramp_info_create ("restore_context", start, code - start, ji, unwind_ops); + + return start; +} + +gpointer +mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) +{ + guint8 *code; + guint8* start; + int size, offset, gregs_offset, fregs_offset, ctx_offset, num_fregs, frame_size; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + + size = 512; + start = code = mono_global_codeman_reserve (size); + + /* Compute stack frame size and offsets */ + offset = 0; + /* frame block */ + offset += 2 * 8; + /* gregs */ + gregs_offset = offset; + offset += 32 * 8; + /* fregs */ + num_fregs = 8; + fregs_offset = offset; + offset += num_fregs * 8; + ctx_offset = offset; + ctx_offset += 8; + frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + + /* + * We are being called from C code, ctx is in r0, the address to call is in r1. + * We need to save state, restore ctx, make the call, then restore the previous state, + * returning the value returned by the call. + */ + + /* Setup a frame */ + arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -frame_size); + arm_movspx (code, ARMREG_FP, ARMREG_SP); + + /* Save ctx */ + arm_strx (code, ARMREG_R0, ARMREG_FP, ctx_offset); + /* Save gregs */ + code = mono_arm_emit_store_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS | (1 << ARMREG_FP), ARMREG_FP, gregs_offset); + /* No need to save/restore fregs, since we don't currently use them */ + + /* Load regs from ctx */ + code = mono_arm_emit_load_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, regs)); + /* Load fp */ + arm_ldrx (code, ARMREG_FP, ARMREG_R0, MONO_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_FP * 8)); + + /* Make the call */ + arm_blrx (code, ARMREG_R1); + /* For filters, the result is in R0 */ + + /* Restore fp */ + arm_ldrx (code, ARMREG_FP, ARMREG_SP, gregs_offset + (ARMREG_FP * 8)); + /* Load ctx */ + arm_ldrx (code, ARMREG_IP0, ARMREG_FP, ctx_offset); + /* Save registers back to ctx */ + /* This isn't strictly neccessary since we don't allocate variables used in eh clauses to registers */ + code = mono_arm_emit_store_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoContext, regs)); + + /* Restore regs */ + code = mono_arm_emit_load_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS, ARMREG_FP, gregs_offset); + /* Destroy frame */ + code = mono_arm_emit_destroy_frame (code, frame_size, (1 << ARMREG_IP0)); + arm_retx (code, ARMREG_LR); + + g_assert ((code - start) < size); + mono_arch_flush_icache (start, code - start); + mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); + + if (info) + *info = mono_tramp_info_create ("call_filter", start, code - start, ji, unwind_ops); + + return start; +} + +static gpointer +get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm, gboolean resume_unwind, const char *tramp_name, MonoTrampInfo **info, gboolean aot) +{ + guint8 *start, *code; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + int i, offset, gregs_offset, fregs_offset, frame_size, num_fregs; + + code = start = mono_global_codeman_reserve (size); + + /* We are being called by JITted code, the exception object/type token is in R0 */ + + /* Compute stack frame size and offsets */ + offset = 0; + /* frame block */ + offset += 2 * 8; + /* gregs */ + gregs_offset = offset; + offset += 32 * 8; + /* fregs */ + num_fregs = 8; + fregs_offset = offset; + offset += num_fregs * 8; + frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + + /* Setup a frame */ + arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -frame_size); + arm_movspx (code, ARMREG_FP, ARMREG_SP); + + /* Save gregs */ + code = mono_arm_emit_store_regarray (code, 0xffffffff, ARMREG_FP, gregs_offset); + if (corlib && !llvm) + /* The real LR is in R1 */ + arm_strx (code, ARMREG_R1, ARMREG_FP, gregs_offset + (ARMREG_LR * 8)); + /* Save fp/sp */ + arm_ldrx (code, ARMREG_IP0, ARMREG_FP, 0); + arm_strx (code, ARMREG_IP0, ARMREG_FP, gregs_offset + (ARMREG_FP * 8)); + arm_addx_imm (code, ARMREG_IP0, ARMREG_FP, frame_size); + arm_strx (code, ARMREG_IP0, ARMREG_FP, gregs_offset + (ARMREG_SP * 8)); + /* Save fregs */ + for (i = 0; i < num_fregs; ++i) + arm_strfpx (code, ARMREG_D8 + i, ARMREG_FP, fregs_offset + (i * 8)); + + /* Call the C trampoline function */ + /* Arg1 = exception object/type token */ + arm_movx (code, ARMREG_R0, ARMREG_R0); + /* Arg2 = caller ip */ + if (corlib) { + if (llvm) + arm_ldrx (code, ARMREG_R1, ARMREG_FP, gregs_offset + (ARMREG_LR * 8)); + else + arm_movx (code, ARMREG_R1, ARMREG_R1); + } else { + arm_ldrx (code, ARMREG_R1, ARMREG_FP, 8); + } + /* Arg 3 = gregs */ + arm_addx_imm (code, ARMREG_R2, ARMREG_FP, gregs_offset); + /* Arg 4 = fregs */ + arm_addx_imm (code, ARMREG_R3, ARMREG_FP, fregs_offset); + /* Arg 5 = corlib */ + arm_movzx (code, ARMREG_R4, corlib ? 1 : 0, 0); + /* Arg 6 = rethrow */ + arm_movzx (code, ARMREG_R5, rethrow ? 1 : 0, 0); + /* Call the function */ + if (aot) { + const char *icall_name; + + if (resume_unwind) + icall_name = "mono_arm_resume_unwind"; + else + icall_name = "mono_arm_throw_exception"; + + code = mono_arm_emit_aotconst (&ji, code, start, ARMREG_LR, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name); + } else { + gpointer icall_func; + + if (resume_unwind) + icall_func = mono_arm_resume_unwind; + else + icall_func = mono_arm_throw_exception; + + code = mono_arm_emit_imm64 (code, ARMREG_LR, (guint64)icall_func); + } + arm_blrx (code, ARMREG_LR); + /* This shouldn't return */ + arm_brk (code, 0x0); + + g_assert ((code - start) < size); + mono_arch_flush_icache (start, code - start); + mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); + + if (info) + *info = mono_tramp_info_create (tramp_name, start, code - start, ji, unwind_ops); + + return start; +} + +gpointer +mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline (256, FALSE, FALSE, FALSE, FALSE, "throw_exception", info, aot); +} + +gpointer +mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline (256, FALSE, TRUE, FALSE, FALSE, "rethrow_exception", info, aot); +} + +gpointer +mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) +{ + return get_throw_trampoline (256, TRUE, FALSE, FALSE, FALSE, "throw_corlib_exception", info, aot); +} + +GSList* +mono_arm_get_exception_trampolines (gboolean aot) +{ + MonoTrampInfo *info; + GSList *tramps = NULL; + + /* LLVM uses the normal trampolines, but with a different name */ + get_throw_trampoline (256, TRUE, FALSE, FALSE, FALSE, "llvm_throw_corlib_exception_trampoline", &info, aot); + tramps = g_slist_prepend (tramps, info); + + get_throw_trampoline (256, TRUE, FALSE, TRUE, FALSE, "llvm_throw_corlib_exception_abs_trampoline", &info, aot); + tramps = g_slist_prepend (tramps, info); + + get_throw_trampoline (256, FALSE, FALSE, FALSE, TRUE, "llvm_resume_unwind_trampoline", &info, aot); + tramps = g_slist_prepend (tramps, info); + + return tramps; +} + +#else /* DISABLE_JIT */ + +gpointer +mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +GSList* +mono_arm_get_exception_trampolines (gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +#endif /* !DISABLE_JIT */ + +void +mono_arch_exceptions_init (void) +{ + guint8 *tramp; + GSList *tramps, *l; + + if (mono_aot_only) { + tramp = mono_aot_get_trampoline ("llvm_throw_corlib_exception_trampoline"); + mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_trampoline", NULL, TRUE); + tramp = mono_aot_get_trampoline ("llvm_throw_corlib_exception_abs_trampoline"); + mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_abs_trampoline", NULL, TRUE); + tramp = mono_aot_get_trampoline ("llvm_resume_unwind_trampoline"); + mono_register_jit_icall (tramp, "llvm_resume_unwind_trampoline", NULL, TRUE); + } else { + tramps = mono_arm_get_exception_trampolines (FALSE); + for (l = tramps; l; l = l->next) { + MonoTrampInfo *info = l->data; + + mono_register_jit_icall (info->code, g_strdup (info->name), NULL, TRUE); + mono_tramp_info_register (info, NULL); + } + g_slist_free (tramps); + } +} + +/* + * mono_arm_throw_exception: + * + * This function is called by the exception trampolines. + * FP_REGS points to the 8 callee saved fp regs. + */ +void +mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow) +{ + MonoContext ctx; + MonoObject *exc = NULL; + guint32 ex_token_index, ex_token; + + if (!corlib) + exc = arg; + else { + ex_token_index = (guint64)arg; + ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index; + exc = (MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token); + } + + /* Adjust pc so it points into the call instruction */ + pc -= 4; + + /* Initialize a ctx based on the arguments */ + memset (&ctx, 0, sizeof (MonoContext)); + memcpy (&(ctx.regs [0]), int_regs, sizeof (mgreg_t) * 32); + memcpy (&(ctx.fregs [ARMREG_D8]), fp_regs, sizeof (double) * 8); + ctx.pc = pc; + + if (mono_object_isinst (exc, mono_defaults.exception_class)) { + MonoException *mono_ex = (MonoException*)exc; + if (!rethrow) + mono_ex->stack_trace = NULL; + } + + mono_handle_exception (&ctx, exc); + + mono_restore_context (&ctx); +} + +void +mono_arm_resume_unwind (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow) +{ + MonoContext ctx; + + /* Adjust pc so it points into the call instruction */ + pc -= 4; + + /* Initialize a ctx based on the arguments */ + memset (&ctx, 0, sizeof (MonoContext)); + memcpy (&(ctx.regs [0]), int_regs, sizeof (mgreg_t) * 32); + memcpy (&(ctx.fregs [ARMREG_D8]), fp_regs, sizeof (double) * 8); + ctx.pc = pc; + + mono_resume_unwind (&ctx); +} + +/* + * mono_arch_unwind_frame: + * + * See exceptions-amd64.c for docs; + */ +gboolean +mono_arch_unwind_frame (MonoDomain *domain, MonoJitTlsData *jit_tls, + MonoJitInfo *ji, MonoContext *ctx, + MonoContext *new_ctx, MonoLMF **lmf, + mgreg_t **save_locations, + StackFrameInfo *frame) +{ + gpointer ip = MONO_CONTEXT_GET_IP (ctx); + + memset (frame, 0, sizeof (StackFrameInfo)); + frame->ji = ji; + + *new_ctx = *ctx; + + if (ji != NULL) { + mgreg_t regs [MONO_MAX_IREGS + 8 + 1]; + guint8 *cfa; + guint32 unwind_info_len; + guint8 *unwind_info; + + frame->type = FRAME_TYPE_MANAGED; + + unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len); + + memcpy (regs, &new_ctx->regs, sizeof (mgreg_t) * 32); + /* v8..v15 are callee saved */ + memcpy (regs + MONO_MAX_IREGS, &(new_ctx->fregs [8]), sizeof (mgreg_t) * 8); + + mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, + (guint8*)ji->code_start + ji->code_size, + ip, NULL, regs, MONO_MAX_IREGS + 8, + save_locations, MONO_MAX_IREGS, &cfa); + + memcpy (&new_ctx->regs, regs, sizeof (mgreg_t) * 32); + memcpy (&(new_ctx->fregs [8]), regs + MONO_MAX_IREGS, sizeof (mgreg_t) * 8); + + new_ctx->pc = regs [ARMREG_LR]; + new_ctx->regs [ARMREG_SP] = (mgreg_t)cfa; + + if (*lmf && (*lmf)->gregs [MONO_ARCH_LMF_REG_SP] && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->gregs [MONO_ARCH_LMF_REG_SP])) { + /* remove any unused lmf */ + *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); + } + + /* we substract 1, so that the IP points into the call instruction */ + new_ctx->pc--; + + return TRUE; + } else if (*lmf) { + if (((gsize)(*lmf)->previous_lmf) & 2) { + /* + * This LMF entry is created by the soft debug code to mark transitions to + * managed code done during invokes. + */ + MonoLMFExt *ext = (MonoLMFExt*)(*lmf); + + g_assert (ext->debugger_invoke); + + memcpy (new_ctx, &ext->ctx, sizeof (MonoContext)); + + *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); + + frame->type = FRAME_TYPE_DEBUGGER_INVOKE; + + return TRUE; + } + + frame->type = FRAME_TYPE_MANAGED_TO_NATIVE; + + ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->pc, NULL); + if (!ji) + return FALSE; + + g_assert (MONO_ARCH_LMF_REGS == ((0x3ff << 19) | (1 << ARMREG_FP) | (1 << ARMREG_SP))); + memcpy (&new_ctx->regs [ARMREG_R19], &(*lmf)->gregs [0], sizeof (mgreg_t) * 10); + new_ctx->regs [ARMREG_FP] = (*lmf)->gregs [MONO_ARCH_LMF_REG_FP]; + new_ctx->regs [ARMREG_SP] = (*lmf)->gregs [MONO_ARCH_LMF_REG_SP]; + new_ctx->pc = (*lmf)->pc; + + /* we substract 1, so that the IP points into the call instruction */ + new_ctx->pc--; + + *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); + + return TRUE; + } + + return FALSE; +} + +void +mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) +{ + mono_sigctx_to_monoctx (sigctx, mctx); +} + +void +mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) +{ + mono_monoctx_to_sigctx (mctx, sigctx); +} + +/* + * handle_exception: + * + * Called by resuming from a signal handler. + */ +static void +handle_signal_exception (gpointer obj) +{ + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + MonoContext ctx; + + memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext)); + + mono_handle_exception (&ctx, obj); + + mono_restore_context (&ctx); +} + +/* + * This is the function called from the signal handler + */ +gboolean +mono_arch_handle_exception (void *ctx, gpointer obj) +{ +#if defined(MONO_CROSS_COMPILE) + g_assert_not_reached (); +#else + MonoJitTlsData *jit_tls; + void *sigctx = ctx; + + /* + * Resume into the normal stack and handle the exception there. + */ + jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + + /* Pass the ctx parameter in TLS */ + mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx); + /* The others in registers */ + UCONTEXT_REG_R0 (sigctx) = (gsize)obj; + + UCONTEXT_REG_PC (sigctx) = (gsize)handle_signal_exception; + UCONTEXT_REG_SP (sigctx) = UCONTEXT_REG_SP (sigctx) - MONO_ARCH_REDZONE_SIZE; +#endif + + return TRUE; +} + +gpointer +mono_arch_ip_from_context (void *sigctx) +{ +#ifdef MONO_CROSS_COMPILE + g_assert_not_reached (); + return NULL; +#else + return (gpointer)UCONTEXT_REG_PC (sigctx); +#endif +} + +void +mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data) +{ + mgreg_t sp = (mgreg_t)MONO_CONTEXT_GET_SP (ctx); + + // FIXME: + g_assert (!user_data); + + /* Allocate a stack frame */ + sp -= 32; + MONO_CONTEXT_SET_SP (ctx, sp); + + mono_arch_setup_resume_sighandler_ctx (ctx, async_cb); +} + +/* + * mono_arch_setup_resume_sighandler_ctx: + * + * Setup CTX so execution continues at FUNC. + */ +void +mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func) +{ + MONO_CONTEXT_SET_IP (ctx,func); +} diff --git a/mono/mini/exceptions-s390x.c b/mono/mini/exceptions-s390x.c index bfb3fabcda8..fc2390d0b85 100644 --- a/mono/mini/exceptions-s390x.c +++ b/mono/mini/exceptions-s390x.c @@ -13,6 +13,7 @@ /* Dietmar Maurer (dietmar@ximian.com) */ /* */ /* Copyright - 2001 Ximian, Inc. */ +/* Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* */ /*------------------------------------------------------------------*/ diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index dbf89a8d517..6d87c74e92d 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -8,6 +8,7 @@ * (C) 2002 Ximian, Inc. * Copyright 2003-2011 Novell Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/liveness.c b/mono/mini/liveness.c index f26d6597bb5..c8978930740 100644 --- a/mono/mini/liveness.c +++ b/mono/mini/liveness.c @@ -6,6 +6,7 @@ * * (C) 2002 Ximian, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/llvm-jit.cpp b/mono/mini/llvm-jit.cpp index 6a7c49c0629..7fef6b85cb9 100644 --- a/mono/mini/llvm-jit.cpp +++ b/mono/mini/llvm-jit.cpp @@ -4,7 +4,7 @@ // (C) 2009-2011 Novell, Inc. // Copyright 2011-2015 Xamarin, Inc (http://www.xamarin.com) // - +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // // Mono's internal header files are not C++ clean, so avoid including them if // possible diff --git a/mono/mini/local-propagation.c b/mono/mini/local-propagation.c index 2120fa08728..f23c5ff3bb9 100644 --- a/mono/mini/local-propagation.c +++ b/mono/mini/local-propagation.c @@ -10,6 +10,7 @@ * * (C) 2006 Novell, Inc. http://www.novell.com * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 71ed0310656..aed8309edf6 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -8,6 +8,7 @@ * (C) 2002 Ximian, Inc. * Copyright 2003-2010 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/mini-amd64-gsharedvt.c b/mono/mini/mini-amd64-gsharedvt.c new file mode 100644 index 00000000000..c3e2e99bc86 --- /dev/null +++ b/mono/mini/mini-amd64-gsharedvt.c @@ -0,0 +1,478 @@ +/* + * mini-amd64-gsharedvt.c: libcorkscrew-based native unwinder + * + * Authors: + * Zoltan Varga + * Rodrigo Kumpera + * Andi McClure + * + * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mini.h" +#include "mini-amd64.h" +#include "mini-amd64-gsharedvt.h" +#include "debugger-agent.h" + +#if defined (MONO_ARCH_GSHAREDVT_SUPPORTED) + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +gboolean +mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig) +{ + return FALSE; +} + +static const char* +storage_name (ArgStorage st) +{ + switch (st) { + case ArgInIReg: return "ArgInIReg"; + case ArgInFloatSSEReg: return "ArgInFloatSSEReg"; + case ArgInDoubleSSEReg: return "ArgInDoubleSSEReg"; + case ArgOnStack: return "ArgOnStack"; + case ArgValuetypeInReg: return "ArgValuetypeInReg"; + case ArgValuetypeAddrInIReg: return "ArgValuetypeAddrInIReg"; + case ArgGSharedVtInReg: return "ArgGSharedVtInReg"; + case ArgGSharedVtOnStack: return "ArgGSharedVtOnStack"; + case ArgNone: return "ArgNone"; + default: return "unknown"; + } +} + +static char * +arg_info_desc (ArgInfo *info) +{ + GString *str = g_string_new (""); + + g_string_append_printf (str, "offset %d reg %s storage %s nregs %d", info->offset, mono_arch_regname (info->reg), storage_name (info->storage), info->nregs); + if (info->storage == ArgValuetypeInReg) + g_string_append_printf (str, " {(%s %s), (%s %s)", + storage_name (info->pair_storage [0]), + mono_arch_regname (info->pair_regs [0]), + storage_name (info->pair_storage [1]), + mono_arch_regname (info->pair_regs [1])); + + return g_string_free (str, FALSE); +} + +static inline void +add_to_map (GPtrArray *map, int src, int dst) +{ + g_ptr_array_add (map, GUINT_TO_POINTER (src)); + g_ptr_array_add (map, GUINT_TO_POINTER (dst)); +} + +/* + * Slot mapping: + * 0..5 - rdi, rsi, rdx, rcx, r8, r9 + * 6..13 - xmm0..xmm7 + * 14.. - stack slots + */ +static inline int +map_reg (int reg) +{ + int i = 0; + for (i = 0; i < PARAM_REGS; ++i) { + if (param_regs [i] == reg) + return i; + } + g_error ("Invalid argument register number %d", reg); + return -1; +} + +static inline int +map_freg (int reg) +{ + return reg + PARAM_REGS; +} + +static inline int +map_stack_slot (int slot) +{ + return slot + PARAM_REGS + FLOAT_PARAM_REGS; +} + +/* +Format for the source descriptor: + + +Format for the destination descriptor: + bits 0:15 - source register + bits 16:23 - return marshal + bits 24:32 - slot count +*/ +#define SRC_DESCRIPTOR_MARSHAL_SHIFT 16 +#define SRC_DESCRIPTOR_MARSHAL_MASK 0x0Ff + +#define SLOT_COUNT_SHIFT 24 +#define SLOT_COUNT_MASK 0xff +#define SLOT_BYTE_SIZE 8 + +static int +get_arg_slots (ArgInfo *ainfo, int **out_slots, gboolean is_source_argument) +{ + int sreg = ainfo->reg; + int sslot = ainfo->offset / 8; + int *src = NULL; + int i, nsrc; + + switch (ainfo->storage) { + case ArgInIReg: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_reg (sreg); + break; + case ArgValuetypeInReg: + nsrc = ainfo->nregs; + src = g_malloc (nsrc * sizeof (int)); + for (i = 0; i < ainfo->nregs; ++i) + src [i] = map_reg (ainfo->pair_regs [i]); + break; + case ArgOnStack: + nsrc = ainfo->arg_size / SLOT_BYTE_SIZE; + src = g_malloc (nsrc * sizeof (int)); + // is_source_argument adds 2 because we're skipping over the old BBP and the return address + // XXX this is a very fragile setup as changes in alignment for the caller reg array can cause the magic number be 3 + for (i = 0; i < nsrc; ++i) + src [i] = map_stack_slot (sslot + i + (is_source_argument ? 2 : 0)); + break; + case ArgInDoubleSSEReg: + case ArgInFloatSSEReg: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_freg (sreg); + break; + default: + NOT_IMPLEMENTED; + break; + } + + *out_slots = src; + return nsrc; +} + +// Once src is known, operate on the dst +static void +handle_marshal_when_src_gsharedvt (ArgInfo *dst_info, int *arg_marshal, int *arg_slots) +{ + switch (dst_info->storage) { + case ArgInIReg: + case ArgInDoubleSSEReg: + case ArgInFloatSSEReg: + *arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL; + *arg_slots = 1; + break; + case ArgOnStack: + *arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL; + g_assert (dst_info->arg_size % SLOT_BYTE_SIZE == 0); // Assert quadword aligned + *arg_slots = dst_info->arg_size / SLOT_BYTE_SIZE; + break; + case ArgValuetypeInReg: + *arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL; + *arg_slots = dst_info->nregs; + break; + default: + NOT_IMPLEMENTED; // Inappropriate value: if dst and src are gsharedvt at once, we shouldn't be here + break; + } +} + +// Once dst is known, operate on the src +static void +handle_marshal_when_dst_gsharedvt (ArgInfo *src_info, int *arg_marshal) +{ + switch (src_info->storage) { + case ArgInIReg: + case ArgInDoubleSSEReg: + case ArgInFloatSSEReg: + case ArgValuetypeInReg: + case ArgOnStack: + *arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF; + break; + default: + NOT_IMPLEMENTED; // See above + break; + } +} + +static void +handle_map_when_gsharedvt_in_reg (ArgInfo *reg_info, int *n, int **map) +{ + *n = 1; + *map = g_new0 (int, 1); + (*map) [0] = map_reg (reg_info->reg); +} + +static void +handle_map_when_gsharedvt_on_stack (ArgInfo *reg_info, int *n, int **map, gboolean is_source_argument) +{ + *n = 1; + *map = g_new0 (int, 1); + int sslot = reg_info->offset / SLOT_BYTE_SIZE; + (*map) [0] = map_stack_slot (sslot + (is_source_argument ? 2 : 0)); // see get_arg_slots +} + +gpointer +mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) +{ + GSharedVtCallInfo *info; + CallInfo *caller_cinfo, *callee_cinfo; + MonoMethodSignature *caller_sig, *callee_sig; + int aindex, i; + gboolean var_ret = FALSE; + CallInfo *cinfo, *gcinfo; + MonoMethodSignature *sig, *gsig; + GPtrArray *map; + + if (gsharedvt_in) { + caller_sig = normal_sig; + callee_sig = gsharedvt_sig; + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + } else { + callee_sig = normal_sig; + caller_sig = gsharedvt_sig; + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + } + + /* + * If GSHAREDVT_IN is true, this means we are transitioning from normal to gsharedvt code. The caller uses the + * normal call signature, while the callee uses the gsharedvt signature. + * If GSHAREDVT_IN is false, its the other way around. + */ + + /* sig/cinfo describes the normal call, while gsig/gcinfo describes the gsharedvt call */ + if (gsharedvt_in) { + sig = caller_sig; + gsig = callee_sig; + cinfo = caller_cinfo; + gcinfo = callee_cinfo; + } else { + sig = callee_sig; + gsig = caller_sig; + cinfo = callee_cinfo; + gcinfo = caller_cinfo; + } + + DEBUG_AMD64_GSHAREDVT_PRINT ("source sig: (%s) return (%s)\n", mono_signature_get_desc (caller_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (caller_sig))); // Leak + DEBUG_AMD64_GSHAREDVT_PRINT ("dest sig: (%s) return (%s)\n", mono_signature_get_desc (callee_sig, FALSE), mono_type_full_name (mono_signature_get_return_type (callee_sig))); + + if (gcinfo->ret.is_gsharedvt_return_value) { + /* + * The return type is gsharedvt + */ + var_ret = TRUE; + } + + /* + * The stack looks like this: + * + * + * + * We have to map the stack slots in to the stack slots in . + */ + map = g_ptr_array_new (); + + for (aindex = 0; aindex < cinfo->nargs; ++aindex) { + ArgInfo *src_info = &caller_cinfo->args [aindex]; + ArgInfo *dst_info = &callee_cinfo->args [aindex]; + int *src = NULL, *dst = NULL; + int nsrc = -1, ndst = -1, nslots = 0; + + int arg_marshal = GSHAREDVT_ARG_NONE; + int arg_slots = 0; // Size in quadwords + DEBUG_AMD64_GSHAREDVT_PRINT ("-- arg %d in (%s) out (%s)\n", aindex, arg_info_desc (src_info), arg_info_desc (dst_info)); + + switch (src_info->storage) { + case ArgInIReg: + case ArgInDoubleSSEReg: + case ArgInFloatSSEReg: + case ArgValuetypeInReg: + case ArgOnStack: + nsrc = get_arg_slots (src_info, &src, TRUE); + break; + case ArgGSharedVtInReg: + handle_marshal_when_src_gsharedvt (dst_info, &arg_marshal, &arg_slots); + handle_map_when_gsharedvt_in_reg (src_info, &nsrc, &src); + break; + case ArgGSharedVtOnStack: + handle_marshal_when_src_gsharedvt (dst_info, &arg_marshal, &arg_slots); + handle_map_when_gsharedvt_on_stack (src_info, &nsrc, &src, TRUE); + break; + default: + g_error ("Gsharedvt can't handle source arg type %d", (int)src_info->storage); // Inappropriate value: ArgValuetypeAddrInIReg is for returns only + } + + switch (dst_info->storage) { + case ArgInIReg: + case ArgInDoubleSSEReg: + case ArgInFloatSSEReg: + case ArgOnStack: + case ArgValuetypeInReg: + ndst = get_arg_slots (dst_info, &dst, FALSE); + break; + case ArgGSharedVtInReg: + handle_marshal_when_dst_gsharedvt (src_info, &arg_marshal); + handle_map_when_gsharedvt_in_reg (dst_info, &ndst, &dst); + break; + case ArgGSharedVtOnStack: + handle_marshal_when_dst_gsharedvt (src_info, &arg_marshal); + handle_map_when_gsharedvt_on_stack (dst_info, &ndst, &dst, FALSE); + break; + default: + g_error ("Gsharedvt can't handle dest arg type %d", (int)dst_info->storage); // See above + } + if (nsrc) + src [0] |= (arg_marshal << SRC_DESCRIPTOR_MARSHAL_SHIFT) | (arg_slots << SLOT_COUNT_SHIFT); + + /* Merge and add to the global list*/ + nslots = MIN (nsrc, ndst); + DEBUG_AMD64_GSHAREDVT_PRINT ("nsrc %d ndst %d\n", nsrc, ndst); + + for (i = 0; i < nslots; ++i) + add_to_map (map, src [i], dst [i]); + + g_free (src); + g_free (dst); + } + + DEBUG_AMD64_GSHAREDVT_PRINT ("-- return in (%s) out (%s) var_ret %d\n", arg_info_desc (&caller_cinfo->ret), arg_info_desc (&callee_cinfo->ret), var_ret); + + if (cinfo->ret.storage == ArgValuetypeAddrInIReg) { + /* Both the caller and the callee pass the vtype ret address in r8 */ + g_assert (cinfo->ret.storage == gcinfo->ret.storage); + add_to_map (map, map_reg (cinfo->ret.reg), map_reg (cinfo->ret.reg)); + } + + info = mono_domain_alloc0 (mono_domain_get (), sizeof (GSharedVtCallInfo) + (map->len * sizeof (int))); + info->addr = addr; + info->stack_usage = callee_cinfo->stack_usage; + info->ret_marshal = GSHAREDVT_RET_NONE; + info->gsharedvt_in = gsharedvt_in ? 1 : 0; + info->vret_slot = -1; + info->calli = calli; + + if (var_ret) { + g_assert (gcinfo->ret.is_gsharedvt_return_value); + info->vret_arg_reg = map_reg (gcinfo->ret.reg); + DEBUG_AMD64_GSHAREDVT_PRINT ("mapping vreg_arg_reg to %d in reg %s\n", info->vret_arg_reg, mono_arch_regname (gcinfo->ret.reg)); + } else { + info->vret_arg_reg = -1; + } + +#ifdef DEBUG_AMD64_GSHAREDVT + printf ("final map:\n"); + for (i = 0; i < map->len; i += 2) { + printf ("\t[%d] src %x dst %x\n ", + i / 2, + GPOINTER_TO_UINT (g_ptr_array_index (map, i)), + GPOINTER_TO_UINT (g_ptr_array_index (map, i + 1))); + } +#endif + + info->vcall_offset = vcall_offset; + info->map_count = map->len / 2; + for (i = 0; i < map->len; ++i) + info->map [i] = GPOINTER_TO_UINT (g_ptr_array_index (map, i)); + g_ptr_array_free (map, TRUE); + + /* Compute return value marshalling */ + if (var_ret) { + /* Compute return value marshalling */ + switch (cinfo->ret.storage) { + case ArgInIReg: + if (!gsharedvt_in || sig->ret->byref) { + info->ret_marshal = GSHAREDVT_RET_IREGS_1; + } else { + MonoType *ret = sig->ret; + + // Unwrap enums + if (ret->type == MONO_TYPE_VALUETYPE) + ret = mini_type_get_underlying_type (ret); + + switch (ret->type) { + case MONO_TYPE_I1: + info->ret_marshal = GSHAREDVT_RET_I1; + break; + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_U1: + info->ret_marshal = GSHAREDVT_RET_U1; + break; + case MONO_TYPE_I2: + info->ret_marshal = GSHAREDVT_RET_I2; + break; + case MONO_TYPE_CHAR: + case MONO_TYPE_U2: + info->ret_marshal = GSHAREDVT_RET_U2; + break; + case MONO_TYPE_I4: + info->ret_marshal = GSHAREDVT_RET_I4; + break; + case MONO_TYPE_U4: + info->ret_marshal = GSHAREDVT_RET_U4; + break; + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_PTR: + case MONO_TYPE_FNPTR: + case MONO_TYPE_CLASS: + case MONO_TYPE_OBJECT: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_ARRAY: + case MONO_TYPE_STRING: + case MONO_TYPE_U8: + case MONO_TYPE_I8: + info->ret_marshal = GSHAREDVT_RET_I8; + break; + + default: + g_error ("Gsharedvt can't handle dst type [%d]", (int)sig->ret->type); + } + } + break; + case ArgValuetypeInReg: + info->ret_marshal = GSHAREDVT_RET_IREGS_1 - 1 + cinfo->ret.nregs; + g_assert (cinfo->ret.nregs == 1); // ABI supports 2-register return but we do not implement this. + break; + case ArgInDoubleSSEReg: + case ArgInFloatSSEReg: + info->ret_marshal = GSHAREDVT_RET_R8; + break; + case ArgValuetypeAddrInIReg: + break; + default: + g_error ("Can't marshal return of storage [%d] %s", (int)cinfo->ret.storage, storage_name (cinfo->ret.storage)); + } + + if (gsharedvt_in && cinfo->ret.storage != ArgValuetypeAddrInIReg) { + /* Allocate stack space for the return value */ + info->vret_slot = map_stack_slot (info->stack_usage / sizeof (gpointer)); + info->stack_usage += mono_type_stack_size_internal (normal_sig->ret, NULL, FALSE) + sizeof (gpointer); + } + DEBUG_AMD64_GSHAREDVT_PRINT ("RET marshal is %s\n", ret_marshal_name [info->ret_marshal]); + } + + info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + + DEBUG_AMD64_GSHAREDVT_PRINT ("allocated an info at %p stack usage %d\n", info, info->stack_usage); + return info; +} + +#endif \ No newline at end of file diff --git a/mono/mini/mini-amd64-gsharedvt.h b/mono/mini/mini-amd64-gsharedvt.h new file mode 100644 index 00000000000..3e3d56c54f2 --- /dev/null +++ b/mono/mini/mini-amd64-gsharedvt.h @@ -0,0 +1,55 @@ +/* + * mini-exceptions-native-unwinder.c: libcorkscrew-based native unwinder + * + * Authors: + * Zoltan Varga + * Rodrigo Kumpera + * Andi McClure + * + * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#ifndef MINI_AMD64_GSHAREDVT_H +#define MINI_AMD64_GSHAREDVT_H + +typedef enum { + GSHAREDVT_ARG_NONE = 0, + GSHAREDVT_ARG_BYVAL_TO_BYREF, + GSHAREDVT_ARG_BYREF_TO_BYVAL, +} GSharedVtArgMarshal; + +typedef enum { + GSHAREDVT_RET_NONE = 0, + GSHAREDVT_RET_I1, // 1 byte integer + GSHAREDVT_RET_U1, // 1 byte unsigned + GSHAREDVT_RET_I2, // 2 byte integer + GSHAREDVT_RET_U2, // 2 byte unsigned + GSHAREDVT_RET_I4, // 4 byte integer + GSHAREDVT_RET_U4, // 4 byte unsigned + GSHAREDVT_RET_I8, // 8 byte integer + GSHAREDVT_RET_IREGS_1, // Load in first return register + GSHAREDVT_RET_R8, // Double + GSHAREDVT_RET_NUM, +} GSharedVtRetMarshal; + +static const char* ret_marshal_name[] = { + "GSHAREDVT_RET_NONE", + "GSHAREDVT_RET_I1", + "GSHAREDVT_RET_U1", + "GSHAREDVT_RET_I2", + "GSHAREDVT_RET_U2", + "GSHAREDVT_RET_I4", + "GSHAREDVT_RET_U4", + "GSHAREDVT_RET_I8", + "GSHAREDVT_RET_IREGS_1", + "GSHAREDVT_RET_R8", + "GSHAREDVT_RET_NUM", +}; + +#ifdef DEBUG_AMD64_GSHAREDVT +#define DEBUG_AMD64_GSHAREDVT_PRINT printf +#else +#define DEBUG_AMD64_GSHAREDVT_PRINT(...) +#endif + +#endif /* MINI_AMD64_GSHAREDVT_H */ \ No newline at end of file diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index b1cdaaf8dfe..18e48283d95 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -12,6 +12,7 @@ * (C) 2003 Ximian, Inc. * Copyright 2003-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" #include @@ -479,48 +480,6 @@ mono_amd64_patch (unsigned char* code, gpointer target) amd64_patch (code, target); } -typedef enum { - ArgInIReg, - ArgInFloatSSEReg, - ArgInDoubleSSEReg, - ArgOnStack, - ArgValuetypeInReg, - ArgValuetypeAddrInIReg, - /* gsharedvt argument passed by addr */ - ArgGSharedVtInReg, - ArgGSharedVtOnStack, - ArgNone /* only in pair_storage */ -} ArgStorage; - -typedef struct { - gint16 offset; - gint8 reg; - ArgStorage storage : 8; - gboolean is_gsharedvt_return_value : 1; - - /* Only if storage == ArgValuetypeInReg */ - ArgStorage pair_storage [2]; - gint8 pair_regs [2]; - /* The size of each pair (bytes) */ - int pair_size [2]; - int nregs; - /* Only if storage == ArgOnStack */ - int arg_size; // Bytes, will always be rounded up/aligned to 8 byte boundary -} ArgInfo; - -typedef struct { - int nargs; - guint32 stack_usage; - guint32 reg_usage; - guint32 freg_usage; - gboolean need_stack_align; - /* The index of the vret arg in the argument list */ - int vret_arg_index; - ArgInfo ret; - ArgInfo sig_cookie; - ArgInfo args [1]; -} CallInfo; - #define DEBUG(a) if (cfg->verbose_level > 1) a static void inline @@ -1465,7 +1424,7 @@ mono_arch_init (void) mono_aot_register_jit_icall ("mono_amd64_throw_corlib_exception", mono_amd64_throw_corlib_exception); mono_aot_register_jit_icall ("mono_amd64_resume_unwind", mono_amd64_resume_unwind); mono_aot_register_jit_icall ("mono_amd64_get_original_ip", mono_amd64_get_original_ip); -#if defined(ENABLE_GSHAREDVT) +#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) mono_aot_register_jit_icall ("mono_amd64_start_gsharedvt_call", mono_amd64_start_gsharedvt_call); #endif @@ -8845,8 +8804,8 @@ mono_arch_opcode_supported (int opcode) } } -#if defined(ENABLE_GSHAREDVT) && defined(MONO_ARCH_GSHAREDVT_SUPPORTED) - -#include "../../../mono-extensions/mono/mini/mini-amd64-gsharedvt.c" - -#endif /* !ENABLE_GSHAREDVT */ +CallInfo* +mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) +{ + return get_call_info (mp, sig); +} diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h index 343a42f8d99..c22c9be0fd0 100644 --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -265,6 +265,49 @@ typedef struct { guint8 buffer [256]; } DynCallArgs; +typedef enum { + ArgInIReg, + ArgInFloatSSEReg, + ArgInDoubleSSEReg, + ArgOnStack, + ArgValuetypeInReg, + ArgValuetypeAddrInIReg, + /* gsharedvt argument passed by addr */ + ArgGSharedVtInReg, + ArgGSharedVtOnStack, + ArgNone /* only in pair_storage */ +} ArgStorage; + +typedef struct { + gint16 offset; + gint8 reg; + ArgStorage storage : 8; + gboolean is_gsharedvt_return_value : 1; + + /* Only if storage == ArgValuetypeInReg */ + ArgStorage pair_storage [2]; + gint8 pair_regs [2]; + /* The size of each pair (bytes) */ + int pair_size [2]; + int nregs; + /* Only if storage == ArgOnStack */ + int arg_size; // Bytes, will always be rounded up/aligned to 8 byte boundary +} ArgInfo; + +typedef struct { + int nargs; + guint32 stack_usage; + guint32 reg_usage; + guint32 freg_usage; + gboolean need_stack_align; + /* The index of the vret arg in the argument list */ + int vret_arg_index; + ArgInfo ret; + ArgInfo sig_cookie; + ArgInfo args [1]; +} CallInfo; + + #define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->gregs [AMD64_RAX] = (gsize)exc; } while (0) #define MONO_CONTEXT_SET_LLVM_EH_SELECTOR_REG(ctx, sel) do { (ctx)->gregs [AMD64_RDX] = (gsize)(sel); } while (0) @@ -379,7 +422,6 @@ typedef struct { #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1 #define MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK 1 -#define MONO_ARCH_GSHAREDVT_SUPPORTED 1 #define MONO_ARCH_HAVE_OP_TAIL_CALL 1 #define MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET 1 #define MONO_ARCH_HAVE_DUMMY_INIT 1 @@ -395,6 +437,11 @@ typedef struct { #define MONO_ARCH_HAVE_TLS_GET_REG 1 #endif +#if !defined (TARGET_WIN32) +#define MONO_ARCH_GSHAREDVT_SUPPORTED 1 +#endif + + #if defined(TARGET_APPLETVOS) /* No signals */ #define MONO_ARCH_NEED_DIV_CHECK 1 @@ -460,5 +507,7 @@ void mono_arch_unwindinfo_install_unwind_info (gpointer* monoui, gpointer code, #define MONO_ARCH_HAVE_UNWIND_TABLE 1 #endif +CallInfo* mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig); + #endif /* __MONO_MINI_AMD64_H__ */ diff --git a/mono/mini/mini-arm-gsharedvt.c b/mono/mini/mini-arm-gsharedvt.c new file mode 100644 index 00000000000..aef522b2856 --- /dev/null +++ b/mono/mini/mini-arm-gsharedvt.c @@ -0,0 +1,329 @@ +/* + * mini-arm-gsharedvt.c: gsharedvt support code for arm + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mini.h" +#include "mini-arm.h" + +#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +/* + * GSHAREDVT + */ + +gboolean +mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig) +{ + /* + if (sig->ret && is_variable_size (sig->ret)) + return FALSE; + */ + return TRUE; +} + +static inline void +add_to_map (GPtrArray *map, int src, int dst) +{ + g_ptr_array_add (map, GUINT_TO_POINTER (src)); + g_ptr_array_add (map, GUINT_TO_POINTER (dst)); +} + +static inline int +map_reg (int reg) +{ + return reg; +} + +static inline int +map_stack_slot (int slot) +{ + return slot + 4; +} + +static int +get_arg_slots (ArgInfo *ainfo, int **out_slots) +{ + int sreg = ainfo->reg; + int sslot = ainfo->offset / 4; + int *src = NULL; + int i, nsrc; + + switch (ainfo->storage) { + case RegTypeGeneral: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_reg (sreg); + break; + case RegTypeIRegPair: + nsrc = 2; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_reg (sreg); + src [1] = map_reg (sreg + 1); + break; + case RegTypeStructByVal: + nsrc = ainfo->struct_size / 4; + src = g_malloc (nsrc * sizeof (int)); + g_assert (ainfo->size <= nsrc); + for (i = 0; i < ainfo->size; ++i) + src [i] = map_reg (sreg + i); + for (i = ainfo->size; i < nsrc; ++i) + src [i] = map_stack_slot (sslot + (i - ainfo->size)); + break; + case RegTypeBase: + nsrc = ainfo->size / 4; + src = g_malloc (nsrc * sizeof (int)); + for (i = 0; i < nsrc; ++i) + src [i] = map_stack_slot (sslot + i); + break; + case RegTypeBaseGen: + nsrc = 2; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_reg (ARMREG_R3); + src [1] = map_stack_slot (sslot); + break; + default: + g_assert_not_reached (); + break; + } + + *out_slots = src; + return nsrc; +} + +/* + * mono_arch_get_gsharedvt_call_info: + * + * See mini-x86.c for documentation. + */ +gpointer +mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) +{ + GSharedVtCallInfo *info; + CallInfo *caller_cinfo, *callee_cinfo; + MonoMethodSignature *caller_sig, *callee_sig; + int aindex, i; + gboolean var_ret = FALSE; + CallInfo *cinfo, *gcinfo; + MonoMethodSignature *sig, *gsig; + GPtrArray *map; + + if (gsharedvt_in) { + caller_sig = normal_sig; + callee_sig = gsharedvt_sig; + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + } else { + callee_sig = normal_sig; + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + caller_sig = gsharedvt_sig; + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + } + + /* + * If GSHAREDVT_IN is true, this means we are transitioning from normal to gsharedvt code. The caller uses the + * normal call signature, while the callee uses the gsharedvt signature. + * If GSHAREDVT_IN is false, its the other way around. + */ + + /* sig/cinfo describes the normal call, while gsig/gcinfo describes the gsharedvt call */ + if (gsharedvt_in) { + sig = caller_sig; + gsig = callee_sig; + cinfo = caller_cinfo; + gcinfo = callee_cinfo; + } else { + sig = callee_sig; + gsig = caller_sig; + cinfo = callee_cinfo; + gcinfo = caller_cinfo; + } + + if (gcinfo->ret.storage == RegTypeStructByAddr && gsig->ret && mini_is_gsharedvt_type (gsig->ret)) { + /* + * The return type is gsharedvt + */ + var_ret = TRUE; + } + + /* + * The stack looks like this: + * + * + * + * + * We have to map the stack slots in to the stack slots in . + * The argument registers are mapped to slot 0..3, stack slot 0 is mapped to slot 4, etc. + */ + map = g_ptr_array_new (); + + if (cinfo->ret.storage == RegTypeStructByAddr) { + /* + * Map ret arg. + * This handles the case when the method returns a normal vtype, and when it returns a type arg, and its instantiated + * with a vtype. + */ + g_assert (caller_cinfo->ret.storage == RegTypeStructByAddr); + g_assert (callee_cinfo->ret.storage == RegTypeStructByAddr); + add_to_map (map, map_reg (caller_cinfo->ret.reg), map_reg (callee_cinfo->ret.reg)); + } + + for (aindex = 0; aindex < cinfo->nargs; ++aindex) { + ArgInfo *ainfo = &caller_cinfo->args [aindex]; + ArgInfo *ainfo2 = &callee_cinfo->args [aindex]; + int *src = NULL, *dst = NULL; + int nsrc, ndst, nslots, src_slot, arg_marshal; + + /* + * The src descriptor looks like this: + * - 4 bits src slot + * - 12 bits number of slots + * - 8 bits marshal type (GSHAREDVT_ARG_...) + */ + + arg_marshal = GSHAREDVT_ARG_NONE; + + if (ainfo->storage == RegTypeGSharedVtInReg || ainfo->storage == RegTypeGSharedVtOnStack) { + /* Pass the value whose address is received in a reg by value */ + g_assert (ainfo2->storage != RegTypeGSharedVtInReg); + ndst = get_arg_slots (ainfo2, &dst); + nsrc = 1; + src = g_new0 (int, 1); + if (ainfo->storage == RegTypeGSharedVtInReg) + src_slot = map_reg (ainfo->reg); + else + src_slot = map_stack_slot (ainfo->offset / 4); + g_assert (ndst < 256); + g_assert (src_slot < 16); + src [0] = (ndst << 4) | src_slot; + + if (ainfo2->storage == RegTypeGeneral && ainfo2->size != 0 && ainfo2->size != 4) { + /* Have to load less than 4 bytes */ + // FIXME: Signed types + switch (ainfo2->size) { + case 1: + arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL_U1; + break; + case 2: + arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL_U2; + break; + default: + g_assert_not_reached (); + break; + } + } else { + arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL; + } + } else { + nsrc = get_arg_slots (ainfo, &src); + } + if (ainfo2->storage == RegTypeGSharedVtInReg) { + /* Pass the address of the first src slot in a reg */ + arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF; + ndst = 1; + dst = g_new0 (int, 1); + dst [0] = map_reg (ainfo2->reg); + } else if (ainfo2->storage == RegTypeGSharedVtOnStack) { + /* Pass the address of the first src slot in a stack slot */ + arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF; + ndst = 1; + dst = g_new0 (int, 1); + dst [0] = map_stack_slot (ainfo2->offset / 4); + } else { + ndst = get_arg_slots (ainfo2, &dst); + } + if (nsrc) + src [0] |= (arg_marshal << 16); + nslots = MIN (nsrc, ndst); + + for (i = 0; i < nslots; ++i) + add_to_map (map, src [i], dst [i]); + + g_free (src); + g_free (dst); + } + + info = mono_domain_alloc0 (mono_domain_get (), sizeof (GSharedVtCallInfo) + (map->len * sizeof (int))); + info->addr = addr; + info->stack_usage = callee_cinfo->stack_usage; + info->ret_marshal = GSHAREDVT_RET_NONE; + info->gsharedvt_in = gsharedvt_in ? 1 : 0; + info->vret_slot = -1; + info->calli = calli; + if (var_ret) { + g_assert (gcinfo->ret.storage == RegTypeStructByAddr); + info->vret_arg_reg = gcinfo->ret.reg; + } else { + info->vret_arg_reg = -1; + } + info->vcall_offset = vcall_offset; + info->map_count = map->len / 2; + for (i = 0; i < map->len; ++i) + info->map [i] = GPOINTER_TO_UINT (g_ptr_array_index (map, i)); + g_ptr_array_free (map, TRUE); + + /* Compute return value marshalling */ + if (var_ret) { + switch (cinfo->ret.storage) { + case RegTypeGeneral: + if (gsharedvt_in && !sig->ret->byref && sig->ret->type == MONO_TYPE_I1) + info->ret_marshal = GSHAREDVT_RET_I1; + else if (gsharedvt_in && !sig->ret->byref && (sig->ret->type == MONO_TYPE_U1 || sig->ret->type == MONO_TYPE_BOOLEAN)) + info->ret_marshal = GSHAREDVT_RET_U1; + else if (gsharedvt_in && !sig->ret->byref && sig->ret->type == MONO_TYPE_I2) + info->ret_marshal = GSHAREDVT_RET_I2; + else if (gsharedvt_in && !sig->ret->byref && (sig->ret->type == MONO_TYPE_U2 || sig->ret->type == MONO_TYPE_CHAR)) + info->ret_marshal = GSHAREDVT_RET_U2; + else + info->ret_marshal = GSHAREDVT_RET_IREG; + break; + case RegTypeIRegPair: + info->ret_marshal = GSHAREDVT_RET_IREGS; + break; + case RegTypeFP: + // FIXME: VFP + if (cinfo->ret.size == 4) + info->ret_marshal = GSHAREDVT_RET_IREG; + else + info->ret_marshal = GSHAREDVT_RET_IREGS; + break; + case RegTypeStructByAddr: + info->ret_marshal = GSHAREDVT_RET_NONE; + break; + default: + g_assert_not_reached (); + } + } + + if (gsharedvt_in && var_ret && caller_cinfo->ret.storage != RegTypeStructByAddr) { + /* Allocate stack space for the return value */ + info->vret_slot = map_stack_slot (info->stack_usage / sizeof (gpointer)); + info->stack_usage += mono_type_stack_size_internal (normal_sig->ret, NULL, FALSE) + sizeof (gpointer); + } + + info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + + g_free (caller_cinfo); + g_free (callee_cinfo); + + return info; +} + +#endif \ No newline at end of file diff --git a/mono/mini/mini-arm-tls.S b/mono/mini/mini-arm-tls.S index 63096e7439f..47a6dbb5ba2 100644 --- a/mono/mini/mini-arm-tls.S +++ b/mono/mini/mini-arm-tls.S @@ -2,6 +2,7 @@ * mini-arm-tls.S: tls getters and setters for arm platforms * * Copyright 2015 Xamarin, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index a7df6fc1c1b..86d4e123919 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -8,6 +8,7 @@ * (C) 2003 Ximian, Inc. * Copyright 2003-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" #include @@ -903,7 +904,7 @@ mono_arch_init (void) mono_aot_register_jit_icall ("mono_arm_throw_exception", mono_arm_throw_exception); mono_aot_register_jit_icall ("mono_arm_throw_exception_by_token", mono_arm_throw_exception_by_token); mono_aot_register_jit_icall ("mono_arm_resume_unwind", mono_arm_resume_unwind); -#if defined(ENABLE_GSHAREDVT) +#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) mono_aot_register_jit_icall ("mono_arm_start_gsharedvt_call", mono_arm_start_gsharedvt_call); #endif mono_aot_register_jit_icall ("mono_arm_unaligned_stack", mono_arm_unaligned_stack); @@ -1159,50 +1160,6 @@ mono_arch_flush_icache (guint8 *code, gint size) #endif } -typedef enum { - RegTypeNone, - /* Passed/returned in an ireg */ - RegTypeGeneral, - /* Passed/returned in a pair of iregs */ - RegTypeIRegPair, - /* Passed on the stack */ - RegTypeBase, - /* First word in r3, second word on the stack */ - RegTypeBaseGen, - /* FP value passed in either an ireg or a vfp reg */ - RegTypeFP, - RegTypeStructByVal, - RegTypeStructByAddr, - /* gsharedvt argument passed by addr in greg */ - RegTypeGSharedVtInReg, - /* gsharedvt argument passed by addr on stack */ - RegTypeGSharedVtOnStack, - RegTypeHFA -} ArgStorage; - -typedef struct { - gint32 offset; - guint16 vtsize; /* in param area */ - /* RegTypeHFA */ - int esize; - /* RegTypeHFA */ - int nregs; - guint8 reg; - ArgStorage storage; - gint32 struct_size; - guint8 size : 4; /* 1, 2, 4, 8, or regs used by RegTypeStructByVal */ -} ArgInfo; - -typedef struct { - int nargs; - guint32 stack_usage; - /* The index of the vret arg in the argument list for RegTypeStructByAddr */ - int vret_arg_index; - ArgInfo ret; - ArgInfo sig_cookie; - ArgInfo args [1]; -} CallInfo; - #define DEBUG(a) static void inline @@ -7664,8 +7621,8 @@ mono_arch_opcode_supported (int opcode) } } -#if defined(ENABLE_GSHAREDVT) - -#include "../../../mono-extensions/mono/mini/mini-arm-gsharedvt.c" - -#endif /* !MONOTOUCH */ +CallInfo* +mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) +{ + return get_call_info (mp, sig); +} diff --git a/mono/mini/mini-arm.h b/mono/mini/mini-arm.h index b09db53452a..bcd922f522b 100644 --- a/mono/mini/mini-arm.h +++ b/mono/mini/mini-arm.h @@ -1,5 +1,6 @@ /* * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_MINI_ARM_H__ @@ -174,6 +175,51 @@ typedef struct { int map [MONO_ZERO_LEN_ARRAY]; } GSharedVtCallInfo; + +typedef enum { + RegTypeNone, + /* Passed/returned in an ireg */ + RegTypeGeneral, + /* Passed/returned in a pair of iregs */ + RegTypeIRegPair, + /* Passed on the stack */ + RegTypeBase, + /* First word in r3, second word on the stack */ + RegTypeBaseGen, + /* FP value passed in either an ireg or a vfp reg */ + RegTypeFP, + RegTypeStructByVal, + RegTypeStructByAddr, + /* gsharedvt argument passed by addr in greg */ + RegTypeGSharedVtInReg, + /* gsharedvt argument passed by addr on stack */ + RegTypeGSharedVtOnStack, + RegTypeHFA +} ArgStorage; + +typedef struct { + gint32 offset; + guint16 vtsize; /* in param area */ + /* RegTypeHFA */ + int esize; + /* RegTypeHFA */ + int nregs; + guint8 reg; + ArgStorage storage; + gint32 struct_size; + guint8 size : 4; /* 1, 2, 4, 8, or regs used by RegTypeStructByVal */ +} ArgInfo; + +typedef struct { + int nargs; + guint32 stack_usage; + /* The index of the vret arg in the argument list for RegTypeStructByAddr */ + int vret_arg_index; + ArgInfo ret; + ArgInfo sig_cookie; + ArgInfo args [1]; +} CallInfo; + /* Structure used by the sequence points in AOTed code */ typedef struct { gpointer ss_trigger_page; @@ -366,4 +412,7 @@ mono_arm_have_tls_get (void); void mono_arm_unaligned_stack (MonoMethod *method); +CallInfo* +mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig); + #endif /* __MONO_MINI_ARM_H__ */ diff --git a/mono/mini/mini-arm64-gsharedvt.c b/mono/mini/mini-arm64-gsharedvt.c new file mode 100644 index 00000000000..3d9664b56bf --- /dev/null +++ b/mono/mini/mini-arm64-gsharedvt.c @@ -0,0 +1,418 @@ +/* + * mini-arm64-gsharedvt.c: gsharedvt support code for arm64 + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include "mini.h" +#include "mini-arm64.h" +#include "mini-arm64-gsharedvt.h" + +/* + * GSHAREDVT + */ +#ifdef MONO_ARCH_GSHARED_SUPPORTED + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +void +mono_arm_gsharedvt_init (void) +{ + mono_aot_register_jit_icall ("mono_arm_start_gsharedvt_call", mono_arm_start_gsharedvt_call); +} + +gboolean +mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig) +{ + /* + if (sig->ret && is_variable_size (sig->ret)) + return FALSE; + */ + return TRUE; +} + +static inline void +add_to_map (GPtrArray *map, int src, int dst) +{ + g_ptr_array_add (map, GUINT_TO_POINTER (src)); + g_ptr_array_add (map, GUINT_TO_POINTER (dst)); +} + +/* + * Slot mapping: + * 0..8 - r0..r8 + * 9..16 - d0..d7 + * 17.. - stack slots + */ + +static inline int +map_reg (int reg) +{ + return reg; +} + +static inline int +map_freg (int reg) +{ + return reg + NUM_GSHAREDVT_ARG_GREGS; +} + +static inline int +map_stack_slot (int slot) +{ + return slot + NUM_GSHAREDVT_ARG_GREGS + NUM_GSHAREDVT_ARG_FREGS; +} + +static int +get_arg_slots (ArgInfo *ainfo, int **out_slots) +{ + int sreg = ainfo->reg; + int sslot = ainfo->offset / 8; + int *src = NULL; + int i, nsrc; + + switch (ainfo->storage) { + case ArgInIReg: + case ArgVtypeByRef: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_reg (sreg); + break; + case ArgVtypeByRefOnStack: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_stack_slot (sslot); + break; + case ArgInFReg: + case ArgInFRegR4: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_freg (sreg); + break; + case ArgHFA: + nsrc = ainfo->nregs; + src = g_malloc (nsrc * sizeof (int)); + for (i = 0; i < ainfo->nregs; ++i) + src [i] = map_freg (sreg + i); + break; + case ArgVtypeInIRegs: + nsrc = ainfo->nregs; + src = g_malloc (nsrc * sizeof (int)); + for (i = 0; i < ainfo->nregs; ++i) + src [i] = map_reg (sreg + i); + break; + case ArgOnStack: + nsrc = 1; + src = g_malloc (nsrc * sizeof (int)); + src [0] = map_stack_slot (sslot); + break; + case ArgVtypeOnStack: + nsrc = ainfo->size / 8; + src = g_malloc (nsrc * sizeof (int)); + for (i = 0; i < nsrc; ++i) + src [i] = map_stack_slot (sslot + i); + break; + default: + NOT_IMPLEMENTED; + break; + } + + *out_slots = src; + return nsrc; +} + +/* + * mono_arch_get_gsharedvt_call_info: + * + * See mini-x86.c for documentation. + */ +gpointer +mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) +{ + GSharedVtCallInfo *info; + CallInfo *caller_cinfo, *callee_cinfo; + MonoMethodSignature *caller_sig, *callee_sig; + int aindex, i; + gboolean var_ret = FALSE; + CallInfo *cinfo, *gcinfo; + MonoMethodSignature *sig, *gsig; + GPtrArray *map; + + if (gsharedvt_in) { + caller_sig = normal_sig; + callee_sig = gsharedvt_sig; + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + } else { + callee_sig = normal_sig; + caller_sig = gsharedvt_sig; + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + } + + /* + * If GSHAREDVT_IN is true, this means we are transitioning from normal to gsharedvt code. The caller uses the + * normal call signature, while the callee uses the gsharedvt signature. + * If GSHAREDVT_IN is false, its the other way around. + */ + + /* sig/cinfo describes the normal call, while gsig/gcinfo describes the gsharedvt call */ + if (gsharedvt_in) { + sig = caller_sig; + gsig = callee_sig; + cinfo = caller_cinfo; + gcinfo = callee_cinfo; + } else { + sig = callee_sig; + gsig = caller_sig; + cinfo = callee_cinfo; + gcinfo = caller_cinfo; + } + + if (gcinfo->ret.gsharedvt) { + /* + * The return type is gsharedvt + */ + var_ret = TRUE; + } + + /* + * The stack looks like this: + * + * + * + * We have to map the stack slots in to the stack slots in . + */ + map = g_ptr_array_new (); + + for (aindex = 0; aindex < cinfo->nargs; ++aindex) { + ArgInfo *ainfo = &caller_cinfo->args [aindex]; + ArgInfo *ainfo2 = &callee_cinfo->args [aindex]; + int *src = NULL, *dst = NULL; + int nsrc, ndst, nslots, src_slot, arg_marshal; + + /* + * The src descriptor looks like this: + * - 6 bits src slot + * - 12 bits number of slots + * - 4 bits marshal type (GSHAREDVT_ARG_...) + * - 4 bits size/sign descriptor (GSHAREDVT_ARG_SIZE) + * - 4 bits offset inside stack slots + */ + arg_marshal = GSHAREDVT_ARG_NONE; + + if (ainfo->gsharedvt) { + /* Pass the value whose address is received in a reg by value */ + g_assert (!ainfo2->gsharedvt); + ndst = get_arg_slots (ainfo2, &dst); + nsrc = 1; + src = g_new0 (int, 1); + if (ainfo->storage == ArgVtypeByRef) + src_slot = map_reg (ainfo->reg); + else + src_slot = map_stack_slot (ainfo->offset / 8); + g_assert (ndst < 256); + g_assert (src_slot < 64); + src [0] = (ndst << 6) | src_slot; + if (ainfo2->storage == ArgHFA && ainfo2->esize == 4) + arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL_HFAR4; + else if (ainfo2->storage == ArgVtypeByRef || ainfo2->storage == ArgVtypeByRefOnStack) + arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYREF; + else + arg_marshal = GSHAREDVT_ARG_BYREF_TO_BYVAL; + } else { + nsrc = get_arg_slots (ainfo, &src); + } + if (ainfo2->storage == ArgVtypeByRef && ainfo2->gsharedvt) { + /* Pass the address of the first src slot in a reg */ + if (ainfo->storage != ArgVtypeByRef) { + if (ainfo->storage == ArgHFA && ainfo->esize == 4) { + arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF_HFAR4; + g_assert (src [0] < 64); + g_assert (nsrc < 256); + src [0] |= (nsrc << 6); + } else { + arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF; + } + } + ndst = 1; + dst = g_new0 (int, 1); + dst [0] = map_reg (ainfo2->reg); + } else if (ainfo2->storage == ArgVtypeByRefOnStack && ainfo2->gsharedvt) { + /* Pass the address of the first src slot in a stack slot */ + if (ainfo->storage != ArgVtypeByRef) + arg_marshal = GSHAREDVT_ARG_BYVAL_TO_BYREF; + ndst = 1; + dst = g_new0 (int, 1); + dst [0] = map_stack_slot (ainfo2->offset / 8); + } else { + ndst = get_arg_slots (ainfo2, &dst); + } + if (nsrc) + src [0] |= (arg_marshal << 18); + if (ainfo->storage == ArgOnStack && ainfo->slot_size != 8) { + GSharedVtArgSize arg_size = GSHAREDVT_ARG_SIZE_NONE; + + /* + * On IOS, stack arguments smaller than 8 bytes can + * share a stack slot. Encode this information into + * the descriptor. + */ + switch (ainfo->slot_size) { + case 1: + arg_size = ainfo->sign ? GSHAREDVT_ARG_SIZE_I1 : GSHAREDVT_ARG_SIZE_U1; + break; + case 2: + arg_size = ainfo->sign ? GSHAREDVT_ARG_SIZE_I2 : GSHAREDVT_ARG_SIZE_U2; + break; + case 4: + arg_size = ainfo->sign ? GSHAREDVT_ARG_SIZE_I4 : GSHAREDVT_ARG_SIZE_U4; + break; + default: + NOT_IMPLEMENTED; + break; + } + /* Encode the size/sign */ + src [0] |= (arg_size << 22); + /* Encode the offset inside the stack slot */ + src [0] |= ((ainfo->offset % 8) << 26); + if (ainfo2->storage == ArgOnStack) + dst [0] |= ((ainfo2->offset % 8) << 26); + } else if (ainfo2->storage == ArgOnStack && ainfo2->slot_size != 8) { + /* The caller passes in an address, need to store it into a stack slot */ + + GSharedVtArgSize arg_size = GSHAREDVT_ARG_SIZE_NONE; + switch (ainfo2->slot_size) { + case 1: + arg_size = ainfo2->sign ? GSHAREDVT_ARG_SIZE_I1 : GSHAREDVT_ARG_SIZE_U1; + break; + case 2: + arg_size = ainfo2->sign ? GSHAREDVT_ARG_SIZE_I2 : GSHAREDVT_ARG_SIZE_U2; + break; + case 4: + arg_size = ainfo2->sign ? GSHAREDVT_ARG_SIZE_I4 : GSHAREDVT_ARG_SIZE_U4; + break; + default: + NOT_IMPLEMENTED; + break; + } + /* Encode the size/sign */ + src [0] |= (arg_size << 22); + /* Encode the offset inside the stack slot */ + dst [0] |= ((ainfo2->offset % 8) << 26); + } + nslots = MIN (nsrc, ndst); + + for (i = 0; i < nslots; ++i) + add_to_map (map, src [i], dst [i]); + + g_free (src); + g_free (dst); + } + + if (cinfo->ret.storage == ArgVtypeByRef) { + /* Both the caller and the callee pass the vtype ret address in r8 */ + g_assert (cinfo->ret.storage == gcinfo->ret.storage); + add_to_map (map, map_reg (ARMREG_R8), map_reg (ARMREG_R8)); + } + + info = mono_domain_alloc0 (mono_domain_get (), sizeof (GSharedVtCallInfo) + (map->len * sizeof (int))); + info->addr = addr; + info->stack_usage = callee_cinfo->stack_usage; + info->ret_marshal = GSHAREDVT_RET_NONE; + info->gsharedvt_in = gsharedvt_in ? 1 : 0; + info->vret_slot = -1; + info->calli = calli; + + if (var_ret) { + g_assert (gcinfo->ret.gsharedvt); + info->vret_arg_reg = map_reg (ARMREG_R8); + } else { + info->vret_arg_reg = -1; + } + + info->vcall_offset = vcall_offset; + info->map_count = map->len / 2; + for (i = 0; i < map->len; ++i) + info->map [i] = GPOINTER_TO_UINT (g_ptr_array_index (map, i)); + g_ptr_array_free (map, TRUE); + + /* Compute return value marshalling */ + if (var_ret) { + switch (cinfo->ret.storage) { + case ArgInIReg: + if (!gsharedvt_in || sig->ret->byref) { + info->ret_marshal = GSHAREDVT_RET_I8; + } else { + switch (sig->ret->type) { + case MONO_TYPE_I1: + info->ret_marshal = GSHAREDVT_RET_I1; + break; + case MONO_TYPE_U1: + case MONO_TYPE_BOOLEAN: + info->ret_marshal = GSHAREDVT_RET_U1; + break; + case MONO_TYPE_I2: + info->ret_marshal = GSHAREDVT_RET_I2; + break; + case MONO_TYPE_U2: + case MONO_TYPE_CHAR: + info->ret_marshal = GSHAREDVT_RET_U2; + break; + case MONO_TYPE_I4: + info->ret_marshal = GSHAREDVT_RET_I4; + break; + case MONO_TYPE_U4: + info->ret_marshal = GSHAREDVT_RET_U4; + break; + default: + info->ret_marshal = GSHAREDVT_RET_I8; + break; + } + } + break; + case ArgInFReg: + info->ret_marshal = GSHAREDVT_RET_R8; + break; + case ArgInFRegR4: + info->ret_marshal = GSHAREDVT_RET_R4; + break; + case ArgVtypeInIRegs: + info->ret_marshal = GSHAREDVT_RET_IREGS_1 - 1 + cinfo->ret.nregs; + break; + case ArgHFA: + if (cinfo->ret.esize == 4) + info->ret_marshal = GSHAREDVT_RET_HFAR4_1 - 1 + cinfo->ret.nregs; + else + info->ret_marshal = GSHAREDVT_RET_HFAR8_1 - 1 + cinfo->ret.nregs; + break; + case ArgVtypeByRef: + /* No conversion needed */ + break; + default: + g_assert_not_reached (); + } + } + + if (gsharedvt_in && var_ret && cinfo->ret.storage != ArgVtypeByRef) { + /* Allocate stack space for the return value */ + info->vret_slot = map_stack_slot (info->stack_usage / sizeof (gpointer)); + info->stack_usage += mono_type_stack_size_internal (normal_sig->ret, NULL, FALSE) + sizeof (gpointer); + } + + info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + + return info; +} + +#else + +void +mono_arm_gsharedvt_init (void) +{ +} + +#endif /* MONO_ARCH_GSHARED_SUPPORTED */ \ No newline at end of file diff --git a/mono/mini/mini-arm64-gsharedvt.h b/mono/mini/mini-arm64-gsharedvt.h new file mode 100644 index 00000000000..b828218887d --- /dev/null +++ b/mono/mini/mini-arm64-gsharedvt.h @@ -0,0 +1,84 @@ +#ifndef __MINI_ARM64_GSHAREDVT_H__ +#define __MINI_ARM64_GSHAREDVT_H__ + +/* Argument marshallings for calls between gsharedvt and normal code */ +typedef enum { + GSHAREDVT_ARG_NONE = 0, + GSHAREDVT_ARG_BYVAL_TO_BYREF = 1, + GSHAREDVT_ARG_BYVAL_TO_BYREF_HFAR4 = 2, + GSHAREDVT_ARG_BYREF_TO_BYVAL = 3, + GSHAREDVT_ARG_BYREF_TO_BYVAL_HFAR4 = 4, + GSHAREDVT_ARG_BYREF_TO_BYREF = 5 +} GSharedVtArgMarshal; + +/* For arguments passed on the stack on ios */ +typedef enum { + GSHAREDVT_ARG_SIZE_NONE = 0, + GSHAREDVT_ARG_SIZE_I1 = 1, + GSHAREDVT_ARG_SIZE_U1 = 2, + GSHAREDVT_ARG_SIZE_I2 = 3, + GSHAREDVT_ARG_SIZE_U2 = 4, + GSHAREDVT_ARG_SIZE_I4 = 5, + GSHAREDVT_ARG_SIZE_U4 = 6, +} GSharedVtArgSize; + +/* Return value marshalling for calls between gsharedvt and normal code */ +typedef enum { + GSHAREDVT_RET_NONE = 0, + GSHAREDVT_RET_I8 = 1, + GSHAREDVT_RET_I1 = 2, + GSHAREDVT_RET_U1 = 3, + GSHAREDVT_RET_I2 = 4, + GSHAREDVT_RET_U2 = 5, + GSHAREDVT_RET_I4 = 6, + GSHAREDVT_RET_U4 = 7, + GSHAREDVT_RET_R8 = 8, + GSHAREDVT_RET_R4 = 9, + GSHAREDVT_RET_IREGS_1 = 10, + GSHAREDVT_RET_IREGS_2 = 11, + GSHAREDVT_RET_IREGS_3 = 12, + GSHAREDVT_RET_IREGS_4 = 13, + GSHAREDVT_RET_IREGS_5 = 14, + GSHAREDVT_RET_IREGS_6 = 15, + GSHAREDVT_RET_IREGS_7 = 16, + GSHAREDVT_RET_IREGS_8 = 17, + GSHAREDVT_RET_HFAR8_1 = 18, + GSHAREDVT_RET_HFAR8_2 = 19, + GSHAREDVT_RET_HFAR8_3 = 20, + GSHAREDVT_RET_HFAR8_4 = 21, + GSHAREDVT_RET_HFAR4_1 = 22, + GSHAREDVT_RET_HFAR4_2 = 23, + GSHAREDVT_RET_HFAR4_3 = 24, + GSHAREDVT_RET_HFAR4_4 = 25, + GSHAREDVT_RET_NUM = 26 +} GSharedVtRetMarshal; + +typedef struct { + /* Method address to call */ + gpointer addr; + /* The trampoline reads this, so keep the size explicit */ + int ret_marshal; + /* If ret_marshal != NONE, this is the reg of the vret arg, else -1 */ + /* Equivalent of vret_arg_slot in x86 implementation. */ + int vret_arg_reg; + /* The stack slot where the return value will be stored */ + int vret_slot; + int stack_usage, map_count; + /* If not -1, then make a virtual call using this vtable offset */ + int vcall_offset; + /* If 1, make an indirect call to the address in the rgctx reg */ + int calli; + /* Whenever this is a in or an out call */ + int gsharedvt_in; + /* Maps stack slots/registers in the caller to the stack slots/registers in the callee */ + int map [MONO_ZERO_LEN_ARRAY]; +} GSharedVtCallInfo; + +/* Number of argument registers (r0..r8) */ +#define NUM_GSHAREDVT_ARG_GREGS 9 +#define NUM_GSHAREDVT_ARG_FREGS 8 + +gpointer +mono_arm_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg); + +#endif /* __MINI_ARM64_GSHAREDVT_H__ */ diff --git a/mono/mini/mini-arm64.c b/mono/mini/mini-arm64.c index 517f6c68a9d..83fe015daa5 100644 --- a/mono/mini/mini-arm64.c +++ b/mono/mini/mini-arm64.c @@ -1 +1,5217 @@ -#include "../../../mono-extensions/mono/mini/mini-arm64.c" +/* + * mini-arm64.c: ARM64 backend for the Mono code generator + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * + * Based on mini-arm.c: + * + * Authors: + * Paolo Molaro (lupus@ximian.com) + * Dietmar Maurer (dietmar@ximian.com) + * + * (C) 2003 Ximian, Inc. + * Copyright 2003-2011 Novell, Inc (http://www.novell.com) + * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +#include "mini.h" +#include "cpu-arm64.h" +#include "ir-emit.h" + +#include +#include +#include +#include + +/* + * Documentation: + * + * - ARM(R) Architecture Reference Manual, ARMv8, for ARMv8-A architecture profile (DDI0487A_a_armv8_arm.pdf) + * - Procedure Call Standard for the ARM 64-bit Architecture (AArch64) (IHI0055B_aapcs64.pdf) + * - ELF for the ARM 64-bit Architecture (IHI0056B_aaelf64.pdf) + * + * Register usage: + * - ip0/ip1/lr are used as temporary registers + * - r27 is used as the rgctx/imt register + * - r28 is used to access arguments passed on the stack + * - d15/d16 are used as fp temporary registers + */ + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +#define FP_TEMP_REG ARMREG_D16 +#define FP_TEMP_REG2 ARMREG_D17 + +#define THUNK_SIZE (4 * 4) + +/* The single step trampoline */ +static gpointer ss_trampoline; + +/* The breakpoint trampoline */ +static gpointer bp_trampoline; + +static gboolean ios_abi; + +static __attribute__((warn_unused_result)) guint8* emit_load_regset (guint8 *code, guint64 regs, int basereg, int offset); + +const char* +mono_arch_regname (int reg) +{ + static const char * rnames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", + "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "fp", + "lr", "sp" + }; + if (reg >= 0 && reg < 32) + return rnames [reg]; + return "unknown"; +} + +const char* +mono_arch_fregname (int reg) +{ + static const char * rnames[] = { + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", + "d10", "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", + "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", + "d30", "d31" + }; + if (reg >= 0 && reg < 32) + return rnames [reg]; + return "unknown fp"; +} + +int +mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) +{ + NOT_IMPLEMENTED; + return 0; +} + +#define MAX_ARCH_DELEGATE_PARAMS 7 + +static gpointer +get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size) +{ + guint8 *code, *start; + + if (has_target) { + start = code = mono_global_codeman_reserve (12); + + /* Replace the this argument with the target */ + arm_ldrx (code, ARMREG_IP0, ARMREG_R0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr)); + arm_ldrx (code, ARMREG_R0, ARMREG_R0, MONO_STRUCT_OFFSET (MonoDelegate, target)); + arm_brx (code, ARMREG_IP0); + + g_assert ((code - start) <= 12); + + mono_arch_flush_icache (start, 12); + } else { + int size, i; + + size = 8 + param_count * 4; + start = code = mono_global_codeman_reserve (size); + + arm_ldrx (code, ARMREG_IP0, ARMREG_R0, MONO_STRUCT_OFFSET (MonoDelegate, method_ptr)); + /* slide down the arguments */ + for (i = 0; i < param_count; ++i) + arm_movx (code, i, i + 1); + arm_brx (code, ARMREG_IP0); + + g_assert ((code - start) <= size); + + mono_arch_flush_icache (start, size); + } + + if (code_size) + *code_size = code - start; + + return start; +} + +/* + * mono_arch_get_delegate_invoke_impls: + * + * Return a list of MonoAotTrampInfo structures for the delegate invoke impl + * trampolines. + */ +GSList* +mono_arch_get_delegate_invoke_impls (void) +{ + GSList *res = NULL; + guint8 *code; + guint32 code_len; + int i; + char *tramp_name; + + code = get_delegate_invoke_impl (TRUE, 0, &code_len); + res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL)); + + for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) { + code = get_delegate_invoke_impl (FALSE, i, &code_len); + tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i); + res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL)); + g_free (tramp_name); + } + + return res; +} + +gpointer +mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_target) +{ + guint8 *code, *start; + + /* + * vtypes are returned in registers, or using the dedicated r8 register, so + * they can be supported by delegate invokes. + */ + + if (has_target) { + static guint8* cached = NULL; + + if (cached) + return cached; + + if (mono_aot_only) + start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target"); + else + start = get_delegate_invoke_impl (TRUE, 0, NULL); + mono_memory_barrier (); + cached = start; + return cached; + } else { + static guint8* cache [MAX_ARCH_DELEGATE_PARAMS + 1] = {NULL}; + int i; + + if (sig->param_count > MAX_ARCH_DELEGATE_PARAMS) + return NULL; + for (i = 0; i < sig->param_count; ++i) + if (!mono_is_regsize_var (sig->params [i])) + return NULL; + + code = cache [sig->param_count]; + if (code) + return code; + + if (mono_aot_only) { + char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", sig->param_count); + start = mono_aot_get_trampoline (name); + g_free (name); + } else { + start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL); + } + mono_memory_barrier (); + cache [sig->param_count] = start; + return start; + } + + return NULL; +} + +gpointer +mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg) +{ + return NULL; +} + +gpointer +mono_arch_get_this_arg_from_call (mgreg_t *regs, guint8 *code) +{ + return (gpointer)regs [ARMREG_R0]; +} + +void +mono_arch_cpu_init (void) +{ +} + +void +mono_arch_init (void) +{ + mono_aot_register_jit_icall ("mono_arm_throw_exception", mono_arm_throw_exception); + mono_aot_register_jit_icall ("mono_arm_resume_unwind", mono_arm_resume_unwind); + + if (!mono_aot_only) + bp_trampoline = mini_get_breakpoint_trampoline (); + + mono_arm_gsharedvt_init (); + +#if defined(TARGET_IOS) + ios_abi = TRUE; +#endif +} + +void +mono_arch_cleanup (void) +{ +} + +guint32 +mono_arch_cpu_optimizations (guint32 *exclude_mask) +{ + *exclude_mask = 0; + return 0; +} + +guint32 +mono_arch_cpu_enumerate_simd_versions (void) +{ + return 0; +} + +void +mono_arch_register_lowlevel_calls (void) +{ +} + +void +mono_arch_finish_init (void) +{ +} + +/* The maximum length is 2 instructions */ +static guint8* +emit_imm (guint8 *code, int dreg, int imm) +{ + // FIXME: Optimize this + if (imm < 0) { + gint64 limm = imm; + arm_movnx (code, dreg, (~limm) & 0xffff, 0); + arm_movkx (code, dreg, (limm >> 16) & 0xffff, 16); + } else { + arm_movzx (code, dreg, imm & 0xffff, 0); + if (imm >> 16) + arm_movkx (code, dreg, (imm >> 16) & 0xffff, 16); + } + + return code; +} + +/* The maximum length is 4 instructions */ +static guint8* +emit_imm64 (guint8 *code, int dreg, guint64 imm) +{ + // FIXME: Optimize this + arm_movzx (code, dreg, imm & 0xffff, 0); + if ((imm >> 16) & 0xffff) + arm_movkx (code, dreg, (imm >> 16) & 0xffff, 16); + if ((imm >> 32) & 0xffff) + arm_movkx (code, dreg, (imm >> 32) & 0xffff, 32); + if ((imm >> 48) & 0xffff) + arm_movkx (code, dreg, (imm >> 48) & 0xffff, 48); + + return code; +} + +guint8* +mono_arm_emit_imm64 (guint8 *code, int dreg, gint64 imm) +{ + return emit_imm64 (code, dreg, imm); +} + +/* + * emit_imm_template: + * + * Emit a patchable code sequence for constructing a 64 bit immediate. + */ +static guint8* +emit_imm64_template (guint8 *code, int dreg) +{ + arm_movzx (code, dreg, 0, 0); + arm_movkx (code, dreg, 0, 16); + arm_movkx (code, dreg, 0, 32); + arm_movkx (code, dreg, 0, 48); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_addw_imm (guint8 *code, int dreg, int sreg, int imm) +{ + if (!arm_is_arith_imm (imm)) { + code = emit_imm (code, ARMREG_LR, imm); + arm_addw (code, dreg, sreg, ARMREG_LR); + } else { + arm_addw_imm (code, dreg, sreg, imm); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_addx_imm (guint8 *code, int dreg, int sreg, int imm) +{ + if (!arm_is_arith_imm (imm)) { + code = emit_imm (code, ARMREG_LR, imm); + arm_addx (code, dreg, sreg, ARMREG_LR); + } else { + arm_addx_imm (code, dreg, sreg, imm); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_subw_imm (guint8 *code, int dreg, int sreg, int imm) +{ + if (!arm_is_arith_imm (imm)) { + code = emit_imm (code, ARMREG_LR, imm); + arm_subw (code, dreg, sreg, ARMREG_LR); + } else { + arm_subw_imm (code, dreg, sreg, imm); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_subx_imm (guint8 *code, int dreg, int sreg, int imm) +{ + if (!arm_is_arith_imm (imm)) { + code = emit_imm (code, ARMREG_LR, imm); + arm_subx (code, dreg, sreg, ARMREG_LR); + } else { + arm_subx_imm (code, dreg, sreg, imm); + } + return code; +} + +/* Emit sp+=imm. Clobbers ip0/ip1 */ +static inline __attribute__((warn_unused_result)) guint8* +emit_addx_sp_imm (guint8 *code, int imm) +{ + code = emit_imm (code, ARMREG_IP0, imm); + arm_movspx (code, ARMREG_IP1, ARMREG_SP); + arm_addx (code, ARMREG_IP1, ARMREG_IP1, ARMREG_IP0); + arm_movspx (code, ARMREG_SP, ARMREG_IP1); + return code; +} + +/* Emit sp-=imm. Clobbers ip0/ip1 */ +static inline __attribute__((warn_unused_result)) guint8* +emit_subx_sp_imm (guint8 *code, int imm) +{ + code = emit_imm (code, ARMREG_IP0, imm); + arm_movspx (code, ARMREG_IP1, ARMREG_SP); + arm_subx (code, ARMREG_IP1, ARMREG_IP1, ARMREG_IP0); + arm_movspx (code, ARMREG_SP, ARMREG_IP1); + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_andw_imm (guint8 *code, int dreg, int sreg, int imm) +{ + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_andw (code, dreg, sreg, ARMREG_LR); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_andx_imm (guint8 *code, int dreg, int sreg, int imm) +{ + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_andx (code, dreg, sreg, ARMREG_LR); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_orrw_imm (guint8 *code, int dreg, int sreg, int imm) +{ + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_orrw (code, dreg, sreg, ARMREG_LR); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_orrx_imm (guint8 *code, int dreg, int sreg, int imm) +{ + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_orrx (code, dreg, sreg, ARMREG_LR); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_eorw_imm (guint8 *code, int dreg, int sreg, int imm) +{ + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_eorw (code, dreg, sreg, ARMREG_LR); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_eorx_imm (guint8 *code, int dreg, int sreg, int imm) +{ + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_eorx (code, dreg, sreg, ARMREG_LR); + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_cmpw_imm (guint8 *code, int sreg, int imm) +{ + if (imm == 0) { + arm_cmpw (code, sreg, ARMREG_RZR); + } else { + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_cmpw (code, sreg, ARMREG_LR); + } + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_cmpx_imm (guint8 *code, int sreg, int imm) +{ + if (imm == 0) { + arm_cmpx (code, sreg, ARMREG_RZR); + } else { + // FIXME: + code = emit_imm (code, ARMREG_LR, imm); + arm_cmpx (code, sreg, ARMREG_LR); + } + + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_strb (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_strb_imm (imm)) { + arm_strb (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_strb_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_strh (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_strh_imm (imm)) { + arm_strh (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_strh_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_strw (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_strw_imm (imm)) { + arm_strw (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_strw_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_strfpw (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_strw_imm (imm)) { + arm_strfpw (code, rt, rn, imm); + } else { + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_addx (code, ARMREG_IP0, rn, ARMREG_IP0); + arm_strfpw (code, rt, ARMREG_IP0, 0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_strfpx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_strx_imm (imm)) { + arm_strfpx (code, rt, rn, imm); + } else { + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_addx (code, ARMREG_IP0, rn, ARMREG_IP0); + arm_strfpx (code, rt, ARMREG_IP0, 0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_strx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_strx_imm (imm)) { + arm_strx (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_strx_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrb (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 1)) { + arm_ldrb (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrb_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrsbx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 1)) { + arm_ldrsbx (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrsbx_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrh (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 2)) { + arm_ldrh (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrh_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrshx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 2)) { + arm_ldrshx (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrshx_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrswx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 4)) { + arm_ldrswx (code, rt, rn, imm); + } else { + g_assert (rt != ARMREG_IP0); + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrswx_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrw (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 4)) { + arm_ldrw (code, rt, rn, imm); + } else { + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrw_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 8)) { + arm_ldrx (code, rt, rn, imm); + } else { + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_ldrx_reg (code, rt, rn, ARMREG_IP0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrfpw (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 4)) { + arm_ldrfpw (code, rt, rn, imm); + } else { + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_addx (code, ARMREG_IP0, rn, ARMREG_IP0); + arm_ldrfpw (code, rt, ARMREG_IP0, 0); + } + return code; +} + +static inline __attribute__((warn_unused_result)) guint8* +emit_ldrfpx (guint8 *code, int rt, int rn, int imm) +{ + if (arm_is_pimm12_scaled (imm, 8)) { + arm_ldrfpx (code, rt, rn, imm); + } else { + g_assert (rn != ARMREG_IP0); + code = emit_imm (code, ARMREG_IP0, imm); + arm_addx (code, ARMREG_IP0, rn, ARMREG_IP0); + arm_ldrfpx (code, rt, ARMREG_IP0, 0); + } + return code; +} + +guint8* +mono_arm_emit_ldrx (guint8 *code, int rt, int rn, int imm) +{ + return emit_ldrx (code, rt, rn, imm); +} + +static guint8* +emit_call (MonoCompile *cfg, guint8* code, guint32 patch_type, gconstpointer data) +{ + /* + mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, data, MONO_R_ARM64_IMM); + code = emit_imm64_template (code, ARMREG_LR); + arm_blrx (code, ARMREG_LR); + */ + mono_add_patch_info_rel (cfg, code - cfg->native_code, patch_type, data, MONO_R_ARM64_BL); + arm_bl (code, code); + cfg->thunk_area += THUNK_SIZE; + return code; +} + +static guint8* +emit_aotconst_full (MonoCompile *cfg, MonoJumpInfo **ji, guint8 *code, guint8 *start, int dreg, guint32 patch_type, gconstpointer data) +{ + if (cfg) + mono_add_patch_info (cfg, code - cfg->native_code, patch_type, data); + else + *ji = mono_patch_info_list_prepend (*ji, code - start, patch_type, data); + /* See arch_emit_got_access () in aot-compiler.c */ + arm_ldrx_lit (code, dreg, 0); + arm_nop (code); + arm_nop (code); + return code; +} + +static guint8* +emit_aotconst (MonoCompile *cfg, guint8 *code, int dreg, guint32 patch_type, gconstpointer data) +{ + return emit_aotconst_full (cfg, NULL, code, NULL, dreg, patch_type, data); +} + +/* + * mono_arm_emit_aotconst: + * + * Emit code to load an AOT constant into DREG. Usable from trampolines. + */ +guint8* +mono_arm_emit_aotconst (gpointer ji, guint8 *code, guint8 *code_start, int dreg, guint32 patch_type, gconstpointer data) +{ + return emit_aotconst_full (NULL, (MonoJumpInfo**)ji, code, code_start, dreg, patch_type, data); +} + +static guint8* +emit_tls_get (guint8 *code, int dreg, int tls_offset) +{ + arm_mrs (code, dreg, ARM_MRS_REG_TPIDR_EL0); + if (tls_offset < 256) { + arm_ldrx (code, dreg, dreg, tls_offset); + } else { + code = emit_addx_imm (code, dreg, dreg, tls_offset); + arm_ldrx (code, dreg, dreg, 0); + } + return code; +} + +static guint8* +emit_tls_get_reg (guint8 *code, int dreg, int offset_reg) +{ + g_assert (offset_reg != ARMREG_IP0); + arm_mrs (code, ARMREG_IP0, ARM_MRS_REG_TPIDR_EL0); + arm_ldrx_reg (code, dreg, ARMREG_IP0, offset_reg); + return code; +} + +static guint8* +emit_tls_set (guint8 *code, int sreg, int tls_offset) +{ + int tmpreg = ARMREG_IP0; + + g_assert (sreg != tmpreg); + arm_mrs (code, tmpreg, ARM_MRS_REG_TPIDR_EL0); + if (tls_offset < 256) { + arm_strx (code, sreg, tmpreg, tls_offset); + } else { + code = emit_addx_imm (code, tmpreg, tmpreg, tls_offset); + arm_strx (code, sreg, tmpreg, 0); + } + return code; +} + + +static guint8* +emit_tls_set_reg (guint8 *code, int sreg, int offset_reg) +{ + int tmpreg = ARMREG_IP0; + + g_assert (sreg != tmpreg); + arm_mrs (code, tmpreg, ARM_MRS_REG_TPIDR_EL0); + arm_strx_reg (code, sreg, tmpreg, offset_reg); + return code; +} + +/* + * Emits + * - mov sp, fp + * - ldrp [fp, lr], [sp], !stack_offfset + * Clobbers TEMP_REGS. + */ +__attribute__((warn_unused_result)) guint8* +mono_arm_emit_destroy_frame (guint8 *code, int stack_offset, guint64 temp_regs) +{ + arm_movspx (code, ARMREG_SP, ARMREG_FP); + + if (arm_is_ldpx_imm (stack_offset)) { + arm_ldpx_post (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, stack_offset); + } else { + arm_ldpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0); + /* sp += stack_offset */ + g_assert (temp_regs & (1 << ARMREG_IP0)); + if (temp_regs & (1 << ARMREG_IP1)) { + code = emit_addx_sp_imm (code, stack_offset); + } else { + int imm = stack_offset; + + /* Can't use addx_sp_imm () since we can't clobber ip0/ip1 */ + arm_addx_imm (code, ARMREG_IP0, ARMREG_SP, 0); + while (imm > 256) { + arm_addx_imm (code, ARMREG_IP0, ARMREG_IP0, 256); + imm -= 256; + } + arm_addx_imm (code, ARMREG_SP, ARMREG_IP0, imm); + } + } + return code; +} + +#define is_call_imm(diff) ((gint)(diff) >= -33554432 && (gint)(diff) <= 33554431) + +static guint8* +emit_thunk (guint8 *code, gconstpointer target) +{ + guint8 *p = code; + + arm_ldrx_lit (code, ARMREG_IP0, code + 8); + arm_brx (code, ARMREG_IP0); + *(guint64*)code = (guint64)target; + + mono_arch_flush_icache (p, code - p); + return code; +} + +static gpointer +create_thunk (MonoCompile *cfg, MonoDomain *domain, guchar *code, const guchar *target) +{ + MonoJitInfo *ji; + MonoThunkJitInfo *info; + guint8 *thunks, *p; + int thunks_size; + guint8 *orig_target; + guint8 *target_thunk; + + if (!domain) + domain = mono_domain_get (); + + if (cfg) { + /* + * This can be called multiple times during JITting, + * save the current position in cfg->arch to avoid + * doing a O(n^2) search. + */ + if (!cfg->arch.thunks) { + cfg->arch.thunks = cfg->thunks; + cfg->arch.thunks_size = cfg->thunk_area; + } + thunks = cfg->arch.thunks; + thunks_size = cfg->arch.thunks_size; + if (!thunks_size) { + g_print ("thunk failed %p->%p, thunk space=%d method %s", code, target, thunks_size, mono_method_full_name (cfg->method, TRUE)); + g_assert_not_reached (); + } + + g_assert (*(guint32*)thunks == 0); + emit_thunk (thunks, target); + + cfg->arch.thunks += THUNK_SIZE; + cfg->arch.thunks_size -= THUNK_SIZE; + + return thunks; + } else { + ji = mini_jit_info_table_find (domain, (char*)code, NULL); + g_assert (ji); + info = mono_jit_info_get_thunk_info (ji); + g_assert (info); + + thunks = (guint8*)ji->code_start + info->thunks_offset; + thunks_size = info->thunks_size; + + orig_target = mono_arch_get_call_target (code + 4); + + mono_domain_lock (domain); + + target_thunk = NULL; + if (orig_target >= thunks && orig_target < thunks + thunks_size) { + /* The call already points to a thunk, because of trampolines etc. */ + target_thunk = orig_target; + } else { + for (p = thunks; p < thunks + thunks_size; p += THUNK_SIZE) { + if (((guint32*)p) [0] == 0) { + /* Free entry */ + target_thunk = p; + break; + } else if (((guint64*)p) [1] == (guint64)target) { + /* Thunk already points to target */ + target_thunk = p; + break; + } + } + } + + //printf ("THUNK: %p %p %p\n", code, target, target_thunk); + + if (!target_thunk) { + mono_domain_unlock (domain); + g_print ("thunk failed %p->%p, thunk space=%d method %s", code, target, thunks_size, cfg ? mono_method_full_name (cfg->method, TRUE) : mono_method_full_name (jinfo_get_method (ji), TRUE)); + g_assert_not_reached (); + } + + emit_thunk (target_thunk, target); + + mono_domain_unlock (domain); + + return target_thunk; + } +} + +static void +arm_patch_full (MonoCompile *cfg, MonoDomain *domain, guint8 *code, guint8 *target, int relocation) +{ + switch (relocation) { + case MONO_R_ARM64_B: + arm_b (code, target); + break; + case MONO_R_ARM64_BCC: { + int cond; + + cond = arm_get_bcc_cond (code); + arm_bcc (code, cond, target); + break; + } + case MONO_R_ARM64_CBZ: + arm_set_cbz_target (code, target); + break; + case MONO_R_ARM64_IMM: { + guint64 imm = (guint64)target; + int dreg; + + /* emit_imm64_template () */ + dreg = arm_get_movzx_rd (code); + arm_movzx (code, dreg, imm & 0xffff, 0); + arm_movkx (code, dreg, (imm >> 16) & 0xffff, 16); + arm_movkx (code, dreg, (imm >> 32) & 0xffff, 32); + arm_movkx (code, dreg, (imm >> 48) & 0xffff, 48); + break; + } + case MONO_R_ARM64_BL: + if (arm_is_bl_disp (code, target)) { + arm_bl (code, target); + } else { + gpointer thunk; + + thunk = create_thunk (cfg, domain, code, target); + g_assert (arm_is_bl_disp (code, thunk)); + arm_bl (code, thunk); + } + break; + default: + g_assert_not_reached (); + } +} + +static void +arm_patch_rel (guint8 *code, guint8 *target, int relocation) +{ + arm_patch_full (NULL, NULL, code, target, relocation); +} + +void +mono_arm_patch (guint8 *code, guint8 *target, int relocation) +{ + arm_patch_rel (code, target, relocation); +} + +void +mono_arch_patch_code_new (MonoCompile *cfg, MonoDomain *domain, guint8 *code, MonoJumpInfo *ji, gpointer target) +{ + guint8 *ip; + + ip = ji->ip.i + code; + + switch (ji->type) { + case MONO_PATCH_INFO_METHOD_JUMP: + /* ji->relocation is not set by the caller */ + arm_patch_rel (ip, (guint8*)target, MONO_R_ARM64_B); + break; + default: + arm_patch_full (cfg, domain, ip, (guint8*)target, ji->relocation); + break; + } +} + +void +mono_arch_free_jit_tls_data (MonoJitTlsData *tls) +{ +} + +void +mono_arch_flush_register_windows (void) +{ +} + +MonoMethod* +mono_arch_find_imt_method (mgreg_t *regs, guint8 *code) +{ + return (gpointer)regs [MONO_ARCH_RGCTX_REG]; +} + +MonoVTable* +mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code) +{ + return (gpointer)regs [MONO_ARCH_RGCTX_REG]; +} + +mgreg_t +mono_arch_context_get_int_reg (MonoContext *ctx, int reg) +{ + return ctx->regs [reg]; +} + +void +mono_arch_context_set_int_reg (MonoContext *ctx, int reg, mgreg_t val) +{ + ctx->regs [reg] = val; +} + +/* + * mono_arch_set_target: + * + * Set the target architecture the JIT backend should generate code for, in the form + * of a GNU target triplet. Only used in AOT mode. + */ +void +mono_arch_set_target (char *mtriple) +{ + if (strstr (mtriple, "darwin") || strstr (mtriple, "ios")) { + ios_abi = TRUE; + } +} + +static void +add_general (CallInfo *cinfo, ArgInfo *ainfo, int size, gboolean sign) +{ + if (cinfo->gr >= PARAM_REGS) { + ainfo->storage = ArgOnStack; + if (ios_abi) { + /* Assume size == align */ + cinfo->stack_usage = ALIGN_TO (cinfo->stack_usage, size); + ainfo->offset = cinfo->stack_usage; + ainfo->slot_size = size; + ainfo->sign = sign; + cinfo->stack_usage += size; + } else { + ainfo->offset = cinfo->stack_usage; + ainfo->slot_size = 8; + ainfo->sign = FALSE; + /* Put arguments into 8 byte aligned stack slots */ + cinfo->stack_usage += 8; + } + } else { + ainfo->storage = ArgInIReg; + ainfo->reg = cinfo->gr; + cinfo->gr ++; + } +} + +static void +add_fp (CallInfo *cinfo, ArgInfo *ainfo, gboolean single) +{ + int size = single ? 4 : 8; + + if (cinfo->fr >= FP_PARAM_REGS) { + ainfo->storage = single ? ArgOnStackR4 : ArgOnStackR8; + if (ios_abi) { + cinfo->stack_usage = ALIGN_TO (cinfo->stack_usage, size); + ainfo->offset = cinfo->stack_usage; + ainfo->slot_size = size; + cinfo->stack_usage += size; + } else { + ainfo->offset = cinfo->stack_usage; + ainfo->slot_size = 8; + /* Put arguments into 8 byte aligned stack slots */ + cinfo->stack_usage += 8; + } + } else { + if (single) + ainfo->storage = ArgInFRegR4; + else + ainfo->storage = ArgInFReg; + ainfo->reg = cinfo->fr; + cinfo->fr ++; + } +} + +static gboolean +is_hfa (MonoType *t, int *out_nfields, int *out_esize, int *field_offsets) +{ + MonoClass *klass; + gpointer iter; + MonoClassField *field; + MonoType *ftype, *prev_ftype = NULL; + int i, nfields = 0; + + klass = mono_class_from_mono_type (t); + iter = NULL; + while ((field = mono_class_get_fields (klass, &iter))) { + if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) + continue; + ftype = mono_field_get_type (field); + ftype = mini_get_underlying_type (ftype); + + if (MONO_TYPE_ISSTRUCT (ftype)) { + int nested_nfields, nested_esize; + int nested_field_offsets [16]; + + if (!is_hfa (ftype, &nested_nfields, &nested_esize, nested_field_offsets)) + return FALSE; + if (nested_esize == 4) + ftype = &mono_defaults.single_class->byval_arg; + else + ftype = &mono_defaults.double_class->byval_arg; + if (prev_ftype && prev_ftype->type != ftype->type) + return FALSE; + prev_ftype = ftype; + for (i = 0; i < nested_nfields; ++i) { + if (nfields + i < 4) + field_offsets [nfields + i] = field->offset - sizeof (MonoObject) + nested_field_offsets [i]; + } + nfields += nested_nfields; + } else { + if (!(!ftype->byref && (ftype->type == MONO_TYPE_R4 || ftype->type == MONO_TYPE_R8))) + return FALSE; + if (prev_ftype && prev_ftype->type != ftype->type) + return FALSE; + prev_ftype = ftype; + if (nfields < 4) + field_offsets [nfields] = field->offset - sizeof (MonoObject); + nfields ++; + } + } + if (nfields == 0 || nfields > 4) + return FALSE; + *out_nfields = nfields; + *out_esize = prev_ftype->type == MONO_TYPE_R4 ? 4 : 8; + return TRUE; +} + +static void +add_valuetype (CallInfo *cinfo, ArgInfo *ainfo, MonoType *t) +{ + int i, size, align_size, nregs, nfields, esize; + int field_offsets [16]; + guint32 align; + + size = mini_type_stack_size_full (t, &align, FALSE); + align_size = ALIGN_TO (size, 8); + + nregs = size / 8; + if (is_hfa (t, &nfields, &esize, field_offsets)) { + /* + * The struct might include nested float structs aligned at 8, + * so need to keep track of the offsets of the individual fields. + */ + if (cinfo->fr + nfields <= FP_PARAM_REGS) { + ainfo->storage = ArgHFA; + ainfo->reg = cinfo->fr; + ainfo->nregs = nfields; + ainfo->size = size; + ainfo->esize = esize; + for (i = 0; i < nfields; ++i) + ainfo->foffsets [i] = field_offsets [i]; + cinfo->fr += ainfo->nregs; + } else { + ainfo->nfregs_to_skip = FP_PARAM_REGS > cinfo->fr ? FP_PARAM_REGS - cinfo->fr : 0; + cinfo->fr = FP_PARAM_REGS; + size = ALIGN_TO (size, 8); + ainfo->storage = ArgVtypeOnStack; + ainfo->offset = cinfo->stack_usage; + ainfo->size = size; + ainfo->hfa = TRUE; + ainfo->nregs = nfields; + ainfo->esize = esize; + cinfo->stack_usage += size; + } + return; + } + + if (align_size > 16) { + ainfo->storage = ArgVtypeByRef; + ainfo->size = size; + return; + } + + if (cinfo->gr + nregs > PARAM_REGS) { + size = ALIGN_TO (size, 8); + ainfo->storage = ArgVtypeOnStack; + ainfo->offset = cinfo->stack_usage; + ainfo->size = size; + cinfo->stack_usage += size; + cinfo->gr = PARAM_REGS; + } else { + ainfo->storage = ArgVtypeInIRegs; + ainfo->reg = cinfo->gr; + ainfo->nregs = nregs; + ainfo->size = size; + cinfo->gr += nregs; + } +} + +static void +add_param (CallInfo *cinfo, ArgInfo *ainfo, MonoType *t) +{ + MonoType *ptype; + + ptype = mini_get_underlying_type (t); + switch (ptype->type) { + case MONO_TYPE_I1: + add_general (cinfo, ainfo, 1, TRUE); + break; + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_U1: + add_general (cinfo, ainfo, 1, FALSE); + break; + case MONO_TYPE_I2: + add_general (cinfo, ainfo, 2, TRUE); + break; + case MONO_TYPE_U2: + case MONO_TYPE_CHAR: + add_general (cinfo, ainfo, 2, FALSE); + break; + case MONO_TYPE_I4: + add_general (cinfo, ainfo, 4, TRUE); + break; + case MONO_TYPE_U4: + add_general (cinfo, ainfo, 4, FALSE); + break; + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_PTR: + case MONO_TYPE_FNPTR: + case MONO_TYPE_CLASS: + case MONO_TYPE_OBJECT: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_ARRAY: + case MONO_TYPE_STRING: + case MONO_TYPE_U8: + case MONO_TYPE_I8: + add_general (cinfo, ainfo, 8, FALSE); + break; + case MONO_TYPE_R8: + add_fp (cinfo, ainfo, FALSE); + break; + case MONO_TYPE_R4: + add_fp (cinfo, ainfo, TRUE); + break; + case MONO_TYPE_VALUETYPE: + case MONO_TYPE_TYPEDBYREF: + add_valuetype (cinfo, ainfo, ptype); + break; + case MONO_TYPE_VOID: + ainfo->storage = ArgNone; + break; + case MONO_TYPE_GENERICINST: + if (!mono_type_generic_inst_is_valuetype (ptype)) { + add_general (cinfo, ainfo, 8, FALSE); + } else if (mini_is_gsharedvt_variable_type (ptype)) { + /* + * Treat gsharedvt arguments as large vtypes + */ + ainfo->storage = ArgVtypeByRef; + ainfo->gsharedvt = TRUE; + } else { + add_valuetype (cinfo, ainfo, ptype); + } + break; + case MONO_TYPE_VAR: + case MONO_TYPE_MVAR: + g_assert (mini_is_gsharedvt_type (ptype)); + ainfo->storage = ArgVtypeByRef; + ainfo->gsharedvt = TRUE; + break; + default: + g_assert_not_reached (); + break; + } +} + +/* + * get_call_info: + * + * Obtain information about a call according to the calling convention. + */ +static CallInfo* +get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) +{ + CallInfo *cinfo; + ArgInfo *ainfo; + int n, pstart, pindex; + + n = sig->hasthis + sig->param_count; + + if (mp) + cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + (sizeof (ArgInfo) * n)); + else + cinfo = g_malloc0 (sizeof (CallInfo) + (sizeof (ArgInfo) * n)); + + cinfo->nargs = n; + + /* Return value */ + add_param (cinfo, &cinfo->ret, sig->ret); + if (cinfo->ret.storage == ArgVtypeByRef) + cinfo->ret.reg = ARMREG_R8; + /* Reset state */ + cinfo->gr = 0; + cinfo->fr = 0; + cinfo->stack_usage = 0; + + /* Parameters */ + if (sig->hasthis) + add_general (cinfo, cinfo->args + 0, 8, FALSE); + pstart = 0; + for (pindex = pstart; pindex < sig->param_count; ++pindex) { + ainfo = cinfo->args + sig->hasthis + pindex; + + if ((sig->call_convention == MONO_CALL_VARARG) && (pindex == sig->sentinelpos)) { + /* Prevent implicit arguments and sig_cookie from + being passed in registers */ + cinfo->gr = PARAM_REGS; + cinfo->fr = FP_PARAM_REGS; + /* Emit the signature cookie just before the implicit arguments */ + add_param (cinfo, &cinfo->sig_cookie, &mono_defaults.int_class->byval_arg); + } + + add_param (cinfo, ainfo, sig->params [pindex]); + if (ainfo->storage == ArgVtypeByRef) { + /* Pass the argument address in the next register */ + if (cinfo->gr >= PARAM_REGS) { + ainfo->storage = ArgVtypeByRefOnStack; + ainfo->offset = cinfo->stack_usage; + cinfo->stack_usage += 8; + } else { + ainfo->reg = cinfo->gr; + cinfo->gr ++; + } + } + } + + /* Handle the case where there are no implicit arguments */ + if ((sig->call_convention == MONO_CALL_VARARG) && (pindex == sig->sentinelpos)) { + /* Prevent implicit arguments and sig_cookie from + being passed in registers */ + cinfo->gr = PARAM_REGS; + cinfo->fr = FP_PARAM_REGS; + /* Emit the signature cookie just before the implicit arguments */ + add_param (cinfo, &cinfo->sig_cookie, &mono_defaults.int_class->byval_arg); + } + + cinfo->stack_usage = ALIGN_TO (cinfo->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + + return cinfo; +} + +typedef struct { + MonoMethodSignature *sig; + CallInfo *cinfo; + MonoType *rtype; + MonoType **param_types; + int n_fpargs, n_fpret; +} ArchDynCallInfo; + +static gboolean +dyn_call_supported (CallInfo *cinfo, MonoMethodSignature *sig) +{ + int i; + + if (sig->hasthis + sig->param_count > PARAM_REGS + DYN_CALL_STACK_ARGS) + return FALSE; + + // FIXME: Add more cases + switch (cinfo->ret.storage) { + case ArgNone: + case ArgInIReg: + case ArgInFReg: + case ArgInFRegR4: + case ArgVtypeByRef: + break; + case ArgVtypeInIRegs: + if (cinfo->ret.nregs > 2) + return FALSE; + break; + case ArgHFA: + break; + default: + return FALSE; + } + + for (i = 0; i < cinfo->nargs; ++i) { + ArgInfo *ainfo = &cinfo->args [i]; + + switch (ainfo->storage) { + case ArgInIReg: + case ArgVtypeInIRegs: + case ArgInFReg: + case ArgInFRegR4: + case ArgHFA: + case ArgVtypeByRef: + break; + case ArgOnStack: + if (ainfo->offset >= DYN_CALL_STACK_ARGS * sizeof (mgreg_t)) + return FALSE; + break; + default: + return FALSE; + } + } + + return TRUE; +} + +MonoDynCallInfo* +mono_arch_dyn_call_prepare (MonoMethodSignature *sig) +{ + ArchDynCallInfo *info; + CallInfo *cinfo; + int i; + + cinfo = get_call_info (NULL, sig); + + if (!dyn_call_supported (cinfo, sig)) { + g_free (cinfo); + return NULL; + } + + info = g_new0 (ArchDynCallInfo, 1); + // FIXME: Preprocess the info to speed up start_dyn_call () + info->sig = sig; + info->cinfo = cinfo; + info->rtype = mini_get_underlying_type (sig->ret); + info->param_types = g_new0 (MonoType*, sig->param_count); + for (i = 0; i < sig->param_count; ++i) + info->param_types [i] = mini_get_underlying_type (sig->params [i]); + + switch (cinfo->ret.storage) { + case ArgInFReg: + case ArgInFRegR4: + info->n_fpret = 1; + break; + case ArgHFA: + info->n_fpret = cinfo->ret.nregs; + break; + default: + break; + } + + return (MonoDynCallInfo*)info; +} + +void +mono_arch_dyn_call_free (MonoDynCallInfo *info) +{ + ArchDynCallInfo *ainfo = (ArchDynCallInfo*)info; + + g_free (ainfo->cinfo); + g_free (ainfo->param_types); + g_free (ainfo); +} + +static double +bitcast_r4_to_r8 (float f) +{ + float *p = &f; + + return *(double*)p; +} + +static float +bitcast_r8_to_r4 (double f) +{ + double *p = &f; + + return *(float*)p; +} + +void +mono_arch_start_dyn_call (MonoDynCallInfo *info, gpointer **args, guint8 *ret, guint8 *buf, int buf_len) +{ + ArchDynCallInfo *dinfo = (ArchDynCallInfo*)info; + DynCallArgs *p = (DynCallArgs*)buf; + int aindex, arg_index, greg, i, pindex; + MonoMethodSignature *sig = dinfo->sig; + CallInfo *cinfo = dinfo->cinfo; + int buffer_offset = 0; + + g_assert (buf_len >= sizeof (DynCallArgs)); + + p->res = 0; + p->ret = ret; + p->n_fpargs = dinfo->n_fpargs; + p->n_fpret = dinfo->n_fpret; + + arg_index = 0; + greg = 0; + pindex = 0; + + if (sig->hasthis) + p->regs [greg ++] = (mgreg_t)*(args [arg_index ++]); + + if (cinfo->ret.storage == ArgVtypeByRef) + p->regs [ARMREG_R8] = (mgreg_t)ret; + + for (aindex = pindex; aindex < sig->param_count; aindex++) { + MonoType *t = dinfo->param_types [aindex]; + gpointer *arg = args [arg_index ++]; + ArgInfo *ainfo = &cinfo->args [aindex + sig->hasthis]; + int slot = -1; + + if (ainfo->storage == ArgOnStack) { + slot = PARAM_REGS + 1 + (ainfo->offset / sizeof (mgreg_t)); + } else { + slot = ainfo->reg; + } + + if (t->byref) { + p->regs [slot] = (mgreg_t)*arg; + continue; + } + + if (ios_abi && ainfo->storage == ArgOnStack) { + guint8 *stack_arg = (guint8*)&(p->regs [PARAM_REGS + 1]) + ainfo->offset; + gboolean handled = TRUE; + + /* Special case arguments smaller than 1 machine word */ + switch (t->type) { + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_U1: + *(guint8*)stack_arg = *(guint8*)arg; + break; + case MONO_TYPE_I1: + *(gint8*)stack_arg = *(gint8*)arg; + break; + case MONO_TYPE_U2: + case MONO_TYPE_CHAR: + *(guint16*)stack_arg = *(guint16*)arg; + break; + case MONO_TYPE_I2: + *(gint16*)stack_arg = *(gint16*)arg; + break; + case MONO_TYPE_I4: + *(gint32*)stack_arg = *(gint32*)arg; + break; + case MONO_TYPE_U4: + *(guint32*)stack_arg = *(guint32*)arg; + break; + default: + handled = FALSE; + break; + } + if (handled) + continue; + } + + switch (t->type) { + case MONO_TYPE_STRING: + case MONO_TYPE_CLASS: + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_OBJECT: + case MONO_TYPE_PTR: + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + p->regs [slot] = (mgreg_t)*arg; + break; + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_U1: + p->regs [slot] = *(guint8*)arg; + break; + case MONO_TYPE_I1: + p->regs [slot] = *(gint8*)arg; + break; + case MONO_TYPE_I2: + p->regs [slot] = *(gint16*)arg; + break; + case MONO_TYPE_U2: + case MONO_TYPE_CHAR: + p->regs [slot] = *(guint16*)arg; + break; + case MONO_TYPE_I4: + p->regs [slot] = *(gint32*)arg; + break; + case MONO_TYPE_U4: + p->regs [slot] = *(guint32*)arg; + break; + case MONO_TYPE_R4: + p->fpregs [ainfo->reg] = bitcast_r4_to_r8 (*(float*)arg); + p->n_fpargs ++; + break; + case MONO_TYPE_R8: + p->fpregs [ainfo->reg] = *(double*)arg; + p->n_fpargs ++; + break; + case MONO_TYPE_GENERICINST: + if (MONO_TYPE_IS_REFERENCE (t)) { + p->regs [slot] = (mgreg_t)*arg; + break; + } else { + if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t))) { + MonoClass *klass = mono_class_from_mono_type (t); + guint8 *nullable_buf; + int size; + + /* + * Use p->buffer as a temporary buffer since the data needs to be available after this call + * if the nullable param is passed by ref. + */ + size = mono_class_value_size (klass, NULL); + nullable_buf = p->buffer + buffer_offset; + buffer_offset += size; + g_assert (buffer_offset <= 256); + + /* The argument pointed to by arg is either a boxed vtype or null */ + mono_nullable_init (nullable_buf, (MonoObject*)arg, klass); + + arg = (gpointer*)nullable_buf; + /* Fall though */ + } else { + /* Fall though */ + } + } + case MONO_TYPE_VALUETYPE: + switch (ainfo->storage) { + case ArgVtypeInIRegs: + for (i = 0; i < ainfo->nregs; ++i) + p->regs [slot ++] = ((mgreg_t*)arg) [i]; + break; + case ArgHFA: + if (ainfo->esize == 4) { + for (i = 0; i < ainfo->nregs; ++i) + p->fpregs [ainfo->reg + i] = bitcast_r4_to_r8 (((float*)arg) [ainfo->foffsets [i] / 4]); + } else { + for (i = 0; i < ainfo->nregs; ++i) + p->fpregs [ainfo->reg + i] = ((double*)arg) [ainfo->foffsets [i] / 8]; + } + p->n_fpargs += ainfo->nregs; + break; + case ArgVtypeByRef: + p->regs [slot] = (mgreg_t)arg; + break; + default: + g_assert_not_reached (); + break; + } + break; + default: + g_assert_not_reached (); + } + } +} + +void +mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf) +{ + ArchDynCallInfo *ainfo = (ArchDynCallInfo*)info; + CallInfo *cinfo = ainfo->cinfo; + DynCallArgs *args = (DynCallArgs*)buf; + MonoType *ptype = ainfo->rtype; + guint8 *ret = args->ret; + mgreg_t res = args->res; + mgreg_t res2 = args->res2; + int i; + + if (cinfo->ret.storage == ArgVtypeByRef) + return; + + switch (ptype->type) { + case MONO_TYPE_VOID: + *(gpointer*)ret = NULL; + break; + case MONO_TYPE_STRING: + case MONO_TYPE_CLASS: + case MONO_TYPE_ARRAY: + case MONO_TYPE_SZARRAY: + case MONO_TYPE_OBJECT: + case MONO_TYPE_I: + case MONO_TYPE_U: + case MONO_TYPE_PTR: + *(gpointer*)ret = (gpointer)res; + break; + case MONO_TYPE_I1: + *(gint8*)ret = res; + break; + case MONO_TYPE_U1: + case MONO_TYPE_BOOLEAN: + *(guint8*)ret = res; + break; + case MONO_TYPE_I2: + *(gint16*)ret = res; + break; + case MONO_TYPE_U2: + case MONO_TYPE_CHAR: + *(guint16*)ret = res; + break; + case MONO_TYPE_I4: + *(gint32*)ret = res; + break; + case MONO_TYPE_U4: + *(guint32*)ret = res; + break; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + *(guint64*)ret = res; + break; + case MONO_TYPE_R4: + *(float*)ret = bitcast_r8_to_r4 (args->fpregs [0]); + break; + case MONO_TYPE_R8: + *(double*)ret = args->fpregs [0]; + break; + case MONO_TYPE_GENERICINST: + if (MONO_TYPE_IS_REFERENCE (ptype)) { + *(gpointer*)ret = (gpointer)res; + break; + } else { + /* Fall though */ + } + case MONO_TYPE_VALUETYPE: + switch (ainfo->cinfo->ret.storage) { + case ArgVtypeInIRegs: + *(mgreg_t*)ret = res; + if (ainfo->cinfo->ret.nregs > 1) + ((mgreg_t*)ret) [1] = res2; + break; + case ArgHFA: + /* Use the same area for returning fp values */ + if (cinfo->ret.esize == 4) { + for (i = 0; i < cinfo->ret.nregs; ++i) + ((float*)ret) [cinfo->ret.foffsets [i] / 4] = bitcast_r8_to_r4 (args->fpregs [i]); + } else { + for (i = 0; i < cinfo->ret.nregs; ++i) + ((double*)ret) [cinfo->ret.foffsets [i] / 8] = args->fpregs [i]; + } + break; + default: + g_assert_not_reached (); + break; + } + break; + default: + g_assert_not_reached (); + } +} + +#if __APPLE__ +void sys_icache_invalidate (void *start, size_t len); +#endif + +void +mono_arch_flush_icache (guint8 *code, gint size) +{ +#ifndef MONO_CROSS_COMPILE +#if __APPLE__ + sys_icache_invalidate (code, size); +#else + __clear_cache (code, code + size); +#endif +#endif +} + +#ifndef DISABLE_JIT + +gboolean +mono_arch_opcode_needs_emulation (MonoCompile *cfg, int opcode) +{ + NOT_IMPLEMENTED; + return FALSE; +} + +GList * +mono_arch_get_allocatable_int_vars (MonoCompile *cfg) +{ + GList *vars = NULL; + int i; + + for (i = 0; i < cfg->num_varinfo; i++) { + MonoInst *ins = cfg->varinfo [i]; + MonoMethodVar *vmv = MONO_VARINFO (cfg, i); + + /* unused vars */ + if (vmv->range.first_use.abs_pos >= vmv->range.last_use.abs_pos) + continue; + + if ((ins->flags & (MONO_INST_IS_DEAD|MONO_INST_VOLATILE|MONO_INST_INDIRECT)) || + (ins->opcode != OP_LOCAL && ins->opcode != OP_ARG)) + continue; + + if (mono_is_regsize_var (ins->inst_vtype)) { + g_assert (MONO_VARINFO (cfg, i)->reg == -1); + g_assert (i == vmv->idx); + vars = g_list_prepend (vars, vmv); + } + } + + vars = mono_varlist_sort (cfg, vars, 0); + + return vars; +} + +GList * +mono_arch_get_global_int_regs (MonoCompile *cfg) +{ + GList *regs = NULL; + int i; + + /* r28 is reserved for cfg->arch.args_reg */ + /* r27 is reserved for the imt argument */ + for (i = ARMREG_R19; i <= ARMREG_R26; ++i) + regs = g_list_prepend (regs, GUINT_TO_POINTER (i)); + + return regs; +} + +guint32 +mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv) +{ + MonoInst *ins = cfg->varinfo [vmv->idx]; + + if (ins->opcode == OP_ARG) + return 1; + else + return 2; +} + +void +mono_arch_create_vars (MonoCompile *cfg) +{ + MonoMethodSignature *sig; + CallInfo *cinfo; + + sig = mono_method_signature (cfg->method); + if (!cfg->arch.cinfo) + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); + cinfo = cfg->arch.cinfo; + + if (cinfo->ret.storage == ArgVtypeByRef) { + cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL); + cfg->vret_addr->flags |= MONO_INST_VOLATILE; + } + + if (cfg->gen_sdb_seq_points) { + MonoInst *ins; + + if (cfg->compile_aot) { + ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL); + ins->flags |= MONO_INST_VOLATILE; + cfg->arch.seq_point_info_var = ins; + } + + ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL); + ins->flags |= MONO_INST_VOLATILE; + cfg->arch.ss_tramp_var = ins; + + ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL); + ins->flags |= MONO_INST_VOLATILE; + cfg->arch.bp_tramp_var = ins; + } + + if (cfg->method->save_lmf) { + cfg->create_lmf_var = TRUE; + cfg->lmf_ir = TRUE; +#ifndef TARGET_MACH + cfg->lmf_ir_mono_lmf = TRUE; +#endif + } +} + +void +mono_arch_allocate_vars (MonoCompile *cfg) +{ + MonoMethodSignature *sig; + MonoInst *ins; + CallInfo *cinfo; + ArgInfo *ainfo; + int i, offset, size, align; + guint32 locals_stack_size, locals_stack_align; + gint32 *offsets; + + /* + * Allocate arguments and locals to either register (OP_REGVAR) or to a stack slot (OP_REGOFFSET). + * Compute cfg->stack_offset and update cfg->used_int_regs. + */ + + sig = mono_method_signature (cfg->method); + + if (!cfg->arch.cinfo) + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); + cinfo = cfg->arch.cinfo; + + /* + * The ARM64 ABI always uses a frame pointer. + * The instruction set prefers positive offsets, so fp points to the bottom of the + * frame, and stack slots are at positive offsets. + * If some arguments are received on the stack, their offsets relative to fp can + * not be computed right now because the stack frame might grow due to spilling + * done by the local register allocator. To solve this, we reserve a register + * which points to them. + * The stack frame looks like this: + * args_reg -> + * + * fp -> + * sp -> + */ + cfg->frame_reg = ARMREG_FP; + cfg->flags |= MONO_CFG_HAS_SPILLUP; + offset = 0; + + /* Saved fp+lr */ + offset += 16; + + if (cinfo->stack_usage) { + g_assert (!(cfg->used_int_regs & (1 << ARMREG_R28))); + cfg->arch.args_reg = ARMREG_R28; + cfg->used_int_regs |= 1 << ARMREG_R28; + } + + if (cfg->method->save_lmf) { + /* The LMF var is allocated normally */ + } else { + /* Callee saved regs */ + cfg->arch.saved_gregs_offset = offset; + for (i = 0; i < 32; ++i) + if ((MONO_ARCH_CALLEE_SAVED_REGS & (1 << i)) && (cfg->used_int_regs & (1 << i))) + offset += 8; + } + + /* Return value */ + switch (cinfo->ret.storage) { + case ArgNone: + break; + case ArgInIReg: + case ArgInFReg: + case ArgInFRegR4: + cfg->ret->opcode = OP_REGVAR; + cfg->ret->dreg = cinfo->ret.reg; + break; + case ArgVtypeInIRegs: + case ArgHFA: + /* Allocate a local to hold the result, the epilog will copy it to the correct place */ + cfg->ret->opcode = OP_REGOFFSET; + cfg->ret->inst_basereg = cfg->frame_reg; + cfg->ret->inst_offset = offset; + if (cinfo->ret.storage == ArgHFA) + // FIXME: + offset += 64; + else + offset += 16; + break; + case ArgVtypeByRef: + /* This variable will be initalized in the prolog from R8 */ + cfg->vret_addr->opcode = OP_REGOFFSET; + cfg->vret_addr->inst_basereg = cfg->frame_reg; + cfg->vret_addr->inst_offset = offset; + offset += 8; + if (G_UNLIKELY (cfg->verbose_level > 1)) { + printf ("vret_addr ="); + mono_print_ins (cfg->vret_addr); + } + break; + default: + g_assert_not_reached (); + break; + } + + /* Arguments */ + for (i = 0; i < sig->param_count + sig->hasthis; ++i) { + ainfo = cinfo->args + i; + + ins = cfg->args [i]; + if (ins->opcode == OP_REGVAR) + continue; + + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + + switch (ainfo->storage) { + case ArgInIReg: + case ArgInFReg: + case ArgInFRegR4: + // FIXME: Use nregs/size + /* These will be copied to the stack in the prolog */ + ins->inst_offset = offset; + offset += 8; + break; + case ArgOnStack: + case ArgOnStackR4: + case ArgOnStackR8: + case ArgVtypeOnStack: + /* These are in the parent frame */ + g_assert (cfg->arch.args_reg); + ins->inst_basereg = cfg->arch.args_reg; + ins->inst_offset = ainfo->offset; + break; + case ArgVtypeInIRegs: + case ArgHFA: + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + /* These arguments are saved to the stack in the prolog */ + ins->inst_offset = offset; + if (cfg->verbose_level >= 2) + printf ("arg %d allocated to %s+0x%0x.\n", i, mono_arch_regname (ins->inst_basereg), (int)ins->inst_offset); + if (ainfo->storage == ArgHFA) + // FIXME: + offset += 64; + else + offset += 16; + break; + case ArgVtypeByRefOnStack: { + MonoInst *vtaddr; + + if (ainfo->gsharedvt) { + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->arch.args_reg; + ins->inst_offset = ainfo->offset; + break; + } + + /* The vtype address is in the parent frame */ + g_assert (cfg->arch.args_reg); + MONO_INST_NEW (cfg, vtaddr, 0); + vtaddr->opcode = OP_REGOFFSET; + vtaddr->inst_basereg = cfg->arch.args_reg; + vtaddr->inst_offset = ainfo->offset; + + /* Need an indirection */ + ins->opcode = OP_VTARG_ADDR; + ins->inst_left = vtaddr; + break; + } + case ArgVtypeByRef: { + MonoInst *vtaddr; + + if (ainfo->gsharedvt) { + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + ins->inst_offset = offset; + offset += 8; + break; + } + + /* The vtype address is in a register, will be copied to the stack in the prolog */ + MONO_INST_NEW (cfg, vtaddr, 0); + vtaddr->opcode = OP_REGOFFSET; + vtaddr->inst_basereg = cfg->frame_reg; + vtaddr->inst_offset = offset; + offset += 8; + + /* Need an indirection */ + ins->opcode = OP_VTARG_ADDR; + ins->inst_left = vtaddr; + break; + } + default: + g_assert_not_reached (); + break; + } + } + + /* Allocate these first so they have a small offset, OP_SEQ_POINT depends on this */ + // FIXME: Allocate these to registers + ins = cfg->arch.seq_point_info_var; + if (ins) { + size = 8; + align = 8; + offset += align - 1; + offset &= ~(align - 1); + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + ins->inst_offset = offset; + offset += size; + } + ins = cfg->arch.ss_tramp_var; + if (ins) { + size = 8; + align = 8; + offset += align - 1; + offset &= ~(align - 1); + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + ins->inst_offset = offset; + offset += size; + } + ins = cfg->arch.bp_tramp_var; + if (ins) { + size = 8; + align = 8; + offset += align - 1; + offset &= ~(align - 1); + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + ins->inst_offset = offset; + offset += size; + } + + /* Locals */ + offsets = mono_allocate_stack_slots (cfg, FALSE, &locals_stack_size, &locals_stack_align); + if (locals_stack_align) + offset = ALIGN_TO (offset, locals_stack_align); + + for (i = cfg->locals_start; i < cfg->num_varinfo; i++) { + if (offsets [i] != -1) { + ins = cfg->varinfo [i]; + ins->opcode = OP_REGOFFSET; + ins->inst_basereg = cfg->frame_reg; + ins->inst_offset = offset + offsets [i]; + //printf ("allocated local %d to ", i); mono_print_tree_nl (ins); + } + } + offset += locals_stack_size; + + offset = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + + cfg->stack_offset = offset; +} + +#ifdef ENABLE_LLVM +LLVMCallInfo* +mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig) +{ + int i, n; + CallInfo *cinfo; + ArgInfo *ainfo; + LLVMCallInfo *linfo; + + n = sig->param_count + sig->hasthis; + + cinfo = get_call_info (cfg->mempool, sig); + + linfo = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n)); + + switch (cinfo->ret.storage) { + case ArgInIReg: + case ArgInFReg: + case ArgInFRegR4: + case ArgNone: + break; + case ArgVtypeByRef: + linfo->ret.storage = LLVMArgVtypeByRef; + break; + // + // FIXME: This doesn't work yet since the llvm backend represents these types as an i8 + // array which is returned in int regs + // + case ArgHFA: + linfo->ret.storage = LLVMArgFpStruct; + linfo->ret.nslots = cinfo->ret.nregs; + linfo->ret.esize = cinfo->ret.esize; + break; + case ArgVtypeInIRegs: + /* LLVM models this by returning an int */ + linfo->ret.storage = LLVMArgVtypeAsScalar; + linfo->ret.nslots = cinfo->ret.nregs; + linfo->ret.esize = cinfo->ret.esize; + break; + default: + g_assert_not_reached (); + break; + } + + for (i = 0; i < n; ++i) { + LLVMArgInfo *lainfo = &linfo->args [i]; + + ainfo = cinfo->args + i; + + lainfo->storage = LLVMArgNone; + + switch (ainfo->storage) { + case ArgInIReg: + case ArgInFReg: + case ArgInFRegR4: + case ArgOnStack: + case ArgOnStackR4: + case ArgOnStackR8: + lainfo->storage = LLVMArgNormal; + break; + case ArgVtypeByRef: + case ArgVtypeByRefOnStack: + lainfo->storage = LLVMArgVtypeByRef; + break; + case ArgHFA: { + int j; + + lainfo->storage = LLVMArgAsFpArgs; + lainfo->nslots = ainfo->nregs; + lainfo->esize = ainfo->esize; + for (j = 0; j < ainfo->nregs; ++j) + lainfo->pair_storage [j] = LLVMArgInFPReg; + break; + } + case ArgVtypeInIRegs: + lainfo->storage = LLVMArgAsIArgs; + lainfo->nslots = ainfo->nregs; + break; + case ArgVtypeOnStack: + if (ainfo->hfa) { + int j; + /* Same as above */ + lainfo->storage = LLVMArgAsFpArgs; + lainfo->nslots = ainfo->nregs; + lainfo->esize = ainfo->esize; + lainfo->ndummy_fpargs = ainfo->nfregs_to_skip; + for (j = 0; j < ainfo->nregs; ++j) + lainfo->pair_storage [j] = LLVMArgInFPReg; + } else { + lainfo->storage = LLVMArgAsIArgs; + lainfo->nslots = ainfo->size / 8; + } + break; + default: + g_assert_not_reached (); + break; + } + } + + return linfo; +} +#endif + +static void +add_outarg_reg (MonoCompile *cfg, MonoCallInst *call, ArgStorage storage, int reg, MonoInst *arg) +{ + MonoInst *ins; + + switch (storage) { + case ArgInIReg: + MONO_INST_NEW (cfg, ins, OP_MOVE); + ins->dreg = mono_alloc_ireg_copy (cfg, arg->dreg); + ins->sreg1 = arg->dreg; + MONO_ADD_INS (cfg->cbb, ins); + mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, FALSE); + break; + case ArgInFReg: + MONO_INST_NEW (cfg, ins, OP_FMOVE); + ins->dreg = mono_alloc_freg (cfg); + ins->sreg1 = arg->dreg; + MONO_ADD_INS (cfg->cbb, ins); + mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, TRUE); + break; + case ArgInFRegR4: + if (COMPILE_LLVM (cfg)) + MONO_INST_NEW (cfg, ins, OP_FMOVE); + else if (cfg->r4fp) + MONO_INST_NEW (cfg, ins, OP_RMOVE); + else + MONO_INST_NEW (cfg, ins, OP_ARM_SETFREG_R4); + ins->dreg = mono_alloc_freg (cfg); + ins->sreg1 = arg->dreg; + MONO_ADD_INS (cfg->cbb, ins); + mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, TRUE); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) +{ + MonoMethodSignature *tmp_sig; + int sig_reg; + + if (call->tail_call) + NOT_IMPLEMENTED; + + g_assert (cinfo->sig_cookie.storage == ArgOnStack); + + /* + * mono_ArgIterator_Setup assumes the signature cookie is + * passed first and all the arguments which were before it are + * passed on the stack after the signature. So compensate by + * passing a different signature. + */ + tmp_sig = mono_metadata_signature_dup (call->signature); + tmp_sig->param_count -= call->signature->sentinelpos; + tmp_sig->sentinelpos = 0; + memcpy (tmp_sig->params, call->signature->params + call->signature->sentinelpos, tmp_sig->param_count * sizeof (MonoType*)); + + sig_reg = mono_alloc_ireg (cfg); + MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig); + + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ARMREG_SP, cinfo->sig_cookie.offset, sig_reg); +} + +void +mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) +{ + MonoMethodSignature *sig; + MonoInst *arg, *vtarg; + CallInfo *cinfo; + ArgInfo *ainfo; + int i; + + sig = call->signature; + + cinfo = get_call_info (cfg->mempool, sig); + + switch (cinfo->ret.storage) { + case ArgVtypeInIRegs: + case ArgHFA: + /* + * The vtype is returned in registers, save the return area address in a local, and save the vtype into + * the location pointed to by it after call in emit_move_return_value (). + */ + if (!cfg->arch.vret_addr_loc) { + cfg->arch.vret_addr_loc = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL); + /* Prevent it from being register allocated or optimized away */ + ((MonoInst*)cfg->arch.vret_addr_loc)->flags |= MONO_INST_VOLATILE; + } + + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, ((MonoInst*)cfg->arch.vret_addr_loc)->dreg, call->vret_var->dreg); + break; + case ArgVtypeByRef: + /* Pass the vtype return address in R8 */ + MONO_INST_NEW (cfg, vtarg, OP_MOVE); + vtarg->sreg1 = call->vret_var->dreg; + vtarg->dreg = mono_alloc_preg (cfg); + MONO_ADD_INS (cfg->cbb, vtarg); + + mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, cinfo->ret.reg, FALSE); + break; + default: + break; + } + + for (i = 0; i < cinfo->nargs; ++i) { + ainfo = cinfo->args + i; + arg = call->args [i]; + + if ((sig->call_convention == MONO_CALL_VARARG) && (i == sig->sentinelpos)) { + /* Emit the signature cookie just before the implicit arguments */ + emit_sig_cookie (cfg, call, cinfo); + } + + switch (ainfo->storage) { + case ArgInIReg: + case ArgInFReg: + case ArgInFRegR4: + add_outarg_reg (cfg, call, ainfo->storage, ainfo->reg, arg); + break; + case ArgOnStack: + switch (ainfo->slot_size) { + case 8: + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ARMREG_SP, ainfo->offset, arg->dreg); + break; + case 4: + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, ARMREG_SP, ainfo->offset, arg->dreg); + break; + case 2: + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI2_MEMBASE_REG, ARMREG_SP, ainfo->offset, arg->dreg); + break; + case 1: + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI1_MEMBASE_REG, ARMREG_SP, ainfo->offset, arg->dreg); + break; + default: + g_assert_not_reached (); + break; + } + break; + case ArgOnStackR8: + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, ARMREG_SP, ainfo->offset, arg->dreg); + break; + case ArgOnStackR4: + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, ARMREG_SP, ainfo->offset, arg->dreg); + break; + case ArgVtypeInIRegs: + case ArgVtypeByRef: + case ArgVtypeByRefOnStack: + case ArgVtypeOnStack: + case ArgHFA: { + MonoInst *ins; + guint32 align; + guint32 size; + + size = mono_class_value_size (arg->klass, &align); + + MONO_INST_NEW (cfg, ins, OP_OUTARG_VT); + ins->sreg1 = arg->dreg; + ins->klass = arg->klass; + ins->backend.size = size; + ins->inst_p0 = call; + ins->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo)); + memcpy (ins->inst_p1, ainfo, sizeof (ArgInfo)); + MONO_ADD_INS (cfg->cbb, ins); + break; + } + default: + g_assert_not_reached (); + break; + } + } + + /* Handle the case where there are no implicit arguments */ + if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (cinfo->nargs == sig->sentinelpos)) + emit_sig_cookie (cfg, call, cinfo); + + call->call_info = cinfo; + call->stack_usage = cinfo->stack_usage; +} + +void +mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) +{ + MonoCallInst *call = (MonoCallInst*)ins->inst_p0; + ArgInfo *ainfo = ins->inst_p1; + MonoInst *load; + int i; + + if (ins->backend.size == 0 && !ainfo->gsharedvt) + return; + + switch (ainfo->storage) { + case ArgVtypeInIRegs: + for (i = 0; i < ainfo->nregs; ++i) { + // FIXME: Smaller sizes + MONO_INST_NEW (cfg, load, OP_LOADI8_MEMBASE); + load->dreg = mono_alloc_ireg (cfg); + load->inst_basereg = src->dreg; + load->inst_offset = i * sizeof(mgreg_t); + MONO_ADD_INS (cfg->cbb, load); + add_outarg_reg (cfg, call, ArgInIReg, ainfo->reg + i, load); + } + break; + case ArgHFA: + for (i = 0; i < ainfo->nregs; ++i) { + if (ainfo->esize == 4) + MONO_INST_NEW (cfg, load, OP_LOADR4_MEMBASE); + else + MONO_INST_NEW (cfg, load, OP_LOADR8_MEMBASE); + load->dreg = mono_alloc_freg (cfg); + load->inst_basereg = src->dreg; + load->inst_offset = ainfo->foffsets [i]; + MONO_ADD_INS (cfg->cbb, load); + add_outarg_reg (cfg, call, ainfo->esize == 4 ? ArgInFRegR4 : ArgInFReg, ainfo->reg + i, load); + } + break; + case ArgVtypeByRef: + case ArgVtypeByRefOnStack: { + MonoInst *vtaddr, *load, *arg; + + /* Pass the vtype address in a reg/on the stack */ + if (ainfo->gsharedvt) { + load = src; + } else { + /* Make a copy of the argument */ + vtaddr = mono_compile_create_var (cfg, &ins->klass->byval_arg, OP_LOCAL); + + MONO_INST_NEW (cfg, load, OP_LDADDR); + load->inst_p0 = vtaddr; + vtaddr->flags |= MONO_INST_INDIRECT; + load->type = STACK_MP; + load->klass = vtaddr->klass; + load->dreg = mono_alloc_ireg (cfg); + MONO_ADD_INS (cfg->cbb, load); + mini_emit_memcpy (cfg, load->dreg, 0, src->dreg, 0, ainfo->size, 8); + } + + if (ainfo->storage == ArgVtypeByRef) { + MONO_INST_NEW (cfg, arg, OP_MOVE); + arg->dreg = mono_alloc_preg (cfg); + arg->sreg1 = load->dreg; + MONO_ADD_INS (cfg->cbb, arg); + add_outarg_reg (cfg, call, ArgInIReg, ainfo->reg, arg); + } else { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ARMREG_SP, ainfo->offset, load->dreg); + } + break; + } + case ArgVtypeOnStack: + for (i = 0; i < ainfo->size / 8; ++i) { + MONO_INST_NEW (cfg, load, OP_LOADI8_MEMBASE); + load->dreg = mono_alloc_ireg (cfg); + load->inst_basereg = src->dreg; + load->inst_offset = i * 8; + MONO_ADD_INS (cfg->cbb, load); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI8_MEMBASE_REG, ARMREG_SP, ainfo->offset + (i * 8), load->dreg); + } + break; + default: + g_assert_not_reached (); + break; + } +} + +void +mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val) +{ + MonoMethodSignature *sig; + CallInfo *cinfo; + + sig = mono_method_signature (cfg->method); + if (!cfg->arch.cinfo) + cfg->arch.cinfo = get_call_info (cfg->mempool, sig); + cinfo = cfg->arch.cinfo; + + switch (cinfo->ret.storage) { + case ArgNone: + break; + case ArgInIReg: + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, cfg->ret->dreg, val->dreg); + break; + case ArgInFReg: + MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, cfg->ret->dreg, val->dreg); + break; + case ArgInFRegR4: + if (COMPILE_LLVM (cfg)) + MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, cfg->ret->dreg, val->dreg); + else if (cfg->r4fp) + MONO_EMIT_NEW_UNALU (cfg, OP_RMOVE, cfg->ret->dreg, val->dreg); + else + MONO_EMIT_NEW_UNALU (cfg, OP_ARM_SETFREG_R4, cfg->ret->dreg, val->dreg); + break; + default: + g_assert_not_reached (); + break; + } +} + +gboolean +mono_arch_tail_call_supported (MonoCompile *cfg, MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) +{ + CallInfo *c1, *c2; + gboolean res; + + if (cfg->compile_aot && !cfg->full_aot) + /* OP_TAILCALL doesn't work with AOT */ + return FALSE; + + c1 = get_call_info (NULL, caller_sig); + c2 = get_call_info (NULL, callee_sig); + res = TRUE; + // FIXME: Relax these restrictions + if (c1->stack_usage != 0) + res = FALSE; + if (c1->stack_usage != c2->stack_usage) + res = FALSE; + if ((c1->ret.storage != ArgNone && c1->ret.storage != ArgInIReg) || c1->ret.storage != c2->ret.storage) + res = FALSE; + + g_free (c1); + g_free (c2); + + return res; +} + +gboolean +mono_arch_is_inst_imm (gint64 imm) +{ + return (imm >= -((gint64)1<<31) && imm <= (((gint64)1<<31)-1)); +} + +void* +mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) +{ + NOT_IMPLEMENTED; + return NULL; +} + +void* +mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers) +{ + NOT_IMPLEMENTED; + return NULL; +} + +void +mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb) +{ + //NOT_IMPLEMENTED; +} + +void +mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb) +{ + //NOT_IMPLEMENTED; +} + +#define ADD_NEW_INS(cfg,dest,op) do { \ + MONO_INST_NEW ((cfg), (dest), (op)); \ + mono_bblock_insert_before_ins (bb, ins, (dest)); \ + } while (0) + +void +mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) +{ + MonoInst *ins, *temp, *last_ins = NULL; + + MONO_BB_FOR_EACH_INS (bb, ins) { + switch (ins->opcode) { + case OP_SBB: + case OP_ISBB: + case OP_SUBCC: + case OP_ISUBCC: + if (ins->next && (ins->next->opcode == OP_COND_EXC_C || ins->next->opcode == OP_COND_EXC_IC)) + /* ARM sets the C flag to 1 if there was _no_ overflow */ + ins->next->opcode = OP_COND_EXC_NC; + break; + case OP_IDIV_IMM: + case OP_IREM_IMM: + case OP_IDIV_UN_IMM: + case OP_IREM_UN_IMM: + case OP_LREM_IMM: + mono_decompose_op_imm (cfg, bb, ins); + break; + case OP_LOCALLOC_IMM: + if (ins->inst_imm > 32) { + ADD_NEW_INS (cfg, temp, OP_ICONST); + temp->inst_c0 = ins->inst_imm; + temp->dreg = mono_alloc_ireg (cfg); + ins->sreg1 = temp->dreg; + ins->opcode = mono_op_imm_to_op (ins->opcode); + } + break; + case OP_ICOMPARE_IMM: + if (ins->inst_imm == 0 && ins->next && ins->next->opcode == OP_IBEQ) { + ins->next->opcode = OP_ARM64_CBZW; + ins->next->sreg1 = ins->sreg1; + NULLIFY_INS (ins); + } else if (ins->inst_imm == 0 && ins->next && ins->next->opcode == OP_IBNE_UN) { + ins->next->opcode = OP_ARM64_CBNZW; + ins->next->sreg1 = ins->sreg1; + NULLIFY_INS (ins); + } + break; + case OP_LCOMPARE_IMM: + case OP_COMPARE_IMM: + if (ins->inst_imm == 0 && ins->next && ins->next->opcode == OP_LBEQ) { + ins->next->opcode = OP_ARM64_CBZX; + ins->next->sreg1 = ins->sreg1; + NULLIFY_INS (ins); + } else if (ins->inst_imm == 0 && ins->next && ins->next->opcode == OP_LBNE_UN) { + ins->next->opcode = OP_ARM64_CBNZX; + ins->next->sreg1 = ins->sreg1; + NULLIFY_INS (ins); + } + break; + case OP_FCOMPARE: { + gboolean swap = FALSE; + int reg; + + if (!ins->next) { + /* Optimized away */ + NULLIFY_INS (ins); + break; + } + + /* + * FP compares with unordered operands set the flags + * to NZCV=0011, which matches some non-unordered compares + * as well, like LE, so have to swap the operands. + */ + switch (ins->next->opcode) { + case OP_FBLT: + ins->next->opcode = OP_FBGT; + swap = TRUE; + break; + case OP_FBLE: + ins->next->opcode = OP_FBGE; + swap = TRUE; + break; + default: + break; + } + if (swap) { + reg = ins->sreg1; + ins->sreg1 = ins->sreg2; + ins->sreg2 = reg; + } + break; + } + default: + break; + } + + last_ins = ins; + } + bb->last_ins = last_ins; + bb->max_vreg = cfg->next_vreg; +} + +void +mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *long_ins) +{ +} + +static int +opcode_to_armcond (int opcode) +{ + switch (opcode) { + case OP_IBEQ: + case OP_LBEQ: + case OP_FBEQ: + case OP_CEQ: + case OP_ICEQ: + case OP_LCEQ: + case OP_FCEQ: + case OP_RCEQ: + case OP_COND_EXC_IEQ: + case OP_COND_EXC_EQ: + return ARMCOND_EQ; + case OP_IBGE: + case OP_LBGE: + case OP_FBGE: + case OP_ICGE: + case OP_FCGE: + case OP_RCGE: + return ARMCOND_GE; + case OP_IBGT: + case OP_LBGT: + case OP_FBGT: + case OP_CGT: + case OP_ICGT: + case OP_LCGT: + case OP_FCGT: + case OP_RCGT: + case OP_COND_EXC_IGT: + case OP_COND_EXC_GT: + return ARMCOND_GT; + case OP_IBLE: + case OP_LBLE: + case OP_FBLE: + case OP_ICLE: + case OP_FCLE: + case OP_RCLE: + return ARMCOND_LE; + case OP_IBLT: + case OP_LBLT: + case OP_FBLT: + case OP_CLT: + case OP_ICLT: + case OP_LCLT: + case OP_COND_EXC_ILT: + case OP_COND_EXC_LT: + return ARMCOND_LT; + case OP_IBNE_UN: + case OP_LBNE_UN: + case OP_FBNE_UN: + case OP_ICNEQ: + case OP_FCNEQ: + case OP_RCNEQ: + case OP_COND_EXC_INE_UN: + case OP_COND_EXC_NE_UN: + return ARMCOND_NE; + case OP_IBGE_UN: + case OP_LBGE_UN: + case OP_FBGE_UN: + case OP_ICGE_UN: + case OP_COND_EXC_IGE_UN: + case OP_COND_EXC_GE_UN: + return ARMCOND_HS; + case OP_IBGT_UN: + case OP_LBGT_UN: + case OP_FBGT_UN: + case OP_CGT_UN: + case OP_ICGT_UN: + case OP_LCGT_UN: + case OP_FCGT_UN: + case OP_RCGT_UN: + case OP_COND_EXC_IGT_UN: + case OP_COND_EXC_GT_UN: + return ARMCOND_HI; + case OP_IBLE_UN: + case OP_LBLE_UN: + case OP_FBLE_UN: + case OP_ICLE_UN: + case OP_COND_EXC_ILE_UN: + case OP_COND_EXC_LE_UN: + return ARMCOND_LS; + case OP_IBLT_UN: + case OP_LBLT_UN: + case OP_FBLT_UN: + case OP_CLT_UN: + case OP_ICLT_UN: + case OP_LCLT_UN: + case OP_COND_EXC_ILT_UN: + case OP_COND_EXC_LT_UN: + return ARMCOND_LO; + /* + * FCMP sets the NZCV condition bits as follows: + * eq = 0110 + * < = 1000 + * > = 0010 + * unordered = 0011 + * ARMCOND_LT is N!=V, so it matches unordered too, so + * fclt and fclt_un need to be special cased. + */ + case OP_FCLT: + case OP_RCLT: + /* N==1 */ + return ARMCOND_MI; + case OP_FCLT_UN: + case OP_RCLT_UN: + return ARMCOND_LT; + case OP_COND_EXC_C: + case OP_COND_EXC_IC: + return ARMCOND_CS; + case OP_COND_EXC_OV: + case OP_COND_EXC_IOV: + return ARMCOND_VS; + case OP_COND_EXC_NC: + case OP_COND_EXC_INC: + return ARMCOND_CC; + case OP_COND_EXC_NO: + case OP_COND_EXC_INO: + return ARMCOND_VC; + default: + printf ("%s\n", mono_inst_name (opcode)); + g_assert_not_reached (); + return -1; + } +} + +/* This clobbers LR */ +static inline __attribute__((warn_unused_result)) guint8* +emit_cond_exc (MonoCompile *cfg, guint8 *code, int opcode, const char *exc_name) +{ + int cond; + + cond = opcode_to_armcond (opcode); + /* Capture PC */ + arm_adrx (code, ARMREG_IP1, code); + mono_add_patch_info_rel (cfg, code - cfg->native_code, MONO_PATCH_INFO_EXC, exc_name, MONO_R_ARM64_BCC); + arm_bcc (code, cond, 0); + return code; +} + +static guint8* +emit_move_return_value (MonoCompile *cfg, guint8 * code, MonoInst *ins) +{ + CallInfo *cinfo; + MonoCallInst *call; + + call = (MonoCallInst*)ins; + cinfo = call->call_info; + g_assert (cinfo); + switch (cinfo->ret.storage) { + case ArgNone: + break; + case ArgInIReg: + /* LLVM compiled code might only set the bottom bits */ + if (call->signature && mini_get_underlying_type (call->signature->ret)->type == MONO_TYPE_I4) + arm_sxtwx (code, call->inst.dreg, cinfo->ret.reg); + else if (call->inst.dreg != cinfo->ret.reg) + arm_movx (code, call->inst.dreg, cinfo->ret.reg); + break; + case ArgInFReg: + if (call->inst.dreg != cinfo->ret.reg) + arm_fmovd (code, call->inst.dreg, cinfo->ret.reg); + break; + case ArgInFRegR4: + if (cfg->r4fp) + arm_fmovs (code, call->inst.dreg, cinfo->ret.reg); + else + arm_fcvt_sd (code, call->inst.dreg, cinfo->ret.reg); + break; + case ArgVtypeInIRegs: { + MonoInst *loc = cfg->arch.vret_addr_loc; + int i; + + /* Load the destination address */ + g_assert (loc && loc->opcode == OP_REGOFFSET); + code = emit_ldrx (code, ARMREG_LR, loc->inst_basereg, loc->inst_offset); + for (i = 0; i < cinfo->ret.nregs; ++i) + arm_strx (code, cinfo->ret.reg + i, ARMREG_LR, i * 8); + break; + } + case ArgHFA: { + MonoInst *loc = cfg->arch.vret_addr_loc; + int i; + + /* Load the destination address */ + g_assert (loc && loc->opcode == OP_REGOFFSET); + code = emit_ldrx (code, ARMREG_LR, loc->inst_basereg, loc->inst_offset); + for (i = 0; i < cinfo->ret.nregs; ++i) { + if (cinfo->ret.esize == 4) + arm_strfpw (code, cinfo->ret.reg + i, ARMREG_LR, cinfo->ret.foffsets [i]); + else + arm_strfpx (code, cinfo->ret.reg + i, ARMREG_LR, cinfo->ret.foffsets [i]); + } + break; + } + case ArgVtypeByRef: + break; + default: + g_assert_not_reached (); + break; + } + return code; +} + +/* + * emit_branch_island: + * + * Emit a branch island for the conditional branches from cfg->native_code + start_offset to code. + */ +static guint8* +emit_branch_island (MonoCompile *cfg, guint8 *code, int start_offset) +{ + MonoJumpInfo *ji; + int offset, island_size; + + /* Iterate over the patch infos added so far by this bb */ + island_size = 0; + for (ji = cfg->patch_info; ji; ji = ji->next) { + if (ji->ip.i < start_offset) + /* The patch infos are in reverse order, so this means the end */ + break; + if (ji->relocation == MONO_R_ARM64_BCC || ji->relocation == MONO_R_ARM64_CBZ) + island_size += 4; + } + + if (island_size) { + offset = code - cfg->native_code; + if (offset > (cfg->code_size - island_size - 16)) { + cfg->code_size *= 2; + cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); + code = cfg->native_code + offset; + } + + /* Branch over the island */ + arm_b (code, code + 4 + island_size); + + for (ji = cfg->patch_info; ji; ji = ji->next) { + if (ji->ip.i < start_offset) + break; + if (ji->relocation == MONO_R_ARM64_BCC || ji->relocation == MONO_R_ARM64_CBZ) { + /* Rewrite the cond branch so it branches to an uncoditional branch in the branch island */ + arm_patch_rel (cfg->native_code + ji->ip.i, code, ji->relocation); + /* Rewrite the patch so it points to the unconditional branch */ + ji->ip.i = code - cfg->native_code; + ji->relocation = MONO_R_ARM64_B; + arm_b (code, code); + } + } + } + return code; +} + +void +mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) +{ + MonoInst *ins; + MonoCallInst *call; + guint offset; + guint8 *code = cfg->native_code + cfg->code_len; + int start_offset, max_len, dreg, sreg1, sreg2; + mgreg_t imm; + + if (cfg->verbose_level > 2) + g_print ("Basic block %d starting at offset 0x%x\n", bb->block_num, bb->native_offset); + + start_offset = code - cfg->native_code; + + MONO_BB_FOR_EACH_INS (bb, ins) { + offset = code - cfg->native_code; + + max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN]; + + if (offset > (cfg->code_size - max_len - 16)) { + cfg->code_size *= 2; + cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); + code = cfg->native_code + offset; + } + + if (G_UNLIKELY (cfg->arch.cond_branch_islands && offset - start_offset > 4 * 0x1ffff)) { + /* Emit a branch island for large basic blocks */ + code = emit_branch_island (cfg, code, start_offset); + offset = code - cfg->native_code; + start_offset = offset; + } + + mono_debug_record_line_number (cfg, ins, offset); + + dreg = ins->dreg; + sreg1 = ins->sreg1; + sreg2 = ins->sreg2; + imm = ins->inst_imm; + + switch (ins->opcode) { + case OP_ICONST: + code = emit_imm (code, dreg, ins->inst_c0); + break; + case OP_I8CONST: + code = emit_imm64 (code, dreg, ins->inst_c0); + break; + case OP_MOVE: + if (dreg != sreg1) + arm_movx (code, dreg, sreg1); + break; + case OP_NOP: + case OP_RELAXED_NOP: + break; + case OP_JUMP_TABLE: + mono_add_patch_info_rel (cfg, offset, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0, MONO_R_ARM64_IMM); + code = emit_imm64_template (code, dreg); + break; + case OP_BREAK: + /* + * gdb does not like encountering the hw breakpoint ins in the debugged code. + * So instead of emitting a trap, we emit a call a C function and place a + * breakpoint there. + */ + code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_break"); + break; + case OP_LOCALLOC: { + guint8 *buf [16]; + + arm_addx_imm (code, ARMREG_IP0, sreg1, (MONO_ARCH_FRAME_ALIGNMENT - 1)); + // FIXME: andx_imm doesn't work yet + code = emit_imm (code, ARMREG_IP1, -MONO_ARCH_FRAME_ALIGNMENT); + arm_andx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); + //arm_andx_imm (code, ARMREG_IP0, sreg1, - MONO_ARCH_FRAME_ALIGNMENT); + arm_movspx (code, ARMREG_IP1, ARMREG_SP); + arm_subx (code, ARMREG_IP1, ARMREG_IP1, ARMREG_IP0); + arm_movspx (code, ARMREG_SP, ARMREG_IP1); + + /* Init */ + /* ip1 = pointer, ip0 = end */ + arm_addx (code, ARMREG_IP0, ARMREG_IP1, ARMREG_IP0); + buf [0] = code; + arm_cmpx (code, ARMREG_IP1, ARMREG_IP0); + buf [1] = code; + arm_bcc (code, ARMCOND_EQ, 0); + arm_stpx (code, ARMREG_RZR, ARMREG_RZR, ARMREG_IP1, 0); + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 16); + arm_b (code, buf [0]); + arm_patch_rel (buf [1], code, MONO_R_ARM64_BCC); + + arm_movspx (code, dreg, ARMREG_SP); + if (cfg->param_area) + code = emit_subx_sp_imm (code, cfg->param_area); + break; + } + case OP_LOCALLOC_IMM: { + int imm, offset; + + imm = ALIGN_TO (ins->inst_imm, MONO_ARCH_FRAME_ALIGNMENT); + g_assert (arm_is_arith_imm (imm)); + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, imm); + + /* Init */ + g_assert (MONO_ARCH_FRAME_ALIGNMENT == 16); + offset = 0; + while (offset < imm) { + arm_stpx (code, ARMREG_RZR, ARMREG_RZR, ARMREG_SP, offset); + offset += 16; + } + arm_movspx (code, dreg, ARMREG_SP); + if (cfg->param_area) + code = emit_subx_sp_imm (code, cfg->param_area); + break; + } + case OP_AOTCONST: + code = emit_aotconst (cfg, code, dreg, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0); + break; + case OP_OBJC_GET_SELECTOR: + mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_OBJC_SELECTOR_REF, ins->inst_p0); + /* See arch_emit_objc_selector_ref () in aot-compiler.c */ + arm_ldrx_lit (code, ins->dreg, 0); + arm_nop (code); + arm_nop (code); + break; + case OP_SEQ_POINT: { + MonoInst *info_var = cfg->arch.seq_point_info_var; + + /* + * For AOT, we use one got slot per method, which will point to a + * SeqPointInfo structure, containing all the information required + * by the code below. + */ + if (cfg->compile_aot) { + g_assert (info_var); + g_assert (info_var->opcode == OP_REGOFFSET); + } + + if (ins->flags & MONO_INST_SINGLE_STEP_LOC) { + MonoInst *var = cfg->arch.ss_tramp_var; + + g_assert (var); + g_assert (var->opcode == OP_REGOFFSET); + /* Load ss_tramp_var */ + /* This is equal to &ss_trampoline */ + arm_ldrx (code, ARMREG_IP1, var->inst_basereg, var->inst_offset); + /* Load the trampoline address */ + arm_ldrx (code, ARMREG_IP1, ARMREG_IP1, 0); + /* Call it if it is non-null */ + arm_cbzx (code, ARMREG_IP1, code + 8); + arm_blrx (code, ARMREG_IP1); + } + + mono_add_seq_point (cfg, bb, ins, code - cfg->native_code); + + if (cfg->compile_aot) { + guint32 offset = code - cfg->native_code; + guint32 val; + + arm_ldrx (code, ARMREG_IP1, info_var->inst_basereg, info_var->inst_offset); + /* Add the offset */ + val = ((offset / 4) * sizeof (guint8*)) + MONO_STRUCT_OFFSET (SeqPointInfo, bp_addrs); + /* Load the info->bp_addrs [offset], which is either 0 or the address of the bp trampoline */ + code = emit_ldrx (code, ARMREG_IP1, ARMREG_IP1, val); + /* Skip the load if its 0 */ + arm_cbzx (code, ARMREG_IP1, code + 8); + /* Call the breakpoint trampoline */ + arm_blrx (code, ARMREG_IP1); + } else { + MonoInst *var = cfg->arch.bp_tramp_var; + + g_assert (var); + g_assert (var->opcode == OP_REGOFFSET); + /* Load the address of the bp trampoline into IP0 */ + arm_ldrx (code, ARMREG_IP0, var->inst_basereg, var->inst_offset); + /* + * A placeholder for a possible breakpoint inserted by + * mono_arch_set_breakpoint (). + */ + arm_nop (code); + } + break; + } + + /* BRANCH */ + case OP_BR: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb, MONO_R_ARM64_B); + arm_b (code, code); + break; + case OP_BR_REG: + arm_brx (code, sreg1); + break; + case OP_IBEQ: + case OP_IBGE: + case OP_IBGT: + case OP_IBLE: + case OP_IBLT: + case OP_IBNE_UN: + case OP_IBGE_UN: + case OP_IBGT_UN: + case OP_IBLE_UN: + case OP_IBLT_UN: + case OP_LBEQ: + case OP_LBGE: + case OP_LBGT: + case OP_LBLE: + case OP_LBLT: + case OP_LBNE_UN: + case OP_LBGE_UN: + case OP_LBGT_UN: + case OP_LBLE_UN: + case OP_LBLT_UN: + case OP_FBEQ: + case OP_FBNE_UN: + case OP_FBLT: + case OP_FBGT: + case OP_FBGT_UN: + case OP_FBLE: + case OP_FBGE: + case OP_FBGE_UN: { + int cond; + + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_BCC); + cond = opcode_to_armcond (ins->opcode); + arm_bcc (code, cond, 0); + break; + } + case OP_FBLT_UN: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_BCC); + /* For fp compares, ARMCOND_LT is lt or unordered */ + arm_bcc (code, ARMCOND_LT, 0); + break; + case OP_FBLE_UN: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_BCC); + arm_bcc (code, ARMCOND_EQ, 0); + offset = code - cfg->native_code; + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_BCC); + /* For fp compares, ARMCOND_LT is lt or unordered */ + arm_bcc (code, ARMCOND_LT, 0); + break; + case OP_ARM64_CBZW: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_CBZ); + arm_cbzw (code, sreg1, 0); + break; + case OP_ARM64_CBZX: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_CBZ); + arm_cbzx (code, sreg1, 0); + break; + case OP_ARM64_CBNZW: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_CBZ); + arm_cbnzw (code, sreg1, 0); + break; + case OP_ARM64_CBNZX: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_true_bb, MONO_R_ARM64_CBZ); + arm_cbnzx (code, sreg1, 0); + break; + /* ALU */ + case OP_IADD: + arm_addw (code, dreg, sreg1, sreg2); + break; + case OP_LADD: + arm_addx (code, dreg, sreg1, sreg2); + break; + case OP_ISUB: + arm_subw (code, dreg, sreg1, sreg2); + break; + case OP_LSUB: + arm_subx (code, dreg, sreg1, sreg2); + break; + case OP_IAND: + arm_andw (code, dreg, sreg1, sreg2); + break; + case OP_LAND: + arm_andx (code, dreg, sreg1, sreg2); + break; + case OP_IOR: + arm_orrw (code, dreg, sreg1, sreg2); + break; + case OP_LOR: + arm_orrx (code, dreg, sreg1, sreg2); + break; + case OP_IXOR: + arm_eorw (code, dreg, sreg1, sreg2); + break; + case OP_LXOR: + arm_eorx (code, dreg, sreg1, sreg2); + break; + case OP_INEG: + arm_negw (code, dreg, sreg1); + break; + case OP_LNEG: + arm_negx (code, dreg, sreg1); + break; + case OP_INOT: + arm_mvnw (code, dreg, sreg1); + break; + case OP_LNOT: + arm_mvnx (code, dreg, sreg1); + break; + case OP_IADDCC: + arm_addsw (code, dreg, sreg1, sreg2); + break; + case OP_ADDCC: + case OP_LADDCC: + arm_addsx (code, dreg, sreg1, sreg2); + break; + case OP_ISUBCC: + arm_subsw (code, dreg, sreg1, sreg2); + break; + case OP_LSUBCC: + case OP_SUBCC: + arm_subsx (code, dreg, sreg1, sreg2); + break; + case OP_ICOMPARE: + arm_cmpw (code, sreg1, sreg2); + break; + case OP_COMPARE: + case OP_LCOMPARE: + arm_cmpx (code, sreg1, sreg2); + break; + case OP_IADD_IMM: + code = emit_addw_imm (code, dreg, sreg1, imm); + break; + case OP_LADD_IMM: + case OP_ADD_IMM: + code = emit_addx_imm (code, dreg, sreg1, imm); + break; + case OP_ISUB_IMM: + code = emit_subw_imm (code, dreg, sreg1, imm); + break; + case OP_LSUB_IMM: + code = emit_subx_imm (code, dreg, sreg1, imm); + break; + case OP_IAND_IMM: + code = emit_andw_imm (code, dreg, sreg1, imm); + break; + case OP_LAND_IMM: + case OP_AND_IMM: + code = emit_andx_imm (code, dreg, sreg1, imm); + break; + case OP_IOR_IMM: + code = emit_orrw_imm (code, dreg, sreg1, imm); + break; + case OP_LOR_IMM: + code = emit_orrx_imm (code, dreg, sreg1, imm); + break; + case OP_IXOR_IMM: + code = emit_eorw_imm (code, dreg, sreg1, imm); + break; + case OP_LXOR_IMM: + code = emit_eorx_imm (code, dreg, sreg1, imm); + break; + case OP_ICOMPARE_IMM: + code = emit_cmpw_imm (code, sreg1, imm); + break; + case OP_LCOMPARE_IMM: + case OP_COMPARE_IMM: + if (imm == 0) { + arm_cmpx (code, sreg1, ARMREG_RZR); + } else { + // FIXME: 32 vs 64 bit issues for 0xffffffff + code = emit_imm64 (code, ARMREG_LR, imm); + arm_cmpx (code, sreg1, ARMREG_LR); + } + break; + case OP_ISHL: + arm_lslvw (code, dreg, sreg1, sreg2); + break; + case OP_LSHL: + arm_lslvx (code, dreg, sreg1, sreg2); + break; + case OP_ISHR: + arm_asrvw (code, dreg, sreg1, sreg2); + break; + case OP_LSHR: + arm_asrvx (code, dreg, sreg1, sreg2); + break; + case OP_ISHR_UN: + arm_lsrvw (code, dreg, sreg1, sreg2); + break; + case OP_LSHR_UN: + arm_lsrvx (code, dreg, sreg1, sreg2); + break; + case OP_ISHL_IMM: + if (imm == 0) + arm_movx (code, dreg, sreg1); + else + arm_lslw (code, dreg, sreg1, imm); + break; + case OP_LSHL_IMM: + if (imm == 0) + arm_movx (code, dreg, sreg1); + else + arm_lslx (code, dreg, sreg1, imm); + break; + case OP_ISHR_IMM: + if (imm == 0) + arm_movx (code, dreg, sreg1); + else + arm_asrw (code, dreg, sreg1, imm); + break; + case OP_LSHR_IMM: + case OP_SHR_IMM: + if (imm == 0) + arm_movx (code, dreg, sreg1); + else + arm_asrx (code, dreg, sreg1, imm); + break; + case OP_ISHR_UN_IMM: + if (imm == 0) + arm_movx (code, dreg, sreg1); + else + arm_lsrw (code, dreg, sreg1, imm); + break; + case OP_SHR_UN_IMM: + case OP_LSHR_UN_IMM: + if (imm == 0) + arm_movx (code, dreg, sreg1); + else + arm_lsrx (code, dreg, sreg1, imm); + break; + + /* 64BIT ALU */ + case OP_SEXT_I4: + arm_sxtwx (code, dreg, sreg1); + break; + case OP_ZEXT_I4: + /* Clean out the upper word */ + arm_movw (code, dreg, sreg1); + break; + case OP_SHL_IMM: + arm_lslx (code, dreg, sreg1, imm); + break; + + /* MULTIPLY/DIVISION */ + case OP_IDIV: + case OP_IREM: + // FIXME: Optimize this + /* Check for zero */ + arm_cmpx_imm (code, sreg2, 0); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "DivideByZeroException"); + /* Check for INT_MIN/-1 */ + code = emit_imm (code, ARMREG_IP0, 0x80000000); + arm_cmpx (code, sreg1, ARMREG_IP0); + arm_cset (code, ARMCOND_EQ, ARMREG_IP1); + code = emit_imm (code, ARMREG_IP0, 0xffffffff); + arm_cmpx (code, sreg2, ARMREG_IP0); + arm_cset (code, ARMCOND_EQ, ARMREG_IP0); + arm_andx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); + arm_cmpx_imm (code, ARMREG_IP0, 1); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "OverflowException"); + if (ins->opcode == OP_IREM) { + arm_sdivw (code, ARMREG_LR, sreg1, sreg2); + arm_msubw (code, dreg, ARMREG_LR, sreg2, sreg1); + } else { + arm_sdivw (code, dreg, sreg1, sreg2); + } + break; + case OP_IDIV_UN: + arm_cmpx_imm (code, sreg2, 0); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "DivideByZeroException"); + arm_udivw (code, dreg, sreg1, sreg2); + break; + case OP_IREM_UN: + arm_cmpx_imm (code, sreg2, 0); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "DivideByZeroException"); + arm_udivw (code, ARMREG_LR, sreg1, sreg2); + arm_msubw (code, dreg, ARMREG_LR, sreg2, sreg1); + break; + case OP_LDIV: + case OP_LREM: + // FIXME: Optimize this + /* Check for zero */ + arm_cmpx_imm (code, sreg2, 0); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "DivideByZeroException"); + /* Check for INT64_MIN/-1 */ + code = emit_imm64 (code, ARMREG_IP0, 0x8000000000000000); + arm_cmpx (code, sreg1, ARMREG_IP0); + arm_cset (code, ARMCOND_EQ, ARMREG_IP1); + code = emit_imm64 (code, ARMREG_IP0, 0xffffffffffffffff); + arm_cmpx (code, sreg2, ARMREG_IP0); + arm_cset (code, ARMCOND_EQ, ARMREG_IP0); + arm_andx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); + arm_cmpx_imm (code, ARMREG_IP0, 1); + /* 64 bit uses ArithmeticException */ + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "ArithmeticException"); + if (ins->opcode == OP_LREM) { + arm_sdivx (code, ARMREG_LR, sreg1, sreg2); + arm_msubx (code, dreg, ARMREG_LR, sreg2, sreg1); + } else { + arm_sdivx (code, dreg, sreg1, sreg2); + } + break; + case OP_LDIV_UN: + arm_cmpx_imm (code, sreg2, 0); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "DivideByZeroException"); + arm_udivx (code, dreg, sreg1, sreg2); + break; + case OP_LREM_UN: + arm_cmpx_imm (code, sreg2, 0); + code = emit_cond_exc (cfg, code, OP_COND_EXC_IEQ, "DivideByZeroException"); + arm_udivx (code, ARMREG_LR, sreg1, sreg2); + arm_msubx (code, dreg, ARMREG_LR, sreg2, sreg1); + break; + case OP_IMUL: + arm_mulw (code, dreg, sreg1, sreg2); + break; + case OP_LMUL: + arm_mulx (code, dreg, sreg1, sreg2); + break; + case OP_IMUL_IMM: + code = emit_imm (code, ARMREG_LR, imm); + arm_mulw (code, dreg, sreg1, ARMREG_LR); + break; + case OP_MUL_IMM: + case OP_LMUL_IMM: + code = emit_imm (code, ARMREG_LR, imm); + arm_mulx (code, dreg, sreg1, ARMREG_LR); + break; + + /* CONVERSIONS */ + case OP_ICONV_TO_I1: + case OP_LCONV_TO_I1: + arm_sxtbx (code, dreg, sreg1); + break; + case OP_ICONV_TO_I2: + case OP_LCONV_TO_I2: + arm_sxthx (code, dreg, sreg1); + break; + case OP_ICONV_TO_U1: + case OP_LCONV_TO_U1: + arm_uxtbw (code, dreg, sreg1); + break; + case OP_ICONV_TO_U2: + case OP_LCONV_TO_U2: + arm_uxthw (code, dreg, sreg1); + break; + + /* CSET */ + case OP_CEQ: + case OP_ICEQ: + case OP_LCEQ: + case OP_CLT: + case OP_ICLT: + case OP_LCLT: + case OP_CGT: + case OP_ICGT: + case OP_LCGT: + case OP_CLT_UN: + case OP_ICLT_UN: + case OP_LCLT_UN: + case OP_CGT_UN: + case OP_ICGT_UN: + case OP_LCGT_UN: + case OP_ICNEQ: + case OP_ICGE: + case OP_ICLE: + case OP_ICGE_UN: + case OP_ICLE_UN: { + int cond; + + cond = opcode_to_armcond (ins->opcode); + arm_cset (code, cond, dreg); + break; + } + case OP_FCEQ: + case OP_FCLT: + case OP_FCLT_UN: + case OP_FCGT: + case OP_FCGT_UN: + case OP_FCNEQ: + case OP_FCLE: + case OP_FCGE: { + int cond; + + cond = opcode_to_armcond (ins->opcode); + arm_fcmpd (code, sreg1, sreg2); + arm_cset (code, cond, dreg); + break; + } + + /* MEMORY */ + case OP_LOADI1_MEMBASE: + code = emit_ldrsbx (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOADU1_MEMBASE: + code = emit_ldrb (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOADI2_MEMBASE: + code = emit_ldrshx (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOADU2_MEMBASE: + code = emit_ldrh (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOADI4_MEMBASE: + code = emit_ldrswx (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOADU4_MEMBASE: + code = emit_ldrw (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOAD_MEMBASE: + case OP_LOADI8_MEMBASE: + code = emit_ldrx (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_STOREI1_MEMBASE_IMM: + case OP_STOREI2_MEMBASE_IMM: + case OP_STOREI4_MEMBASE_IMM: + case OP_STORE_MEMBASE_IMM: + case OP_STOREI8_MEMBASE_IMM: { + int immreg; + + if (imm != 0) { + code = emit_imm (code, ARMREG_LR, imm); + immreg = ARMREG_LR; + } else { + immreg = ARMREG_RZR; + } + + switch (ins->opcode) { + case OP_STOREI1_MEMBASE_IMM: + code = emit_strb (code, immreg, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STOREI2_MEMBASE_IMM: + code = emit_strh (code, immreg, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STOREI4_MEMBASE_IMM: + code = emit_strw (code, immreg, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STORE_MEMBASE_IMM: + case OP_STOREI8_MEMBASE_IMM: + code = emit_strx (code, immreg, ins->inst_destbasereg, ins->inst_offset); + break; + default: + g_assert_not_reached (); + break; + } + break; + } + case OP_STOREI1_MEMBASE_REG: + code = emit_strb (code, sreg1, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STOREI2_MEMBASE_REG: + code = emit_strh (code, sreg1, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STOREI4_MEMBASE_REG: + code = emit_strw (code, sreg1, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STORE_MEMBASE_REG: + case OP_STOREI8_MEMBASE_REG: + code = emit_strx (code, sreg1, ins->inst_destbasereg, ins->inst_offset); + break; + + case OP_TLS_GET: + code = emit_tls_get (code, dreg, ins->inst_offset); + break; + case OP_TLS_GET_REG: + code = emit_tls_get_reg (code, dreg, sreg1); + break; + case OP_TLS_SET: + code = emit_tls_set (code, sreg1, ins->inst_offset); + break; + case OP_TLS_SET_REG: + code = emit_tls_set_reg (code, sreg1, sreg2); + break; + + /* Atomic */ + case OP_MEMORY_BARRIER: + arm_dmb (code, 0); + break; + case OP_ATOMIC_ADD_I4: { + guint8 *buf [16]; + + buf [0] = code; + arm_ldaxrw (code, ARMREG_IP0, sreg1); + arm_addx (code, ARMREG_IP0, ARMREG_IP0, sreg2); + arm_stlxrw (code, ARMREG_IP1, ARMREG_IP0, sreg1); + arm_cbnzw (code, ARMREG_IP1, buf [0]); + + arm_movx (code, dreg, ARMREG_IP0); + break; + } + case OP_ATOMIC_ADD_I8: { + guint8 *buf [16]; + + buf [0] = code; + arm_ldaxrx (code, ARMREG_IP0, sreg1); + arm_addx (code, ARMREG_IP0, ARMREG_IP0, sreg2); + arm_stlxrx (code, ARMREG_IP1, ARMREG_IP0, sreg1); + arm_cbnzx (code, ARMREG_IP1, buf [0]); + + arm_movx (code, dreg, ARMREG_IP0); + break; + } + case OP_ATOMIC_EXCHANGE_I4: { + guint8 *buf [16]; + + buf [0] = code; + arm_ldaxrw (code, ARMREG_IP0, sreg1); + arm_stlxrw (code, ARMREG_IP1, sreg2, sreg1); + arm_cbnzw (code, ARMREG_IP1, buf [0]); + + arm_movx (code, dreg, ARMREG_IP0); + break; + } + case OP_ATOMIC_EXCHANGE_I8: { + guint8 *buf [16]; + + buf [0] = code; + arm_ldaxrx (code, ARMREG_IP0, sreg1); + arm_stlxrx (code, ARMREG_IP1, sreg2, sreg1); + arm_cbnzw (code, ARMREG_IP1, buf [0]); + + arm_movx (code, dreg, ARMREG_IP0); + break; + } + case OP_ATOMIC_CAS_I4: { + guint8 *buf [16]; + + /* sreg2 is the value, sreg3 is the comparand */ + buf [0] = code; + arm_ldaxrw (code, ARMREG_IP0, sreg1); + arm_cmpw (code, ARMREG_IP0, ins->sreg3); + buf [1] = code; + arm_bcc (code, ARMCOND_NE, 0); + arm_stlxrw (code, ARMREG_IP1, sreg2, sreg1); + arm_cbnzw (code, ARMREG_IP1, buf [0]); + arm_patch_rel (buf [1], code, MONO_R_ARM64_BCC); + + arm_movx (code, dreg, ARMREG_IP0); + break; + } + case OP_ATOMIC_CAS_I8: { + guint8 *buf [16]; + + buf [0] = code; + arm_ldaxrx (code, ARMREG_IP0, sreg1); + arm_cmpx (code, ARMREG_IP0, ins->sreg3); + buf [1] = code; + arm_bcc (code, ARMCOND_NE, 0); + arm_stlxrx (code, ARMREG_IP1, sreg2, sreg1); + arm_cbnzw (code, ARMREG_IP1, buf [0]); + arm_patch_rel (buf [1], code, MONO_R_ARM64_BCC); + + arm_movx (code, dreg, ARMREG_IP0); + break; + } + case OP_ATOMIC_LOAD_I1: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarb (code, ins->dreg, ARMREG_LR); + arm_sxtbx (code, ins->dreg, ins->dreg); + break; + } + case OP_ATOMIC_LOAD_U1: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarb (code, ins->dreg, ARMREG_LR); + arm_uxtbx (code, ins->dreg, ins->dreg); + break; + } + case OP_ATOMIC_LOAD_I2: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarh (code, ins->dreg, ARMREG_LR); + arm_sxthx (code, ins->dreg, ins->dreg); + break; + } + case OP_ATOMIC_LOAD_U2: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarh (code, ins->dreg, ARMREG_LR); + arm_uxthx (code, ins->dreg, ins->dreg); + break; + } + case OP_ATOMIC_LOAD_I4: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarw (code, ins->dreg, ARMREG_LR); + arm_sxtwx (code, ins->dreg, ins->dreg); + break; + } + case OP_ATOMIC_LOAD_U4: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarw (code, ins->dreg, ARMREG_LR); + arm_movw (code, ins->dreg, ins->dreg); /* Clear upper half of the register. */ + break; + } + case OP_ATOMIC_LOAD_I8: + case OP_ATOMIC_LOAD_U8: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarx (code, ins->dreg, ARMREG_LR); + break; + } + case OP_ATOMIC_LOAD_R4: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + if (cfg->r4fp) { + arm_ldarw (code, ARMREG_LR, ARMREG_LR); + arm_fmov_rx_to_double (code, ins->dreg, ARMREG_LR); + } else { + arm_ldarw (code, ARMREG_LR, ARMREG_LR); + arm_fmov_rx_to_double (code, FP_TEMP_REG, ARMREG_LR); + arm_fcvt_sd (code, ins->dreg, FP_TEMP_REG); + } + break; + } + case OP_ATOMIC_LOAD_R8: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_basereg, ins->inst_offset); + arm_ldarx (code, ARMREG_LR, ARMREG_LR); + arm_fmov_rx_to_double (code, ins->dreg, ARMREG_LR); + break; + } + case OP_ATOMIC_STORE_I1: + case OP_ATOMIC_STORE_U1: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_destbasereg, ins->inst_offset); + arm_stlrb (code, ARMREG_LR, ins->sreg1); + break; + } + case OP_ATOMIC_STORE_I2: + case OP_ATOMIC_STORE_U2: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_destbasereg, ins->inst_offset); + arm_stlrh (code, ARMREG_LR, ins->sreg1); + break; + } + case OP_ATOMIC_STORE_I4: + case OP_ATOMIC_STORE_U4: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_destbasereg, ins->inst_offset); + arm_stlrw (code, ARMREG_LR, ins->sreg1); + break; + } + case OP_ATOMIC_STORE_I8: + case OP_ATOMIC_STORE_U8: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_destbasereg, ins->inst_offset); + arm_stlrx (code, ARMREG_LR, ins->sreg1); + break; + } + case OP_ATOMIC_STORE_R4: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_destbasereg, ins->inst_offset); + if (cfg->r4fp) { + arm_fmov_double_to_rx (code, ARMREG_IP0, ins->sreg1); + arm_stlrw (code, ARMREG_LR, ARMREG_IP0); + } else { + arm_fcvt_ds (code, FP_TEMP_REG, ins->sreg1); + arm_fmov_double_to_rx (code, ARMREG_IP0, FP_TEMP_REG); + arm_stlrw (code, ARMREG_LR, ARMREG_IP0); + } + break; + } + case OP_ATOMIC_STORE_R8: { + code = emit_addx_imm (code, ARMREG_LR, ins->inst_destbasereg, ins->inst_offset); + arm_fmov_double_to_rx (code, ARMREG_IP0, ins->sreg1); + arm_stlrx (code, ARMREG_LR, ARMREG_IP0); + break; + } + + /* FP */ + case OP_R8CONST: { + guint64 imm = *(guint64*)ins->inst_p0; + + if (imm == 0) { + arm_fmov_rx_to_double (code, dreg, ARMREG_RZR); + } else { + code = emit_imm64 (code, ARMREG_LR, imm); + arm_fmov_rx_to_double (code, ins->dreg, ARMREG_LR); + } + break; + } + case OP_R4CONST: { + guint64 imm = *(guint32*)ins->inst_p0; + + code = emit_imm64 (code, ARMREG_LR, imm); + if (cfg->r4fp) { + arm_fmov_rx_to_double (code, dreg, ARMREG_LR); + } else { + arm_fmov_rx_to_double (code, FP_TEMP_REG, ARMREG_LR); + arm_fcvt_sd (code, dreg, FP_TEMP_REG); + } + break; + } + case OP_LOADR8_MEMBASE: + code = emit_ldrfpx (code, dreg, ins->inst_basereg, ins->inst_offset); + break; + case OP_LOADR4_MEMBASE: + if (cfg->r4fp) { + code = emit_ldrfpw (code, dreg, ins->inst_basereg, ins->inst_offset); + } else { + code = emit_ldrfpw (code, FP_TEMP_REG, ins->inst_basereg, ins->inst_offset); + arm_fcvt_sd (code, dreg, FP_TEMP_REG); + } + break; + case OP_STORER8_MEMBASE_REG: + code = emit_strfpx (code, sreg1, ins->inst_destbasereg, ins->inst_offset); + break; + case OP_STORER4_MEMBASE_REG: + if (cfg->r4fp) { + code = emit_strfpw (code, sreg1, ins->inst_destbasereg, ins->inst_offset); + } else { + arm_fcvt_ds (code, FP_TEMP_REG, sreg1); + code = emit_strfpw (code, FP_TEMP_REG, ins->inst_destbasereg, ins->inst_offset); + } + break; + case OP_FMOVE: + if (dreg != sreg1) + arm_fmovd (code, dreg, sreg1); + break; + case OP_RMOVE: + if (dreg != sreg1) + arm_fmovs (code, dreg, sreg1); + break; + case OP_MOVE_F_TO_I4: + if (cfg->r4fp) { + arm_fmov_double_to_rx (code, ins->dreg, ins->sreg1); + } else { + arm_fcvt_ds (code, ins->dreg, ins->sreg1); + arm_fmov_double_to_rx (code, ins->dreg, ins->dreg); + } + break; + case OP_MOVE_I4_TO_F: + if (cfg->r4fp) { + arm_fmov_rx_to_double (code, ins->dreg, ins->sreg1); + } else { + arm_fmov_rx_to_double (code, ins->dreg, ins->sreg1); + arm_fcvt_sd (code, ins->dreg, ins->dreg); + } + break; + case OP_MOVE_F_TO_I8: + arm_fmov_double_to_rx (code, ins->dreg, ins->sreg1); + break; + case OP_MOVE_I8_TO_F: + arm_fmov_rx_to_double (code, ins->dreg, ins->sreg1); + break; + case OP_FCOMPARE: + arm_fcmpd (code, sreg1, sreg2); + break; + case OP_RCOMPARE: + arm_fcmps (code, sreg1, sreg2); + break; + case OP_FCONV_TO_I1: + arm_fcvtzs_dx (code, dreg, sreg1); + arm_sxtbx (code, dreg, dreg); + break; + case OP_FCONV_TO_U1: + arm_fcvtzu_dx (code, dreg, sreg1); + arm_uxtbw (code, dreg, dreg); + break; + case OP_FCONV_TO_I2: + arm_fcvtzs_dx (code, dreg, sreg1); + arm_sxthx (code, dreg, dreg); + break; + case OP_FCONV_TO_U2: + arm_fcvtzu_dx (code, dreg, sreg1); + arm_uxthw (code, dreg, dreg); + break; + case OP_FCONV_TO_I4: + arm_fcvtzs_dx (code, dreg, sreg1); + arm_sxtwx (code, dreg, dreg); + break; + case OP_FCONV_TO_U4: + arm_fcvtzu_dx (code, dreg, sreg1); + break; + case OP_FCONV_TO_I8: + arm_fcvtzs_dx (code, dreg, sreg1); + break; + case OP_FCONV_TO_U8: + arm_fcvtzu_dx (code, dreg, sreg1); + break; + case OP_FCONV_TO_R4: + if (cfg->r4fp) { + arm_fcvt_ds (code, dreg, sreg1); + } else { + arm_fcvt_ds (code, FP_TEMP_REG, sreg1); + arm_fcvt_sd (code, dreg, FP_TEMP_REG); + } + break; + case OP_ICONV_TO_R4: + if (cfg->r4fp) { + arm_scvtf_rw_to_s (code, dreg, sreg1); + } else { + arm_scvtf_rw_to_s (code, FP_TEMP_REG, sreg1); + arm_fcvt_sd (code, dreg, FP_TEMP_REG); + } + break; + case OP_LCONV_TO_R4: + if (cfg->r4fp) { + arm_scvtf_rx_to_s (code, dreg, sreg1); + } else { + arm_scvtf_rx_to_s (code, FP_TEMP_REG, sreg1); + arm_fcvt_sd (code, dreg, FP_TEMP_REG); + } + break; + case OP_ICONV_TO_R8: + arm_scvtf_rw_to_d (code, dreg, sreg1); + break; + case OP_LCONV_TO_R8: + arm_scvtf_rx_to_d (code, dreg, sreg1); + break; + case OP_ICONV_TO_R_UN: + arm_ucvtf_rw_to_d (code, dreg, sreg1); + break; + case OP_LCONV_TO_R_UN: + arm_ucvtf_rx_to_d (code, dreg, sreg1); + break; + case OP_FADD: + arm_fadd_d (code, dreg, sreg1, sreg2); + break; + case OP_FSUB: + arm_fsub_d (code, dreg, sreg1, sreg2); + break; + case OP_FMUL: + arm_fmul_d (code, dreg, sreg1, sreg2); + break; + case OP_FDIV: + arm_fdiv_d (code, dreg, sreg1, sreg2); + break; + case OP_FREM: + /* Emulated */ + g_assert_not_reached (); + break; + case OP_FNEG: + arm_fneg_d (code, dreg, sreg1); + break; + case OP_ARM_SETFREG_R4: + arm_fcvt_ds (code, dreg, sreg1); + break; + case OP_CKFINITE: + /* Check for infinity */ + code = emit_imm64 (code, ARMREG_LR, 0x7fefffffffffffffLL); + arm_fmov_rx_to_double (code, FP_TEMP_REG, ARMREG_LR); + arm_fabs_d (code, FP_TEMP_REG2, sreg1); + arm_fcmpd (code, FP_TEMP_REG2, FP_TEMP_REG); + code = emit_cond_exc (cfg, code, OP_COND_EXC_GT, "ArithmeticException"); + /* Check for nans */ + arm_fcmpd (code, FP_TEMP_REG2, FP_TEMP_REG2); + code = emit_cond_exc (cfg, code, OP_COND_EXC_OV, "ArithmeticException"); + arm_fmovd (code, dreg, sreg1); + break; + + /* R4 */ + case OP_RADD: + arm_fadd_s (code, dreg, sreg1, sreg2); + break; + case OP_RSUB: + arm_fsub_s (code, dreg, sreg1, sreg2); + break; + case OP_RMUL: + arm_fmul_s (code, dreg, sreg1, sreg2); + break; + case OP_RDIV: + arm_fdiv_s (code, dreg, sreg1, sreg2); + break; + case OP_RNEG: + arm_fneg_s (code, dreg, sreg1); + break; + case OP_RCONV_TO_I1: + arm_fcvtzs_sx (code, dreg, sreg1); + arm_sxtbx (code, dreg, dreg); + break; + case OP_RCONV_TO_U1: + arm_fcvtzu_sx (code, dreg, sreg1); + arm_uxtbw (code, dreg, dreg); + break; + case OP_RCONV_TO_I2: + arm_fcvtzs_sx (code, dreg, sreg1); + arm_sxthx (code, dreg, dreg); + break; + case OP_RCONV_TO_U2: + arm_fcvtzu_sx (code, dreg, sreg1); + arm_uxthw (code, dreg, dreg); + break; + case OP_RCONV_TO_I4: + arm_fcvtzs_sx (code, dreg, sreg1); + arm_sxtwx (code, dreg, dreg); + break; + case OP_RCONV_TO_U4: + arm_fcvtzu_sx (code, dreg, sreg1); + break; + case OP_RCONV_TO_I8: + arm_fcvtzs_sx (code, dreg, sreg1); + break; + case OP_RCONV_TO_U8: + arm_fcvtzu_sx (code, dreg, sreg1); + break; + case OP_RCONV_TO_R8: + arm_fcvt_sd (code, dreg, sreg1); + break; + case OP_RCONV_TO_R4: + if (dreg != sreg1) + arm_fmovs (code, dreg, sreg1); + break; + case OP_RCEQ: + case OP_RCLT: + case OP_RCLT_UN: + case OP_RCGT: + case OP_RCGT_UN: + case OP_RCNEQ: + case OP_RCLE: + case OP_RCGE: { + int cond; + + cond = opcode_to_armcond (ins->opcode); + arm_fcmps (code, sreg1, sreg2); + arm_cset (code, cond, dreg); + break; + } + + /* CALLS */ + case OP_VOIDCALL: + case OP_CALL: + case OP_LCALL: + case OP_FCALL: + case OP_RCALL: + case OP_VCALL2: + call = (MonoCallInst*)ins; + if (ins->flags & MONO_INST_HAS_METHOD) + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, call->method); + else + code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, call->fptr); + code = emit_move_return_value (cfg, code, ins); + break; + case OP_VOIDCALL_REG: + case OP_CALL_REG: + case OP_LCALL_REG: + case OP_FCALL_REG: + case OP_RCALL_REG: + case OP_VCALL2_REG: + arm_blrx (code, sreg1); + code = emit_move_return_value (cfg, code, ins); + break; + case OP_VOIDCALL_MEMBASE: + case OP_CALL_MEMBASE: + case OP_LCALL_MEMBASE: + case OP_FCALL_MEMBASE: + case OP_RCALL_MEMBASE: + case OP_VCALL2_MEMBASE: + code = emit_ldrx (code, ARMREG_IP0, ins->inst_basereg, ins->inst_offset); + arm_blrx (code, ARMREG_IP0); + code = emit_move_return_value (cfg, code, ins); + break; + case OP_TAILCALL: { + MonoCallInst *call = (MonoCallInst*)ins; + + g_assert (!cfg->method->save_lmf); + + // FIXME: Copy stack arguments + + /* Restore registers */ + code = emit_load_regset (code, MONO_ARCH_CALLEE_SAVED_REGS & cfg->used_int_regs, ARMREG_FP, cfg->arch.saved_gregs_offset); + + /* Destroy frame */ + code = mono_arm_emit_destroy_frame (code, cfg->stack_offset, ((1 << ARMREG_IP0) | (1 << ARMREG_IP1))); + + if (cfg->compile_aot) { + /* This is not a PLT patch */ + code = emit_aotconst (cfg, code, ARMREG_IP0, MONO_PATCH_INFO_METHOD_JUMP, call->method); + arm_brx (code, ARMREG_IP0); + } else { + mono_add_patch_info_rel (cfg, code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method, MONO_R_ARM64_B); + arm_b (code, code); + } + ins->flags |= MONO_INST_GC_CALLSITE; + ins->backend.pc_offset = code - cfg->native_code; + break; + } + case OP_ARGLIST: + g_assert (cfg->arch.cinfo); + code = emit_addx_imm (code, ARMREG_IP0, cfg->arch.args_reg, ((CallInfo*)cfg->arch.cinfo)->sig_cookie.offset); + arm_strx (code, ARMREG_IP0, sreg1, 0); + break; + case OP_DYN_CALL: { + MonoInst *var = cfg->dyn_call_var; + guint8 *labels [16]; + int i; + + /* + * sreg1 points to a DynCallArgs structure initialized by mono_arch_start_dyn_call (). + * sreg2 is the function to call. + */ + + g_assert (var->opcode == OP_REGOFFSET); + + arm_movx (code, ARMREG_LR, sreg1); + arm_movx (code, ARMREG_IP1, sreg2); + + /* Save args buffer */ + code = emit_strx (code, ARMREG_LR, var->inst_basereg, var->inst_offset); + + /* Set fp argument regs */ + code = emit_ldrw (code, ARMREG_R0, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, n_fpargs)); + arm_cmpw (code, ARMREG_R0, ARMREG_RZR); + labels [0] = code; + arm_bcc (code, ARMCOND_EQ, 0); + for (i = 0; i < 8; ++i) + code = emit_ldrfpx (code, ARMREG_D0 + i, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, fpregs) + (i * 8)); + arm_patch_rel (labels [0], code, MONO_R_ARM64_BCC); + + /* Set stack args */ + for (i = 0; i < DYN_CALL_STACK_ARGS; ++i) { + code = emit_ldrx (code, ARMREG_R0, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, regs) + ((PARAM_REGS + 1 + i) * sizeof (mgreg_t))); + code = emit_strx (code, ARMREG_R0, ARMREG_SP, i * sizeof (mgreg_t)); + } + + /* Set argument registers + r8 */ + code = mono_arm_emit_load_regarray (code, 0x1ff, ARMREG_LR, 0); + + /* Make the call */ + arm_blrx (code, ARMREG_IP1); + + /* Save result */ + code = emit_ldrx (code, ARMREG_LR, var->inst_basereg, var->inst_offset); + arm_strx (code, ARMREG_R0, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, res)); + arm_strx (code, ARMREG_R1, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, res2)); + /* Save fp result */ + code = emit_ldrw (code, ARMREG_R0, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, n_fpret)); + arm_cmpw (code, ARMREG_R0, ARMREG_RZR); + labels [1] = code; + arm_bcc (code, ARMCOND_EQ, 0); + for (i = 0; i < 8; ++i) + code = emit_strfpx (code, ARMREG_D0 + i, ARMREG_LR, MONO_STRUCT_OFFSET (DynCallArgs, fpregs) + (i * 8)); + arm_patch_rel (labels [1], code, MONO_R_ARM64_BCC); + break; + } + + case OP_GENERIC_CLASS_INIT: { + static int byte_offset = -1; + static guint8 bitmask; + guint8 *jump; + + if (byte_offset < 0) + mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask); + + /* Load vtable->initialized */ + arm_ldrsbx (code, ARMREG_IP0, sreg1, byte_offset); + // FIXME: No andx_imm yet */ + code = mono_arm_emit_imm64 (code, ARMREG_IP1, bitmask); + arm_andx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1); + jump = code; + arm_cbnzx (code, ARMREG_IP0, 0); + + /* Slowpath */ + g_assert (sreg1 == ARMREG_R0); + code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, + (gpointer)"mono_generic_class_init"); + + mono_arm_patch (jump, code, MONO_R_ARM64_CBZ); + break; + } + + case OP_CHECK_THIS: + arm_ldrx (code, ARMREG_LR, sreg1, 0); + break; + case OP_NOT_NULL: + case OP_NOT_REACHED: + case OP_DUMMY_USE: + break; + case OP_IL_SEQ_POINT: + mono_add_seq_point (cfg, bb, ins, code - cfg->native_code); + break; + + /* EH */ + case OP_COND_EXC_C: + case OP_COND_EXC_IC: + case OP_COND_EXC_OV: + case OP_COND_EXC_IOV: + case OP_COND_EXC_NC: + case OP_COND_EXC_INC: + case OP_COND_EXC_NO: + case OP_COND_EXC_INO: + case OP_COND_EXC_EQ: + case OP_COND_EXC_IEQ: + case OP_COND_EXC_NE_UN: + case OP_COND_EXC_INE_UN: + case OP_COND_EXC_ILT: + case OP_COND_EXC_LT: + case OP_COND_EXC_ILT_UN: + case OP_COND_EXC_LT_UN: + case OP_COND_EXC_IGT: + case OP_COND_EXC_GT: + case OP_COND_EXC_IGT_UN: + case OP_COND_EXC_GT_UN: + case OP_COND_EXC_IGE: + case OP_COND_EXC_GE: + case OP_COND_EXC_IGE_UN: + case OP_COND_EXC_GE_UN: + case OP_COND_EXC_ILE: + case OP_COND_EXC_LE: + case OP_COND_EXC_ILE_UN: + case OP_COND_EXC_LE_UN: + code = emit_cond_exc (cfg, code, ins->opcode, ins->inst_p1); + break; + case OP_THROW: + if (sreg1 != ARMREG_R0) + arm_movx (code, ARMREG_R0, sreg1); + code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, + (gpointer)"mono_arch_throw_exception"); + break; + case OP_RETHROW: + if (sreg1 != ARMREG_R0) + arm_movx (code, ARMREG_R0, sreg1); + code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, + (gpointer)"mono_arch_rethrow_exception"); + break; + case OP_CALL_HANDLER: + mono_add_patch_info_rel (cfg, offset, MONO_PATCH_INFO_BB, ins->inst_target_bb, MONO_R_ARM64_BL); + arm_bl (code, 0); + cfg->thunk_area += THUNK_SIZE; + break; + case OP_START_HANDLER: { + MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region); + + /* Save caller address */ + code = emit_strx (code, ARMREG_LR, spvar->inst_basereg, spvar->inst_offset); + + /* + * Reserve a param area, see test_0_finally_param_area (). + * This is needed because the param area is not set up when + * we are called from EH code. + */ + if (cfg->param_area) + code = emit_subx_sp_imm (code, cfg->param_area); + break; + } + case OP_ENDFINALLY: + case OP_ENDFILTER: { + MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region); + + if (cfg->param_area) + code = emit_addx_sp_imm (code, cfg->param_area); + + if (ins->opcode == OP_ENDFILTER && sreg1 != ARMREG_R0) + arm_movx (code, ARMREG_R0, sreg1); + + /* Return to either after the branch in OP_CALL_HANDLER, or to the EH code */ + code = emit_ldrx (code, ARMREG_LR, spvar->inst_basereg, spvar->inst_offset); + arm_brx (code, ARMREG_LR); + break; + } + case OP_GET_EX_OBJ: + if (ins->dreg != ARMREG_R0) + arm_movx (code, ins->dreg, ARMREG_R0); + break; + case OP_GC_SAFE_POINT: { +#if defined (USE_COOP_GC) + guint8 *buf [1]; + + arm_ldrx (code, ARMREG_IP1, ins->sreg1, 0); + /* Call it if it is non-null */ + buf [0] = code; + arm_cbzx (code, ARMREG_IP1, 0); + code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_threads_state_poll"); + mono_arm_patch (buf [0], code, MONO_R_ARM64_CBZ); +#endif + break; + } + + default: + g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__); + g_assert_not_reached (); + } + + if ((cfg->opt & MONO_OPT_BRANCH) && ((code - cfg->native_code - offset) > max_len)) { + g_warning ("wrong maximal instruction length of instruction %s (expected %d, got %d)", + mono_inst_name (ins->opcode), max_len, code - cfg->native_code - offset); + g_assert_not_reached (); + } + } + + /* + * If the compiled code size is larger than the bcc displacement (19 bits signed), + * insert branch islands between/inside basic blocks. + */ + if (cfg->arch.cond_branch_islands) + code = emit_branch_island (cfg, code, start_offset); + + cfg->code_len = code - cfg->native_code; +} + +static guint8* +emit_move_args (MonoCompile *cfg, guint8 *code) +{ + MonoInst *ins; + CallInfo *cinfo; + ArgInfo *ainfo; + int i, part; + + cinfo = cfg->arch.cinfo; + g_assert (cinfo); + for (i = 0; i < cinfo->nargs; ++i) { + ainfo = cinfo->args + i; + ins = cfg->args [i]; + + if (ins->opcode == OP_REGVAR) { + switch (ainfo->storage) { + case ArgInIReg: + arm_movx (code, ins->dreg, ainfo->reg); + break; + case ArgOnStack: + switch (ainfo->slot_size) { + case 1: + if (ainfo->sign) + code = emit_ldrsbx (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + else + code = emit_ldrb (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + break; + case 2: + if (ainfo->sign) + code = emit_ldrshx (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + else + code = emit_ldrh (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + break; + case 4: + if (ainfo->sign) + code = emit_ldrswx (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + else + code = emit_ldrw (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + break; + default: + code = emit_ldrx (code, ins->dreg, cfg->arch.args_reg, ainfo->offset); + break; + } + break; + default: + g_assert_not_reached (); + break; + } + } else { + if (ainfo->storage != ArgVtypeByRef && ainfo->storage != ArgVtypeByRefOnStack) + g_assert (ins->opcode == OP_REGOFFSET); + + switch (ainfo->storage) { + case ArgInIReg: + /* Stack slots for arguments have size 8 */ + code = emit_strx (code, ainfo->reg, ins->inst_basereg, ins->inst_offset); + break; + case ArgInFReg: + code = emit_strfpx (code, ainfo->reg, ins->inst_basereg, ins->inst_offset); + break; + case ArgInFRegR4: + code = emit_strfpw (code, ainfo->reg, ins->inst_basereg, ins->inst_offset); + break; + case ArgOnStack: + case ArgOnStackR4: + case ArgOnStackR8: + case ArgVtypeByRefOnStack: + case ArgVtypeOnStack: + break; + case ArgVtypeByRef: { + MonoInst *addr_arg = ins->inst_left; + + if (ainfo->gsharedvt) { + g_assert (ins->opcode == OP_GSHAREDVT_ARG_REGOFFSET); + arm_strx (code, ainfo->reg, ins->inst_basereg, ins->inst_offset); + } else { + g_assert (ins->opcode == OP_VTARG_ADDR); + g_assert (addr_arg->opcode == OP_REGOFFSET); + arm_strx (code, ainfo->reg, addr_arg->inst_basereg, addr_arg->inst_offset); + } + break; + } + case ArgVtypeInIRegs: + for (part = 0; part < ainfo->nregs; part ++) { + code = emit_strx (code, ainfo->reg + part, ins->inst_basereg, ins->inst_offset + (part * 8)); + } + break; + case ArgHFA: + for (part = 0; part < ainfo->nregs; part ++) { + if (ainfo->esize == 4) + code = emit_strfpw (code, ainfo->reg + part, ins->inst_basereg, ins->inst_offset + ainfo->foffsets [part]); + else + code = emit_strfpx (code, ainfo->reg + part, ins->inst_basereg, ins->inst_offset + ainfo->foffsets [part]); + } + break; + default: + g_assert_not_reached (); + break; + } + } + } + + return code; +} + +/* + * emit_store_regarray: + * + * Emit code to store the registers in REGS into the appropriate elements of + * the register array at BASEREG+OFFSET. + */ +static __attribute__((warn_unused_result)) guint8* +emit_store_regarray (guint8 *code, guint64 regs, int basereg, int offset) +{ + int i; + + for (i = 0; i < 32; ++i) { + if (regs & (1 << i)) { + if (i + 1 < 32 && (regs & (1 << (i + 1))) && (i + 1 != ARMREG_SP)) { + arm_stpx (code, i, i + 1, basereg, offset + (i * 8)); + i++; + } else if (i == ARMREG_SP) { + arm_movspx (code, ARMREG_IP1, ARMREG_SP); + arm_strx (code, ARMREG_IP1, basereg, offset + (i * 8)); + } else { + arm_strx (code, i, basereg, offset + (i * 8)); + } + } + } + return code; +} + +/* + * emit_load_regarray: + * + * Emit code to load the registers in REGS from the appropriate elements of + * the register array at BASEREG+OFFSET. + */ +static __attribute__((warn_unused_result)) guint8* +emit_load_regarray (guint8 *code, guint64 regs, int basereg, int offset) +{ + int i; + + for (i = 0; i < 32; ++i) { + if (regs & (1 << i)) { + if ((regs & (1 << (i + 1))) && (i + 1 != ARMREG_SP)) { + if (offset + (i * 8) < 500) + arm_ldpx (code, i, i + 1, basereg, offset + (i * 8)); + else { + code = emit_ldrx (code, i, basereg, offset + (i * 8)); + code = emit_ldrx (code, i + 1, basereg, offset + ((i + 1) * 8)); + } + i++; + } else if (i == ARMREG_SP) { + g_assert_not_reached (); + } else { + code = emit_ldrx (code, i, basereg, offset + (i * 8)); + } + } + } + return code; +} + +/* + * emit_store_regset: + * + * Emit code to store the registers in REGS into consecutive memory locations starting + * at BASEREG+OFFSET. + */ +static __attribute__((warn_unused_result)) guint8* +emit_store_regset (guint8 *code, guint64 regs, int basereg, int offset) +{ + int i, pos; + + pos = 0; + for (i = 0; i < 32; ++i) { + if (regs & (1 << i)) { + if ((regs & (1 << (i + 1))) && (i + 1 != ARMREG_SP)) { + arm_stpx (code, i, i + 1, basereg, offset + (pos * 8)); + i++; + pos++; + } else if (i == ARMREG_SP) { + arm_movspx (code, ARMREG_IP1, ARMREG_SP); + arm_strx (code, ARMREG_IP1, basereg, offset + (pos * 8)); + } else { + arm_strx (code, i, basereg, offset + (pos * 8)); + } + pos++; + } + } + return code; +} + +/* + * emit_load_regset: + * + * Emit code to load the registers in REGS from consecutive memory locations starting + * at BASEREG+OFFSET. + */ +static __attribute__((warn_unused_result)) guint8* +emit_load_regset (guint8 *code, guint64 regs, int basereg, int offset) +{ + int i, pos; + + pos = 0; + for (i = 0; i < 32; ++i) { + if (regs & (1 << i)) { + if ((regs & (1 << (i + 1))) && (i + 1 != ARMREG_SP)) { + arm_ldpx (code, i, i + 1, basereg, offset + (pos * 8)); + i++; + pos++; + } else if (i == ARMREG_SP) { + g_assert_not_reached (); + } else { + arm_ldrx (code, i, basereg, offset + (pos * 8)); + } + pos++; + } + } + return code; +} + +__attribute__((warn_unused_result)) guint8* +mono_arm_emit_load_regarray (guint8 *code, guint64 regs, int basereg, int offset) +{ + return emit_load_regarray (code, regs, basereg, offset); +} + +__attribute__((warn_unused_result)) guint8* +mono_arm_emit_store_regarray (guint8 *code, guint64 regs, int basereg, int offset) +{ + return emit_store_regarray (code, regs, basereg, offset); +} + +__attribute__((warn_unused_result)) guint8* +mono_arm_emit_store_regset (guint8 *code, guint64 regs, int basereg, int offset) +{ + return emit_store_regset (code, regs, basereg, offset); +} + +/* Same as emit_store_regset, but emit unwind info too */ +/* CFA_OFFSET is the offset between the CFA and basereg */ +static __attribute__((warn_unused_result)) guint8* +emit_store_regset_cfa (MonoCompile *cfg, guint8 *code, guint64 regs, int basereg, int offset, int cfa_offset, guint64 no_cfa_regset) +{ + int i, j, pos, nregs; + guint32 cfa_regset = regs & ~no_cfa_regset; + + pos = 0; + for (i = 0; i < 32; ++i) { + nregs = 1; + if (regs & (1 << i)) { + if ((regs & (1 << (i + 1))) && (i + 1 != ARMREG_SP)) { + if (offset < 256) { + arm_stpx (code, i, i + 1, basereg, offset + (pos * 8)); + } else { + code = emit_strx (code, i, basereg, offset + (pos * 8)); + code = emit_strx (code, i + 1, basereg, offset + (pos * 8) + 8); + } + nregs = 2; + } else if (i == ARMREG_SP) { + arm_movspx (code, ARMREG_IP1, ARMREG_SP); + code = emit_strx (code, ARMREG_IP1, basereg, offset + (pos * 8)); + } else { + code = emit_strx (code, i, basereg, offset + (pos * 8)); + } + + for (j = 0; j < nregs; ++j) { + if (cfa_regset & (1 << (i + j))) + mono_emit_unwind_op_offset (cfg, code, i + j, (- cfa_offset) + offset + ((pos + j) * 8)); + } + + i += nregs - 1; + pos += nregs; + } + } + return code; +} + +/* + * emit_setup_lmf: + * + * Emit code to initialize an LMF structure at LMF_OFFSET. + * Clobbers ip0/ip1. + */ +static guint8* +emit_setup_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, int cfa_offset) +{ + /* + * The LMF should contain all the state required to be able to reconstruct the machine state + * at the current point of execution. Since the LMF is only read during EH, only callee + * saved etc. registers need to be saved. + * FIXME: Save callee saved fp regs, JITted code doesn't use them, but native code does, and they + * need to be restored during EH. + */ + + /* pc */ + arm_adrx (code, ARMREG_LR, code); + code = emit_strx (code, ARMREG_LR, ARMREG_FP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, pc)); + /* gregs + fp + sp */ + /* Don't emit unwind info for sp/fp, they are already handled in the prolog */ + code = emit_store_regset_cfa (cfg, code, MONO_ARCH_LMF_REGS, ARMREG_FP, lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, gregs), cfa_offset, (1 << ARMREG_FP) | (1 << ARMREG_SP)); + + return code; +} + +guint8 * +mono_arch_emit_prolog (MonoCompile *cfg) +{ + MonoMethod *method = cfg->method; + MonoMethodSignature *sig; + MonoBasicBlock *bb; + guint8 *code; + int cfa_offset, max_offset; + + sig = mono_method_signature (method); + cfg->code_size = 256 + sig->param_count * 64; + code = cfg->native_code = g_malloc (cfg->code_size); + + /* This can be unaligned */ + cfg->stack_offset = ALIGN_TO (cfg->stack_offset, MONO_ARCH_FRAME_ALIGNMENT); + + /* + * - Setup frame + */ + cfa_offset = 0; + mono_emit_unwind_op_def_cfa (cfg, code, ARMREG_SP, 0); + + /* Setup frame */ + if (arm_is_ldpx_imm (-cfg->stack_offset)) { + arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -cfg->stack_offset); + } else { + /* sp -= cfg->stack_offset */ + /* This clobbers ip0/ip1 */ + code = emit_subx_sp_imm (code, cfg->stack_offset); + arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0); + } + cfa_offset += cfg->stack_offset; + mono_emit_unwind_op_def_cfa_offset (cfg, code, cfa_offset); + mono_emit_unwind_op_offset (cfg, code, ARMREG_FP, (- cfa_offset) + 0); + mono_emit_unwind_op_offset (cfg, code, ARMREG_LR, (- cfa_offset) + 8); + arm_movspx (code, ARMREG_FP, ARMREG_SP); + mono_emit_unwind_op_def_cfa_reg (cfg, code, ARMREG_FP); + if (cfg->param_area) { + /* The param area is below the frame pointer */ + code = emit_subx_sp_imm (code, cfg->param_area); + } + + if (cfg->method->save_lmf) { + code = emit_setup_lmf (cfg, code, cfg->lmf_var->inst_offset, cfa_offset); + } else { + /* Save gregs */ + code = emit_store_regset_cfa (cfg, code, MONO_ARCH_CALLEE_SAVED_REGS & cfg->used_int_regs, ARMREG_FP, cfg->arch.saved_gregs_offset, cfa_offset, 0); + } + + /* Setup args reg */ + if (cfg->arch.args_reg) { + /* The register was already saved above */ + code = emit_addx_imm (code, cfg->arch.args_reg, ARMREG_FP, cfg->stack_offset); + } + + /* Save return area addr received in R8 */ + if (cfg->vret_addr) { + MonoInst *ins = cfg->vret_addr; + + g_assert (ins->opcode == OP_REGOFFSET); + code = emit_strx (code, ARMREG_R8, ins->inst_basereg, ins->inst_offset); + } + + /* Save mrgctx received in MONO_ARCH_RGCTX_REG */ + if (cfg->rgctx_var) { + MonoInst *ins = cfg->rgctx_var; + + g_assert (ins->opcode == OP_REGOFFSET); + + code = emit_strx (code, MONO_ARCH_RGCTX_REG, ins->inst_basereg, ins->inst_offset); + } + + /* + * Move arguments to their registers/stack locations. + */ + code = emit_move_args (cfg, code); + + /* Initialize seq_point_info_var */ + if (cfg->arch.seq_point_info_var) { + MonoInst *ins = cfg->arch.seq_point_info_var; + + /* Initialize the variable from a GOT slot */ + code = emit_aotconst (cfg, code, ARMREG_IP0, MONO_PATCH_INFO_SEQ_POINT_INFO, cfg->method); + g_assert (ins->opcode == OP_REGOFFSET); + code = emit_strx (code, ARMREG_IP0, ins->inst_basereg, ins->inst_offset); + + /* Initialize ss_tramp_var */ + ins = cfg->arch.ss_tramp_var; + g_assert (ins->opcode == OP_REGOFFSET); + + code = emit_ldrx (code, ARMREG_IP1, ARMREG_IP0, MONO_STRUCT_OFFSET (SeqPointInfo, ss_tramp_addr)); + code = emit_strx (code, ARMREG_IP1, ins->inst_basereg, ins->inst_offset); + } else { + MonoInst *ins; + + if (cfg->arch.ss_tramp_var) { + /* Initialize ss_tramp_var */ + ins = cfg->arch.ss_tramp_var; + g_assert (ins->opcode == OP_REGOFFSET); + + code = emit_imm64 (code, ARMREG_IP0, (guint64)&ss_trampoline); + code = emit_strx (code, ARMREG_IP0, ins->inst_basereg, ins->inst_offset); + } + + if (cfg->arch.bp_tramp_var) { + /* Initialize bp_tramp_var */ + ins = cfg->arch.bp_tramp_var; + g_assert (ins->opcode == OP_REGOFFSET); + + code = emit_imm64 (code, ARMREG_IP0, (guint64)bp_trampoline); + code = emit_strx (code, ARMREG_IP0, ins->inst_basereg, ins->inst_offset); + } + } + + max_offset = 0; + if (cfg->opt & MONO_OPT_BRANCH) { + for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { + MonoInst *ins; + bb->max_offset = max_offset; + + MONO_BB_FOR_EACH_INS (bb, ins) { + max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN]; + } + } + } + if (max_offset > 0x3ffff * 4) + cfg->arch.cond_branch_islands = TRUE; + + return code; +} + +static guint8* +realloc_code (MonoCompile *cfg, int size) +{ + while (cfg->code_len + size > (cfg->code_size - 16)) { + cfg->code_size *= 2; + cfg->native_code = g_realloc (cfg->native_code, cfg->code_size); + cfg->stat_code_reallocs++; + } + return cfg->native_code + cfg->code_len; +} + +void +mono_arch_emit_epilog (MonoCompile *cfg) +{ + CallInfo *cinfo; + int max_epilog_size; + guint8 *code; + int i; + + max_epilog_size = 16 + 20*4; + code = realloc_code (cfg, max_epilog_size); + + if (cfg->method->save_lmf) { + code = mono_arm_emit_load_regarray (code, MONO_ARCH_CALLEE_SAVED_REGS & cfg->used_int_regs, ARMREG_FP, cfg->lmf_var->inst_offset + MONO_STRUCT_OFFSET (MonoLMF, gregs) - (MONO_ARCH_FIRST_LMF_REG * 8)); + } else { + /* Restore gregs */ + code = emit_load_regset (code, MONO_ARCH_CALLEE_SAVED_REGS & cfg->used_int_regs, ARMREG_FP, cfg->arch.saved_gregs_offset); + } + + /* Load returned vtypes into registers if needed */ + cinfo = cfg->arch.cinfo; + switch (cinfo->ret.storage) { + case ArgVtypeInIRegs: { + MonoInst *ins = cfg->ret; + + for (i = 0; i < cinfo->ret.nregs; ++i) + code = emit_ldrx (code, cinfo->ret.reg + i, ins->inst_basereg, ins->inst_offset + (i * 8)); + break; + } + case ArgHFA: { + MonoInst *ins = cfg->ret; + + for (i = 0; i < cinfo->ret.nregs; ++i) { + if (cinfo->ret.esize == 4) + code = emit_ldrfpw (code, cinfo->ret.reg + i, ins->inst_basereg, ins->inst_offset + cinfo->ret.foffsets [i]); + else + code = emit_ldrfpx (code, cinfo->ret.reg + i, ins->inst_basereg, ins->inst_offset + cinfo->ret.foffsets [i]); + } + break; + } + default: + break; + } + + /* Destroy frame */ + code = mono_arm_emit_destroy_frame (code, cfg->stack_offset, ((1 << ARMREG_IP0) | (1 << ARMREG_IP1))); + + arm_retx (code, ARMREG_LR); + + g_assert (code - (cfg->native_code + cfg->code_len) < max_epilog_size); + + cfg->code_len = code - cfg->native_code; +} + +void +mono_arch_emit_exceptions (MonoCompile *cfg) +{ + MonoJumpInfo *ji; + MonoClass *exc_class; + guint8 *code, *ip; + guint8* exc_throw_pos [MONO_EXC_INTRINS_NUM]; + guint8 exc_throw_found [MONO_EXC_INTRINS_NUM]; + int i, id, size = 0; + + for (i = 0; i < MONO_EXC_INTRINS_NUM; i++) { + exc_throw_pos [i] = NULL; + exc_throw_found [i] = 0; + } + + for (ji = cfg->patch_info; ji; ji = ji->next) { + if (ji->type == MONO_PATCH_INFO_EXC) { + i = mini_exception_id_by_name (ji->data.target); + if (!exc_throw_found [i]) { + size += 32; + exc_throw_found [i] = TRUE; + } + } + } + + code = realloc_code (cfg, size); + + /* Emit code to raise corlib exceptions */ + for (ji = cfg->patch_info; ji; ji = ji->next) { + if (ji->type != MONO_PATCH_INFO_EXC) + continue; + + ip = cfg->native_code + ji->ip.i; + + id = mini_exception_id_by_name (ji->data.target); + + if (exc_throw_pos [id]) { + /* ip points to the bcc () in OP_COND_EXC_... */ + arm_patch_rel (ip, exc_throw_pos [id], ji->relocation); + ji->type = MONO_PATCH_INFO_NONE; + continue; + } + + exc_throw_pos [id] = code; + arm_patch_rel (ip, code, ji->relocation); + + /* We are being branched to from the code generated by emit_cond_exc (), the pc is in ip1 */ + + /* r0 = type token */ + exc_class = mono_class_load_from_name (mono_defaults.corlib, "System", ji->data.name); + code = emit_imm (code, ARMREG_R0, exc_class->type_token - MONO_TOKEN_TYPE_DEF); + /* r1 = throw ip */ + arm_movx (code, ARMREG_R1, ARMREG_IP1); + /* Branch to the corlib exception throwing trampoline */ + ji->ip.i = code - cfg->native_code; + ji->type = MONO_PATCH_INFO_INTERNAL_METHOD; + ji->data.name = "mono_arch_throw_corlib_exception"; + ji->relocation = MONO_R_ARM64_BL; + arm_bl (code, 0); + cfg->thunk_area += THUNK_SIZE; + } + + cfg->code_len = code - cfg->native_code; + + g_assert (cfg->code_len < cfg->code_size); +} + +MonoInst* +mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) +{ + return NULL; +} + +gboolean +mono_arch_print_tree (MonoInst *tree, int arity) +{ + return FALSE; +} + +guint32 +mono_arch_get_patch_offset (guint8 *code) +{ + return 0; +} + +gpointer +mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, + gpointer fail_tramp) +{ + int i, buf_len, imt_reg; + guint8 *buf, *code; + +#if DEBUG_IMT + printf ("building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable); + for (i = 0; i < count; ++i) { + MonoIMTCheckItem *item = imt_entries [i]; + printf ("method %d (%p) %s vtable slot %p is_equals %d chunk size %d\n", i, item->key, item->key->name, &vtable->vtable [item->value.vtable_slot], item->is_equals, item->chunk_size); + } +#endif + + buf_len = 0; + for (i = 0; i < count; ++i) { + MonoIMTCheckItem *item = imt_entries [i]; + if (item->is_equals) { + gboolean fail_case = !item->check_target_idx && fail_tramp; + + if (item->check_target_idx || fail_case) { + if (!item->compare_done || fail_case) { + buf_len += 4 * 4 + 4; + } + buf_len += 4; + if (item->has_target_code) { + buf_len += 5 * 4; + } else { + buf_len += 6 * 4; + } + if (fail_case) { + buf_len += 5 * 4; + } + } else { + buf_len += 6 * 4; + } + } else { + buf_len += 6 * 4; + } + } + + if (fail_tramp) + buf = mono_method_alloc_generic_virtual_thunk (domain, buf_len); + else + buf = mono_domain_code_reserve (domain, buf_len); + code = buf; + + /* + * We are called by JITted code, which passes in the IMT argument in + * MONO_ARCH_RGCTX_REG (r27). We need to preserve all caller saved regs + * except ip0/ip1. + */ + imt_reg = MONO_ARCH_RGCTX_REG; + for (i = 0; i < count; ++i) { + MonoIMTCheckItem *item = imt_entries [i]; + + item->code_target = code; + + if (item->is_equals) { + /* + * Check the imt argument against item->key, if equals, jump to either + * item->value.target_code or to vtable [item->value.vtable_slot]. + * If fail_tramp is set, jump to it if not-equals. + */ + gboolean fail_case = !item->check_target_idx && fail_tramp; + + if (item->check_target_idx || fail_case) { + /* Compare imt_reg with item->key */ + if (!item->compare_done || fail_case) { + // FIXME: Optimize this + code = emit_imm64 (code, ARMREG_IP0, (guint64)item->key); + arm_cmpx (code, imt_reg, ARMREG_IP0); + } + item->jmp_code = code; + arm_bcc (code, ARMCOND_NE, 0); + /* Jump to target if equals */ + if (item->has_target_code) { + code = emit_imm64 (code, ARMREG_IP0, (guint64)item->value.target_code); + arm_brx (code, ARMREG_IP0); + } else { + guint64 imm = (guint64)&(vtable->vtable [item->value.vtable_slot]); + + code = emit_imm64 (code, ARMREG_IP0, imm); + arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); + arm_brx (code, ARMREG_IP0); + } + + if (fail_case) { + arm_patch_rel (item->jmp_code, code, MONO_R_ARM64_BCC); + item->jmp_code = NULL; + code = emit_imm64 (code, ARMREG_IP0, (guint64)fail_tramp); + arm_brx (code, ARMREG_IP0); + } + } else { + guint64 imm = (guint64)&(vtable->vtable [item->value.vtable_slot]); + + code = emit_imm64 (code, ARMREG_IP0, imm); + arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0); + arm_brx (code, ARMREG_IP0); + } + } else { + code = emit_imm64 (code, ARMREG_IP0, (guint64)item->key); + arm_cmpx (code, imt_reg, ARMREG_IP0); + item->jmp_code = code; + arm_bcc (code, ARMCOND_HS, 0); + } + } + /* Patch the branches */ + for (i = 0; i < count; ++i) { + MonoIMTCheckItem *item = imt_entries [i]; + if (item->jmp_code && item->check_target_idx) + arm_patch_rel (item->jmp_code, imt_entries [item->check_target_idx]->code_target, MONO_R_ARM64_BCC); + } + + g_assert ((code - buf) < buf_len); + + mono_arch_flush_icache (buf, code - buf); + + return buf; +} + +GSList * +mono_arch_get_trampolines (gboolean aot) +{ + return mono_arm_get_exception_trampolines (aot); +} + +#else /* DISABLE_JIT */ + +gpointer +mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count, + gpointer fail_tramp) +{ + g_assert_not_reached (); + return NULL; +} + +#endif /* !DISABLE_JIT */ + +#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED + +void +mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip) +{ + guint8 *code = ip; + guint32 native_offset = ip - (guint8*)ji->code_start; + + if (ji->from_aot) { + SeqPointInfo *info = mono_arch_get_seq_point_info (mono_domain_get (), ji->code_start); + + g_assert (native_offset % 4 == 0); + g_assert (info->bp_addrs [native_offset / 4] == 0); + info->bp_addrs [native_offset / 4] = mini_get_breakpoint_trampoline (); + } else { + /* ip points to an ldrx */ + code += 4; + arm_blrx (code, ARMREG_IP0); + mono_arch_flush_icache (ip, code - ip); + } +} + +void +mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip) +{ + guint8 *code = ip; + + if (ji->from_aot) { + guint32 native_offset = ip - (guint8*)ji->code_start; + SeqPointInfo *info = mono_arch_get_seq_point_info (mono_domain_get (), ji->code_start); + + g_assert (native_offset % 4 == 0); + info->bp_addrs [native_offset / 4] = NULL; + } else { + /* ip points to an ldrx */ + code += 4; + arm_nop (code); + mono_arch_flush_icache (ip, code - ip); + } +} + +void +mono_arch_start_single_stepping (void) +{ + ss_trampoline = mini_get_single_step_trampoline (); +} + +void +mono_arch_stop_single_stepping (void) +{ + ss_trampoline = NULL; +} + +gboolean +mono_arch_is_single_step_event (void *info, void *sigctx) +{ + /* We use soft breakpoints on arm64 */ + return FALSE; +} + +gboolean +mono_arch_is_breakpoint_event (void *info, void *sigctx) +{ + /* We use soft breakpoints on arm64 */ + return FALSE; +} + +void +mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji) +{ + g_assert_not_reached (); +} + +void +mono_arch_skip_single_step (MonoContext *ctx) +{ + g_assert_not_reached (); +} + +gpointer +mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code) +{ + SeqPointInfo *info; + MonoJitInfo *ji; + + // FIXME: Add a free function + + mono_domain_lock (domain); + info = g_hash_table_lookup (domain_jit_info (domain)->arch_seq_points, + code); + mono_domain_unlock (domain); + + if (!info) { + ji = mono_jit_info_table_find (domain, (char*)code); + g_assert (ji); + + info = g_malloc0 (sizeof (SeqPointInfo) + (ji->code_size / 4) * sizeof(guint8*)); + + info->ss_tramp_addr = &ss_trampoline; + + mono_domain_lock (domain); + g_hash_table_insert (domain_jit_info (domain)->arch_seq_points, + code, info); + mono_domain_unlock (domain); + } + + return info; +} + +void +mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf) +{ + ext->lmf.previous_lmf = prev_lmf; + /* Mark that this is a MonoLMFExt */ + ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2); + ext->lmf.gregs [MONO_ARCH_LMF_REG_SP] = (gssize)ext; +} + +#endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */ + +gboolean +mono_arch_opcode_supported (int opcode) +{ + switch (opcode) { + case OP_ATOMIC_ADD_I4: + case OP_ATOMIC_ADD_I8: + case OP_ATOMIC_EXCHANGE_I4: + case OP_ATOMIC_EXCHANGE_I8: + case OP_ATOMIC_CAS_I4: + case OP_ATOMIC_CAS_I8: + case OP_ATOMIC_LOAD_I1: + case OP_ATOMIC_LOAD_I2: + case OP_ATOMIC_LOAD_I4: + case OP_ATOMIC_LOAD_I8: + case OP_ATOMIC_LOAD_U1: + case OP_ATOMIC_LOAD_U2: + case OP_ATOMIC_LOAD_U4: + case OP_ATOMIC_LOAD_U8: + case OP_ATOMIC_LOAD_R4: + case OP_ATOMIC_LOAD_R8: + case OP_ATOMIC_STORE_I1: + case OP_ATOMIC_STORE_I2: + case OP_ATOMIC_STORE_I4: + case OP_ATOMIC_STORE_I8: + case OP_ATOMIC_STORE_U1: + case OP_ATOMIC_STORE_U2: + case OP_ATOMIC_STORE_U4: + case OP_ATOMIC_STORE_U8: + case OP_ATOMIC_STORE_R4: + case OP_ATOMIC_STORE_R8: + return TRUE; + default: + return FALSE; + } +} + +CallInfo* +mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) +{ + return get_call_info (mp, sig); +} + diff --git a/mono/mini/mini-arm64.h b/mono/mini/mini-arm64.h index a963c75d51c..154859e7165 100644 --- a/mono/mini/mini-arm64.h +++ b/mono/mini/mini-arm64.h @@ -1 +1,268 @@ -#include "../../../mono-extensions/mono/mini/mini-arm64.h" +/* + * mini-arm64.h + * + * Copyright 2013 Xamarin Inc + * + * Based on mini-arm.h: + * + * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +#ifndef __MONO_MINI_ARM64_H__ +#define __MONO_MINI_ARM64_H__ + +#include +#include + +#define MONO_ARCH_CPU_SPEC mono_arm64_cpu_desc + +#define MONO_MAX_IREGS 32 +#define MONO_MAX_FREGS 32 + +#define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->regs [0] = (gsize)exc; } while (0) + +#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do { \ + MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0)); \ + MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0)); \ + MONO_CONTEXT_SET_IP ((ctx), (func)); \ + } while (0) + +#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) + +/* Parameters used by the register allocator */ +/* r0..r7, r9..r14 (r15 is the imt/rgctx reg) */ +#define MONO_ARCH_CALLEE_REGS 0xfeff +/* r19..r28 */ +#define MONO_ARCH_CALLEE_SAVED_REGS (0x3ff << 19) + +/* v16/v17 is reserved for a scratch reg */ +#define MONO_ARCH_CALLEE_FREGS 0xfffc00ff +/* v8..v15 */ +#define MONO_ARCH_CALLEE_SAVED_FREGS 0xff00 + +#define MONO_ARCH_USE_FPSTACK FALSE +#define MONO_ARCH_FPSTACK_SIZE 0 + +#define MONO_ARCH_INST_SREG2_MASK(ins) (0) + +#define MONO_ARCH_INST_FIXED_REG(desc) ((desc) == 'a' ? ARMREG_R0 : -1) + +#define MONO_ARCH_INST_IS_REGPAIR(desc) (0) + +#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc) == 'f') + +#define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1) + +#define MONO_ARCH_USE_FPSTACK FALSE + +#define MONO_ARCH_FRAME_ALIGNMENT 16 + +#define MONO_ARCH_CODE_ALIGNMENT 32 + +/* callee saved regs + fp + sp */ +#define MONO_ARCH_LMF_REGS ((0x3ff << 19) | (1 << ARMREG_FP) | (1 << ARMREG_SP)) +#define MONO_ARCH_NUM_LMF_REGS (10 + 2) +#define MONO_ARCH_FIRST_LMF_REG ARMREG_R19 +#define MONO_ARCH_LMF_REG_FP 10 +#define MONO_ARCH_LMF_REG_SP 11 + +struct MonoLMF { + /* + * If the second lowest bit is set to 1, then this is a MonoLMFExt structure, and + * the other fields are not valid. + */ + gpointer previous_lmf; + gpointer lmf_addr; + mgreg_t pc; + mgreg_t gregs [MONO_ARCH_NUM_LMF_REGS]; +}; + +/* Structure used by the sequence points in AOTed code */ +typedef struct { + gpointer ss_trigger_page; + gpointer bp_trigger_page; + gpointer ss_tramp_addr; + guint8* bp_addrs [MONO_ZERO_LEN_ARRAY]; +} SeqPointInfo; + +#define PARAM_REGS 8 +#define FP_PARAM_REGS 8 + +#define DYN_CALL_STACK_ARGS 6 + +typedef struct { + /* The +1 is for r8 */ + mgreg_t regs [PARAM_REGS + 1 + DYN_CALL_STACK_ARGS]; + mgreg_t res, res2; + guint8 *ret; + double fpregs [FP_PARAM_REGS]; + int n_fpargs, n_fpret; + guint8 buffer [256]; +} DynCallArgs; + +typedef struct { + gpointer cinfo; + int saved_gregs_offset; + /* Points to arguments received on the stack */ + int args_reg; + gboolean cond_branch_islands; + gpointer vret_addr_loc; + gpointer seq_point_info_var; + gpointer ss_tramp_var; + gpointer bp_tramp_var; + guint8 *thunks; + int thunks_size; +} MonoCompileArch; + +#define MONO_ARCH_EMULATE_FREM 1 +#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS 1 +#define MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS 1 +#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1 +#define MONO_ARCH_NEED_DIV_CHECK 1 +#define MONO_ARCH_EMULATE_MUL_OVF 1 +#define MONO_ARCH_HAVE_IMT 1 +#define MONO_ARCH_HAVE_OP_TAIL_CALL 1 +#define MONO_ARCH_THIS_AS_FIRST_ARG 1 +#define MONO_ARCH_RGCTX_REG ARMREG_R15 +#define MONO_ARCH_IMT_REG MONO_ARCH_RGCTX_REG +#define MONO_ARCH_VTABLE_REG ARMREG_R0 +#define MONO_ARCH_EXC_REG ARMREG_R0 +#define MONO_ARCH_HAVE_XP_UNWIND 1 +#define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 +#define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 +#define MONO_ARCH_USE_SIGACTION 1 +#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1 +#define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1 +#define MONO_ARCH_GSHARED_SUPPORTED 1 +#define MONO_ARCH_AOT_SUPPORTED 1 +#define MONO_ARCH_LLVM_SUPPORTED 1 +#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1 +#define MONO_ARCH_HAVE_EXCEPTIONS_INIT 1 +#define MONO_ARCH_HAVE_GET_TRAMPOLINES 1 +#define MONO_ARCH_DYN_CALL_SUPPORTED 1 +#define MONO_ARCH_DYN_CALL_PARAM_AREA (DYN_CALL_STACK_ARGS * 8) +#define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 +#ifndef TARGET_ANDROID +#define MONO_ARCH_GSHAREDVT_SUPPORTED 1 +#endif +#define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1 +#define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1 +#define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1 +#ifndef MONO_CROSS_COMPILE +#define MONO_ARCH_ENABLE_MONO_LMF_VAR 1 +#endif +#define MONO_ARCH_HAVE_OP_GET_EX_OBJ 1 +#define MONO_ARCH_HAVE_OBJC_GET_SELECTOR 1 +#define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1 +#define MONO_ARCH_HAVE_PATCH_CODE_NEW 1 +#define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1 +#define MONO_ARCH_HAVE_OPCODE_NEEDS_EMULATION 1 +#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1 + +#ifdef TARGET_IOS + +#define MONO_ARCH_REDZONE_SIZE 128 + +#else + +#define MONO_ARCH_REDZONE_SIZE 0 +#if !defined(__PIC__) +#define MONO_ARCH_HAVE_TLS_GET 1 +#endif +#define MONO_ARCH_HAVE_TLS_GET_REG 1 + +#endif + +#if defined(TARGET_APPLETVOS) +#define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1 +#endif + +/* Relocations */ +#define MONO_R_ARM64_B 1 +#define MONO_R_ARM64_BCC 2 +#define MONO_R_ARM64_IMM 3 +#define MONO_R_ARM64_BL 4 +#define MONO_R_ARM64_BL_SHORT 5 +#define MONO_R_ARM64_CBZ 6 + + +typedef enum { + ArgInIReg, + ArgInFReg, + ArgInFRegR4, + ArgOnStack, + ArgOnStackR8, + ArgOnStackR4, + /* + * Vtype passed in consecutive int registers. + * ainfo->reg is the firs register, + * ainfo->nregs is the number of registers, + * ainfo->size is the size of the structure. + */ + ArgVtypeInIRegs, + ArgVtypeByRef, + ArgVtypeByRefOnStack, + ArgVtypeOnStack, + ArgHFA, + ArgNone +} ArgStorage; + +typedef struct { + ArgStorage storage; + int reg; + /* ArgOnStack */ + int offset; + /* ArgVtypeInIRegs/ArgHFA */ + int nregs, size; + /* ArgHFA */ + int esize; + /* ArgHFA */ + /* The offsets of the float values inside the arg */ + guint16 foffsets [4]; + /* ArgOnStack */ + int slot_size; + /* hfa */ + int nfregs_to_skip; + gboolean sign; + gboolean gsharedvt; + gboolean hfa; +} ArgInfo; + +typedef struct { + int nargs; + int gr, fr, stack_usage; + ArgInfo ret; + ArgInfo sig_cookie; + ArgInfo args [1]; +} CallInfo; + + +guint8* mono_arm_emit_imm64 (guint8 *code, int dreg, gint64 imm); + +guint8* mono_arm_emit_ldrx (guint8 *code, int rt, int rn, int imm); + +guint8* mono_arm_emit_destroy_frame (guint8 *code, int stack_offset, guint64 temp_regs); + +guint8* mono_arm_emit_store_regset (guint8 *code, guint64 regs, int basereg, int offset); + +guint8* mono_arm_emit_store_regarray (guint8 *code, guint64 regs, int basereg, int offset); + +guint8* mono_arm_emit_load_regarray (guint8 *code, guint64 regs, int basereg, int offset); + +/* MonoJumpInfo **ji */ +guint8* mono_arm_emit_aotconst (gpointer ji, guint8 *code, guint8 *code_start, int dreg, guint32 patch_type, gconstpointer data); + +void mono_arm_patch (guint8 *code, guint8 *target, int relocation); + +void mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow); + +void mono_arm_gsharedvt_init (void); + +GSList* mono_arm_get_exception_trampolines (gboolean aot); + +void mono_arm_resume_unwind (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow); + +CallInfo* mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig); + +#endif /* __MONO_MINI_ARM64_H__ */ diff --git a/mono/mini/mini-cross-helpers.c b/mono/mini/mini-cross-helpers.c index dede99f3ee9..28e04d6d628 100644 --- a/mono/mini/mini-cross-helpers.c +++ b/mono/mini/mini-cross-helpers.c @@ -1,13 +1,93 @@ #include "config.h" -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/mini/mini-cross-helpers.c" +#include + +#include "config.h" + +#include "mini.h" +#include "tasklets.h" +#include + +void +mono_dump_metadata_offsets (void); + +void +mono_metadata_cross_helpers_run (void); + + +static void +mono_dump_jit_offsets (void) +{ +#ifdef USED_CROSS_COMPILER_OFFSETS + g_print ("#error not using native offsets\n"); #else + mono_dump_metadata_offsets (); + + g_print ("#ifndef DISABLE_JIT_OFFSETS\n"); + g_print ("#define USED_CROSS_COMPILER_OFFSETS\n"); +#define DISABLE_METADATA_OFFSETS +#define DECL_OFFSET2(struct,field,offset) this_should_not_happen +#define DECL_ALIGN2(type,size) this_should_not_happen -void mono_cross_helpers_run (void); +#define DECL_OFFSET(struct,field) g_print ("DECL_OFFSET2(%s,%s,%d)\n", #struct, #field, (int)MONO_STRUCT_OFFSET (struct, field)); +#define DECL_ALIGN(type) +#define DECL_SIZE2(type,size) this_should_not_happen +#define DECL_SIZE(type) +#include + + g_print ("#endif //disable jit check\n"); + g_print ("#endif //cross compiler checks\n"); + g_print ("#endif //gc check\n"); + g_print ("#endif //os check\n"); + g_print ("#endif //arch check\n"); + g_print ("#endif //USED_CROSS_COMPILER_OFFSETS check\n"); +#endif +} void mono_cross_helpers_run (void) { -} +#if defined (HAS_CROSS_COMPILER_OFFSETS) && !defined (MONO_CROSS_COMPILE) + gboolean is_broken = FALSE; +#endif + +#ifndef USED_CROSS_COMPILER_OFFSETS + if (g_getenv ("DUMP_CROSS_OFFSETS")) + mono_dump_jit_offsets (); #endif + +#if defined (HAS_CROSS_COMPILER_OFFSETS) && !defined (MONO_CROSS_COMPILE) + mono_metadata_cross_helpers_run (); + +#define DISABLE_METADATA_OFFSETS +#define USE_CROSS_COMPILE_OFFSETS +#define DECL_OFFSET(struct,field) this_should_not_happen_for_cross_fields +#define DECL_OFFSET2(struct,field,offset) \ + if ((int)G_STRUCT_OFFSET (struct, field) != offset) { \ + g_print (#struct ":" #field " invalid struct offset %d (expected %d)\n", \ + offset, \ + (int)G_STRUCT_OFFSET (struct, field)); \ + is_broken = TRUE; \ + } +#define DECL_ALIGN(name,type) this_should_not_happen_for_cross_align +#define DECL_ALIGN2(name,size) \ + if (MONO_ALIGN_ ## name != size) { \ + g_print (#name ": invalid alignment %d (expected %d)\n", \ + size, \ + MONO_ALIGN_ ## name); \ + is_broken = TRUE; \ + } +#define DECL_SIZE(type) this_should_not_happen_for_cross_size +#define DECL_SIZE2(name,size) \ + if (MONO_SIZEOF_ ## name != size) { \ + g_print (#name ": invalid size %d (expected %d)\n", \ + size, \ + MONO_SIZEOF_ ## name); \ + is_broken = TRUE; \ + } + +#include + + g_assert (!is_broken); +#endif +} diff --git a/mono/mini/mini-darwin.c b/mono/mini/mini-darwin.c index 659075cc30a..4f8fbcf6585 100644 --- a/mono/mini/mini-darwin.c +++ b/mono/mini/mini-darwin.c @@ -8,7 +8,7 @@ * Copyright 2003-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) * - * See LICENSE for licensing information. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/mini-exceptions-native-unwinder.c b/mono/mini/mini-exceptions-native-unwinder.c new file mode 100644 index 00000000000..64e0e39eae4 --- /dev/null +++ b/mono/mini/mini-exceptions-native-unwinder.c @@ -0,0 +1,245 @@ +/* + * mini-exceptions-native-unwinder.c: libcorkscrew-based native unwinder + * + * Authors: + * Alex Rønne Petersen (alexrp@xamarin.com) + * + * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include + +/* + * Attempt to handle native SIGSEGVs with libunwind or libcorkscrew. + */ + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#include +#include "mini.h" + +#if defined (PLATFORM_ANDROID) + +#include +#include +#include + +#define UNW_LOCAL_ONLY +#undef _U /* ctype.h apparently defines this and it screws up the libunwind headers. */ +#include "android-libunwind/libunwind.h" +#define _U 0x01 + +#define FUNC_NAME_LENGTH 512 +#define FRAMES_TO_UNWIND 256 + +/* Expand the SYM argument. */ +#define LOAD_SYM(DL, ERR, SYM, VAR) _LOAD_SYM(DL, ERR, SYM, VAR) +#define _LOAD_SYM(DL, ERR, SYM, VAR) \ + do { \ + if ((ERR = mono_dl_symbol (DL, #SYM, (void **) &VAR))) { \ + mono_dl_close (DL); \ + return ERR; \ + } \ + } while (0) + +typedef int (*unw_init_local_t) (unw_cursor_t *, unw_context_t *); +typedef int (*unw_get_reg_t) (unw_cursor_t *, int, unw_word_t *); +typedef int (*unw_get_proc_name_t) (unw_cursor_t *, char *, size_t, unw_word_t *); +typedef int (*unw_step_t) (unw_cursor_t *); + +static char * +mono_extension_handle_native_sigsegv_libunwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info) +{ + char *dl_err; + int unw_err; + + unw_init_local_t unw_init_local_fn; + unw_get_reg_t unw_get_reg_fn; + unw_get_proc_name_t unw_get_proc_name_fn; + unw_step_t unw_step_fn; + + unw_cursor_t cursor; + + size_t frames = 0; + + MonoDl *dl = mono_dl_open ("libunwind.so", MONO_DL_LAZY, &dl_err); + + if (!dl) + return dl_err; + + LOAD_SYM (dl, dl_err, UNW_OBJ (init_local), unw_init_local_fn); + LOAD_SYM (dl, dl_err, UNW_OBJ (get_reg), unw_get_reg_fn); + LOAD_SYM (dl, dl_err, UNW_OBJ (get_proc_name), unw_get_proc_name_fn); + LOAD_SYM (dl, dl_err, UNW_OBJ (step), unw_step_fn); + + if ((unw_err = unw_init_local_fn (&cursor, ctx))) { + mono_dl_close (dl); + + return g_strdup_printf ("unw_init_local () returned %d", unw_err); + } + + do { + int reg_err; + + unw_word_t ip, off; + char name [FUNC_NAME_LENGTH]; + + if ((reg_err = unw_get_reg_fn (&cursor, UNW_REG_IP, &ip))) { + mono_runtime_printf_err ("unw_get_reg (UNW_REG_IP) returned %d", reg_err); + break; + } + + reg_err = unw_get_proc_name_fn (&cursor, name, FUNC_NAME_LENGTH, &off); + + if (reg_err == -UNW_ENOINFO) + strcpy (name, "???"); + + mono_runtime_printf_err (" at %s+%zu [0x%zx]", name, off, ip); + + unw_err = unw_step_fn (&cursor); + frames++; + } while (unw_err > 0 && frames < FRAMES_TO_UNWIND); + + if (unw_err < 0) + mono_runtime_printf_err ("unw_step () returned %d", unw_err); + + mono_dl_close (dl); + + return NULL; +} + +/* + * This code is based on the AOSP header system/core/include/corkscrew/backtrace.h. + * + * This is copied here because libcorkscrew is not a stable library and the header (and + * other headers that it depends on) will eventually go away. + * + * We can probably remove this one day when libunwind becomes the norm. + */ + +typedef struct { + uintptr_t absolute_pc; + uintptr_t stack_top; + size_t stack_size; +} backtrace_frame_t; + +typedef struct { + uintptr_t relative_pc; + uintptr_t relative_symbol_addr; + char *map_name; + char *symbol_name; + char *demangled_name; +} backtrace_symbol_t; + +typedef void (*get_backtrace_symbols_t) (const backtrace_frame_t *backtrace, size_t frames, backtrace_symbol_t *backtrace_symbols); +typedef void (*free_backtrace_symbols_t) (backtrace_symbol_t *backtrace_symbols, size_t frames); + +enum { + MAX_BACKTRACE_LINE_LENGTH = 800, +}; + +/* Internals that we're exploiting to work in a signal handler. Only works on ARM/x86. */ + +typedef struct map_info_t map_info_t; + +typedef ssize_t (*unwind_backtrace_signal_arch_t) (siginfo_t *si, void *sc, const map_info_t *lst, backtrace_frame_t *bt, size_t ignore_depth, size_t max_depth); +typedef map_info_t *(*acquire_my_map_info_list_t) (void); +typedef void (*release_my_map_info_list_t) (map_info_t *milist); + +static char * +mono_extension_handle_native_sigsegv_libcorkscrew (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info) +{ +#if defined (__arm__) || defined (__i386__) + char *dl_err; + + get_backtrace_symbols_t get_backtrace_symbols; + free_backtrace_symbols_t free_backtrace_symbols; + unwind_backtrace_signal_arch_t unwind_backtrace_signal_arch; + acquire_my_map_info_list_t acquire_my_map_info_list; + release_my_map_info_list_t release_my_map_info_list; + + backtrace_frame_t frames [FRAMES_TO_UNWIND]; + backtrace_symbol_t symbols [FRAMES_TO_UNWIND]; + + map_info_t *map_info; + ssize_t frames_unwound; + size_t i; + + MonoDl *dl = mono_dl_open ("libcorkscrew.so", MONO_DL_LAZY, &dl_err); + + if (!dl) + return dl_err; + + LOAD_SYM (dl, dl_err, get_backtrace_symbols, get_backtrace_symbols); + LOAD_SYM (dl, dl_err, free_backtrace_symbols, free_backtrace_symbols); + LOAD_SYM (dl, dl_err, unwind_backtrace_signal_arch, unwind_backtrace_signal_arch); + LOAD_SYM (dl, dl_err, acquire_my_map_info_list, acquire_my_map_info_list); + LOAD_SYM (dl, dl_err, release_my_map_info_list, release_my_map_info_list); + + map_info = acquire_my_map_info_list (); + frames_unwound = unwind_backtrace_signal_arch (info, ctx, map_info, frames, 0, FRAMES_TO_UNWIND); + release_my_map_info_list (map_info); + + if (frames_unwound == -1) { + mono_dl_close (dl); + + return g_strdup ("unwind_backtrace_signal_arch () returned -1"); + } + + get_backtrace_symbols (frames, frames_unwound, symbols); + + for (i = 0; i < frames_unwound; i++) { + backtrace_frame_t *frame = frames + i; + backtrace_symbol_t *symbol = symbols + i; + + const char *name = symbol->demangled_name ? symbol->demangled_name : (symbol->symbol_name ? symbol->symbol_name : "???"); + uintptr_t off = symbol->relative_pc - symbol->relative_symbol_addr; + uintptr_t ip = frame->absolute_pc; + + mono_runtime_printf_err (" at %s+%zu [0x%zx]", name, off, ip); + } + + free_backtrace_symbols (symbols, frames_unwound); + + mono_dl_close (dl); + + return NULL; +#else + return g_strdup ("libcorkscrew is only supported on 32-bit ARM/x86"); +#endif +} + +void +mono_exception_native_unwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info) +{ + char *unwind_err, *corkscrew_err; + + mono_runtime_printf_err ("\nAttempting native Android stacktrace:\n"); + + unwind_err = mono_extension_handle_native_sigsegv_libunwind (ctx, info); + + if (unwind_err) { + corkscrew_err = mono_extension_handle_native_sigsegv_libcorkscrew (ctx, info); + + if (corkscrew_err) { + mono_runtime_printf_err ("\tCould not unwind with `libunwind.so`: %s", unwind_err); + mono_runtime_printf_err ("\tCould not unwind with `libcorkscrew.so`: %s", corkscrew_err); + mono_runtime_printf_err ("\n\tNo options left to get a native stacktrace :-("); + + g_free (corkscrew_err); + } + + g_free (unwind_err); + } +} + +#else + +void +mono_exception_native_unwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info) +{ +} + +#endif diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 77d5fdcb1eb..479aed2f41a 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -8,6 +8,7 @@ * Copyright 2001-2003 Ximian, Inc. * Copyright 2003-2008 Novell, Inc. * Copyright 2011 Xamarin Inc (http://www.xamarin.com). + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -77,10 +78,6 @@ #include "mini-llvm-cpp.h" #endif -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/mini/mini-exceptions.c" -#endif - #ifndef MONO_ARCH_CONTEXT_DEF #define MONO_ARCH_CONTEXT_DEF #endif @@ -2400,8 +2397,8 @@ mono_handle_native_sigsegv (int signal, void *ctx, MONO_SIG_HANDLER_INFO_TYPE *i } #endif } -#elif defined (ENABLE_EXTENSION_MODULE) - mono_extension_handle_native_sigsegv (ctx, info); +#else + mono_exception_native_unwind (ctx, info); #endif /* diff --git a/mono/mini/mini-gc.c b/mono/mini/mini-gc.c index 47265e1d10f..f50d686347e 100644 --- a/mono/mini/mini-gc.c +++ b/mono/mini/mini-gc.c @@ -6,6 +6,7 @@ * * Copyright 2009 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/mini/mini-generic-sharing-gsharedvt.c b/mono/mini/mini-generic-sharing-gsharedvt.c new file mode 100644 index 00000000000..d4a0406edf6 --- /dev/null +++ b/mono/mini/mini-generic-sharing-gsharedvt.c @@ -0,0 +1,292 @@ +/* + * mini-exceptions-native-unwinder.c: libcorkscrew-based native unwinder + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include + +#include +#include +#include +#include + +#include "mini.h" +static gboolean gsharedvt_supported; + +void +mono_set_generic_sharing_vt_supported (gboolean supported) +{ + gsharedvt_supported = supported; +} + +#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED + +/* + * mini_is_gsharedvt_type: + * + * Return whenever T references type arguments instantiated with gshared vtypes. + */ +gboolean +mini_is_gsharedvt_type (MonoType *t) +{ + int i; + + if (t->byref) + return FALSE; + if ((t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) && t->data.generic_param->gshared_constraint && t->data.generic_param->gshared_constraint->type == MONO_TYPE_VALUETYPE) + return TRUE; + else if (t->type == MONO_TYPE_GENERICINST) { + MonoGenericClass *gclass = t->data.generic_class; + MonoGenericContext *context = &gclass->context; + MonoGenericInst *inst; + + inst = context->class_inst; + if (inst) { + for (i = 0; i < inst->type_argc; ++i) + if (mini_is_gsharedvt_type (inst->type_argv [i])) + return TRUE; + } + inst = context->method_inst; + if (inst) { + for (i = 0; i < inst->type_argc; ++i) + if (mini_is_gsharedvt_type (inst->type_argv [i])) + return TRUE; + } + + return FALSE; + } else { + return FALSE; + } +} + +gboolean +mini_is_gsharedvt_klass (MonoClass *klass) +{ + return mini_is_gsharedvt_type (&klass->byval_arg); +} + +gboolean +mini_is_gsharedvt_signature (MonoMethodSignature *sig) +{ + int i; + + if (sig->ret && mini_is_gsharedvt_type (sig->ret)) + return TRUE; + for (i = 0; i < sig->param_count; ++i) { + if (mini_is_gsharedvt_type (sig->params [i])) + return TRUE; + } + return FALSE; +} + +/* + * mini_is_gsharedvt_variable_type: + * + * Return whenever T refers to a GSHAREDVT type whose size differs depending on the values of type parameters. + */ +gboolean +mini_is_gsharedvt_variable_type (MonoType *t) +{ + if (!mini_is_gsharedvt_type (t)) + return FALSE; + if (t->type == MONO_TYPE_GENERICINST) { + MonoGenericClass *gclass = t->data.generic_class; + MonoGenericContext *context = &gclass->context; + MonoGenericInst *inst; + int i; + + if (t->data.generic_class->container_class->byval_arg.type != MONO_TYPE_VALUETYPE || t->data.generic_class->container_class->enumtype) + return FALSE; + + inst = context->class_inst; + if (inst) { + for (i = 0; i < inst->type_argc; ++i) + if (mini_is_gsharedvt_variable_type (inst->type_argv [i])) + return TRUE; + } + inst = context->method_inst; + if (inst) { + for (i = 0; i < inst->type_argc; ++i) + if (mini_is_gsharedvt_variable_type (inst->type_argv [i])) + return TRUE; + } + + return FALSE; + } + return TRUE; +} + +static gboolean +is_variable_size (MonoType *t) +{ + int i; + + if (t->byref) + return FALSE; + + if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) { + MonoGenericParam *param = t->data.generic_param; + + if (param->gshared_constraint && param->gshared_constraint->type != MONO_TYPE_VALUETYPE && param->gshared_constraint->type != MONO_TYPE_GENERICINST) + return FALSE; + if (param->gshared_constraint && param->gshared_constraint->type == MONO_TYPE_GENERICINST) + return is_variable_size (param->gshared_constraint); + return TRUE; + } + if (t->type == MONO_TYPE_GENERICINST && t->data.generic_class->container_class->byval_arg.type == MONO_TYPE_VALUETYPE) { + MonoGenericClass *gclass = t->data.generic_class; + MonoGenericContext *context = &gclass->context; + MonoGenericInst *inst; + + inst = context->class_inst; + if (inst) { + for (i = 0; i < inst->type_argc; ++i) + if (is_variable_size (inst->type_argv [i])) + return TRUE; + } + inst = context->method_inst; + if (inst) { + for (i = 0; i < inst->type_argc; ++i) + if (is_variable_size (inst->type_argv [i])) + return TRUE; + } + } + + return FALSE; +} + +gboolean +mini_is_gsharedvt_sharable_inst (MonoGenericInst *inst) +{ + int i; + gboolean has_vt = FALSE; + + for (i = 0; i < inst->type_argc; ++i) { + MonoType *type = inst->type_argv [i]; + + if ((MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) && !mini_is_gsharedvt_type (type)) { + } else { + has_vt = TRUE; + } + } + + return has_vt; +} + +gboolean +mini_is_gsharedvt_sharable_method (MonoMethod *method) +{ + MonoMethodSignature *sig; + + /* + * A method is gsharedvt if: + * - it has type parameters instantiated with vtypes + */ + if (!gsharedvt_supported) + return FALSE; + if (method->is_inflated) { + MonoMethodInflated *inflated = (MonoMethodInflated*)method; + MonoGenericContext *context = &inflated->context; + MonoGenericInst *inst; + + if (context->class_inst && context->method_inst) { + /* At least one inst has to be gsharedvt sharable, and the other normal or gsharedvt sharable */ + gboolean vt1 = mini_is_gsharedvt_sharable_inst (context->class_inst); + gboolean vt2 = mini_is_gsharedvt_sharable_inst (context->method_inst); + + if ((vt1 && vt2) || + (vt1 && mini_generic_inst_is_sharable (context->method_inst, TRUE, FALSE)) || + (vt2 && mini_generic_inst_is_sharable (context->class_inst, TRUE, FALSE))) + ; + else + return FALSE; + } else { + inst = context->class_inst; + if (inst && !mini_is_gsharedvt_sharable_inst (inst)) + return FALSE; + inst = context->method_inst; + if (inst && !mini_is_gsharedvt_sharable_inst (inst)) + return FALSE; + } + } else { + return FALSE; + } + + sig = mono_method_signature (mono_method_get_declaring_generic_method (method)); + if (!sig) + return FALSE; + + /* + if (mini_is_gsharedvt_variable_signature (sig)) + return FALSE; + */ + + //DEBUG ("GSHAREDVT SHARABLE: %s\n", mono_method_full_name (method, TRUE)); + + return TRUE; +} + +/* + * mini_is_gsharedvt_variable_signature: + * + * Return whenever the calling convention used to call SIG varies depending on the values of type parameters used by SIG, + * i.e. FALSE for swap(T[] arr, int i, int j), TRUE for T get_t (). + */ +gboolean +mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig) +{ + int i; + + if (sig->ret && is_variable_size (sig->ret)) + return TRUE; + for (i = 0; i < sig->param_count; ++i) { + MonoType *t = sig->params [i]; + + if (is_variable_size (t)) + return TRUE; + } + return FALSE; +} +#else + +gboolean +mini_is_gsharedvt_type (MonoType *t) +{ + return FALSE; +} + +gboolean +mini_is_gsharedvt_klass (MonoClass *klass) +{ + return FALSE; +} + +gboolean +mini_is_gsharedvt_signature (MonoMethodSignature *sig) +{ + return FALSE; +} + +gboolean +mini_is_gsharedvt_variable_type (MonoType *t) +{ + return FALSE; +} + +gboolean +mini_is_gsharedvt_sharable_method (MonoMethod *method) +{ + return FALSE; +} + +gboolean +mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig) +{ + return FALSE; +} + +#endif /* !MONO_ARCH_GSHAREDVT_SUPPORTED */ diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c index cba6d8e7ac9..43137b6885f 100644 --- a/mono/mini/mini-generic-sharing.c +++ b/mono/mini/mini-generic-sharing.c @@ -6,6 +6,7 @@ * * Copyright 2007-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -2485,11 +2486,6 @@ mono_method_lookup_rgctx (MonoVTable *class_vtable, MonoGenericInst *method_inst return mrgctx; } - -static gboolean -generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars, - gboolean allow_partial); - static gboolean type_is_sharable (MonoType *type, gboolean allow_type_vars, gboolean allow_partial) { @@ -2510,9 +2506,9 @@ type_is_sharable (MonoType *type, gboolean allow_type_vars, gboolean allow_parti if (allow_partial && !type->byref && type->type == MONO_TYPE_GENERICINST && MONO_TYPE_ISSTRUCT (type)) { MonoGenericClass *gclass = type->data.generic_class; - if (gclass->context.class_inst && !generic_inst_is_sharable (gclass->context.class_inst, allow_type_vars, allow_partial)) + if (gclass->context.class_inst && !mini_generic_inst_is_sharable (gclass->context.class_inst, allow_type_vars, allow_partial)) return FALSE; - if (gclass->context.method_inst && !generic_inst_is_sharable (gclass->context.method_inst, allow_type_vars, allow_partial)) + if (gclass->context.method_inst && !mini_generic_inst_is_sharable (gclass->context.method_inst, allow_type_vars, allow_partial)) return FALSE; if (mono_class_is_nullable (mono_class_from_mono_type (type))) return FALSE; @@ -2522,8 +2518,8 @@ type_is_sharable (MonoType *type, gboolean allow_type_vars, gboolean allow_parti return FALSE; } -static gboolean -generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars, +gboolean +mini_generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars, gboolean allow_partial) { int i; @@ -2572,10 +2568,10 @@ mono_generic_context_is_sharable_full (MonoGenericContext *context, { g_assert (context->class_inst || context->method_inst); - if (context->class_inst && !generic_inst_is_sharable (context->class_inst, allow_type_vars, allow_partial)) + if (context->class_inst && !mini_generic_inst_is_sharable (context->class_inst, allow_type_vars, allow_partial)) return FALSE; - if (context->method_inst && !generic_inst_is_sharable (context->method_inst, allow_type_vars, allow_partial)) + if (context->method_inst && !mini_generic_inst_is_sharable (context->method_inst, allow_type_vars, allow_partial)) return FALSE; return TRUE; @@ -2863,7 +2859,6 @@ mono_method_construct_object_context (MonoMethod *method) } static gboolean gshared_supported; -static gboolean gsharedvt_supported; void mono_set_generic_sharing_supported (gboolean supported) @@ -2871,11 +2866,6 @@ mono_set_generic_sharing_supported (gboolean supported) gshared_supported = supported; } -void -mono_set_generic_sharing_vt_supported (gboolean supported) -{ - gsharedvt_supported = supported; -} void mono_set_partial_sharing_supported (gboolean supported) @@ -3385,7 +3375,7 @@ get_shared_inst (MonoGenericInst *inst, MonoGenericInst *shared_inst, MonoGeneri if (all_vt || gsharedvt) { type_argv [i] = get_gsharedvt_type (shared_inst->type_argv [i]); } else { - /* These types match the ones in generic_inst_is_sharable () */ + /* These types match the ones in mini_generic_inst_is_sharable () */ type_argv [i] = get_shared_type (shared_inst->type_argv [i], inst->type_argv [i]); } } @@ -3528,47 +3518,3 @@ mini_get_rgctx_entry_slot (MonoJumpInfoRgctxEntry *entry) return slot; } - -#if defined(ENABLE_GSHAREDVT) - -#include "../../../mono-extensions/mono/mini/mini-generic-sharing-gsharedvt.c" - -#else - -gboolean -mini_is_gsharedvt_type (MonoType *t) -{ - return FALSE; -} - -gboolean -mini_is_gsharedvt_klass (MonoClass *klass) -{ - return FALSE; -} - -gboolean -mini_is_gsharedvt_signature (MonoMethodSignature *sig) -{ - return FALSE; -} - -gboolean -mini_is_gsharedvt_variable_type (MonoType *t) -{ - return FALSE; -} - -gboolean -mini_is_gsharedvt_sharable_method (MonoMethod *method) -{ - return FALSE; -} - -gboolean -mini_is_gsharedvt_variable_signature (MonoMethodSignature *sig) -{ - return FALSE; -} - -#endif /* !MONOTOUCH */ diff --git a/mono/mini/mini-llvm-cpp.cpp b/mono/mini/mini-llvm-cpp.cpp index 8122365cab9..e3219686ae2 100644 --- a/mono/mini/mini-llvm-cpp.cpp +++ b/mono/mini/mini-llvm-cpp.cpp @@ -3,6 +3,7 @@ // // (C) 2009-2011 Novell, Inc. // Copyright 2011 Xamarin, Inc (http://www.xamarin.com) +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // // diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c index f8aa2390615..adec297e3c3 100644 --- a/mono/mini/mini-llvm.c +++ b/mono/mini/mini-llvm.c @@ -3,6 +3,7 @@ * * Copyright 2009-2011 Novell Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" diff --git a/mono/mini/mini-native-types.c b/mono/mini/mini-native-types.c index 9dadbc30a5d..9ce9be8a98c 100644 --- a/mono/mini/mini-native-types.c +++ b/mono/mini/mini-native-types.c @@ -1,23 +1,446 @@ +/* + * magic-types.c: intrinsics for variable sized int/floats + * + * Author: + * Rodrigo Kumpera (kumpera@gmail.com) + * + * (C) 2013 Xamarin + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + #include +#include + +#include "mini.h" +#include "ir-emit.h" +#include "glib.h" + + +typedef struct { + const char *op_name; + short op_table[4]; +} IntIntrisic; + +typedef struct { + short op_index; + short big_stack_type; + short small_stack_type; + short stack_type; + short conv_4_to_8; + short conv_8_to_4; + short move; + short inc_op; + short dec_op; + short store_op; + short compare_op; +} MagicTypeInfo; + -#if defined(MONO_NATIVE_TYPES) +#if SIZEOF_VOID_P == 8 +#define OP_PT_ADD OP_LADD +#define OP_PT_SUB OP_LSUB +#define OP_PT_MUL OP_LMUL +#define OP_PT_DIV OP_LDIV +#define OP_PT_REM OP_LREM +#define OP_PT_NEG OP_LNEG +#define OP_PT_AND OP_LAND +#define OP_PT_OR OP_LOR +#define OP_PT_XOR OP_LXOR +#define OP_PT_NOT OP_LNOT +#define OP_PT_SHL OP_LSHL +#define OP_PT_SHR OP_LSHR -#include "../../../mono-extensions/mono/mini/mini-native-types.c" +#define OP_PT_DIV_UN OP_LDIV_UN +#define OP_PT_REM_UN OP_LREM_UN +#define OP_PT_SHR_UN OP_LSHR_UN + +#define OP_PT_ADD_IMM OP_LADD_IMM +#define OP_PT_SUB_IMM OP_LSUB_IMM + +#define OP_PT_STORE_FP_MEMBASE_REG OP_STORER8_MEMBASE_REG + +#define OP_PCOMPARE OP_LCOMPARE #else +#define OP_PT_ADD OP_IADD +#define OP_PT_SUB OP_ISUB +#define OP_PT_MUL OP_IMUL +#define OP_PT_DIV OP_IDIV +#define OP_PT_REM OP_IREM +#define OP_PT_NEG OP_INEG +#define OP_PT_AND OP_IAND +#define OP_PT_OR OP_IOR +#define OP_PT_XOR OP_IXOR +#define OP_PT_NOT OP_INOT +#define OP_PT_SHL OP_ISHL +#define OP_PT_SHR OP_ISHR -#include "mini.h" +#define OP_PT_DIV_UN OP_IDIV_UN +#define OP_PT_REM_UN OP_IREM_UN +#define OP_PT_SHR_UN OP_ISHR_UN -MonoType* -mini_native_type_replace_type (MonoType *type) +#define OP_PT_ADD_IMM OP_IADD_IMM +#define OP_PT_SUB_IMM OP_ISUB_IMM + +#define OP_PT_STORE_FP_MEMBASE_REG OP_STORER4_MEMBASE_REG + +#define OP_PCOMPARE OP_ICOMPARE + +#endif + +static const IntIntrisic int_binop[] = { + { "op_Addition", { OP_PT_ADD, OP_PT_ADD, OP_FADD, OP_RADD } }, + { "op_Subtraction", { OP_PT_SUB, OP_PT_SUB, OP_FSUB, OP_RSUB } }, + { "op_Multiply", { OP_PT_MUL, OP_PT_MUL, OP_FMUL, OP_RMUL } }, + { "op_Division", { OP_PT_DIV, OP_PT_DIV_UN, OP_FDIV, OP_RDIV } }, + { "op_Modulus", { OP_PT_REM, OP_PT_REM_UN, OP_FREM, OP_RREM } }, + { "op_BitwiseAnd", { OP_PT_AND, OP_PT_AND } }, + { "op_BitwiseOr", { OP_PT_OR, OP_PT_OR } }, + { "op_ExclusiveOr", { OP_PT_XOR, OP_PT_XOR } }, + { "op_LeftShift", { OP_PT_SHL, OP_PT_SHL } }, + { "op_RightShift", { OP_PT_SHR, OP_PT_SHR_UN } }, +}; + +static const IntIntrisic int_unnop[] = { + { "op_UnaryPlus", { OP_MOVE, OP_MOVE, OP_FMOVE, OP_RMOVE } }, + { "op_UnaryNegation", { OP_PT_NEG, OP_PT_NEG, OP_FNEG, OP_RNEG } }, + { "op_OnesComplement", { OP_PT_NOT, OP_PT_NOT, OP_FNOT, OP_RNOT } }, +}; + +static const IntIntrisic int_cmpop[] = { + { "op_Inequality", { OP_ICNEQ, OP_ICNEQ, OP_FCNEQ, OP_RCNEQ } }, + { "op_Equality", { OP_ICEQ, OP_ICEQ, OP_FCEQ, OP_RCEQ } }, + { "op_GreaterThan", { OP_ICGT, OP_ICGT_UN, OP_FCGT, OP_RCGT } }, + { "op_GreaterThanOrEqual", { OP_ICGE, OP_ICGE_UN, OP_FCGE, OP_RCGE } }, + { "op_LessThan", { OP_ICLT, OP_ICLT_UN, OP_FCLT, OP_RCLT } }, + { "op_LessThanOrEqual", { OP_ICLE, OP_ICLE_UN, OP_FCLE, OP_RCLE } }, +}; + +static const MagicTypeInfo type_info[] = { + //nint + { 0, STACK_I8, STACK_I4, STACK_PTR, OP_ICONV_TO_I8, OP_LCONV_TO_I4, OP_MOVE, OP_PT_ADD_IMM, OP_PT_SUB_IMM, OP_STORE_MEMBASE_REG, OP_PCOMPARE }, + //nuint + { 1, STACK_I8, STACK_I4, STACK_PTR, OP_ICONV_TO_U8, OP_LCONV_TO_U4, OP_MOVE, OP_PT_ADD_IMM, OP_PT_SUB_IMM, OP_STORE_MEMBASE_REG, OP_PCOMPARE }, + //nfloat + { 2, STACK_R8, STACK_R8, STACK_R8, OP_FCONV_TO_R8, OP_FCONV_TO_R4, OP_FMOVE, 0, 0, OP_PT_STORE_FP_MEMBASE_REG, 0 }, +}; + +static inline gboolean mono_class_is_magic_int (MonoClass *klass); +static inline gboolean mono_class_is_magic_float (MonoClass *klass); + + +static inline gboolean +type_size (MonoCompile *cfg, MonoType *type) { - return type; + if (type->type == MONO_TYPE_I4 || type->type == MONO_TYPE_U4) + return 4; + else if (type->type == MONO_TYPE_I8 || type->type == MONO_TYPE_U8) + return 8; + else if (type->type == MONO_TYPE_R4 && !type->byref && cfg->r4fp) + return 4; + else if (type->type == MONO_TYPE_R8 && !type->byref) + return 8; + return SIZEOF_VOID_P; } +#ifndef DISABLE_JIT + +static gboolean is_int_type (MonoType *t); +static gboolean is_float_type (MonoType *t); + +static MonoInst* +emit_narrow (MonoCompile *cfg, const MagicTypeInfo *info, int sreg) +{ + MonoInst *ins; + + MONO_INST_NEW (cfg, ins, info->conv_8_to_4); + ins->sreg1 = sreg; + if (info->conv_8_to_4 == OP_FCONV_TO_R4) + ins->type = cfg->r4_stack_type; + else + ins->type = info->small_stack_type; + ins->dreg = alloc_dreg (cfg, ins->type); + MONO_ADD_INS (cfg->cbb, ins); + return mono_decompose_opcode (cfg, ins); +} + +static MonoInst* +emit_widen (MonoCompile *cfg, const MagicTypeInfo *info, int sreg) +{ + MonoInst *ins; + + if (cfg->r4fp && info->conv_4_to_8 == OP_FCONV_TO_R8) + MONO_INST_NEW (cfg, ins, OP_RCONV_TO_R8); + else + MONO_INST_NEW (cfg, ins, info->conv_4_to_8); + ins->sreg1 = sreg; + ins->type = info->big_stack_type; + ins->dreg = alloc_dreg (cfg, info->big_stack_type); + MONO_ADD_INS (cfg->cbb, ins); + return mono_decompose_opcode (cfg, ins); +} + +static MonoInst* +emit_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args, const MagicTypeInfo *info) +{ + int i = 0; + const char *name = cmethod->name; + MonoInst *ins; + int type_index, stack_type; + + if (info->op_index == 2 && cfg->r4fp && SIZEOF_VOID_P == 4) { + type_index = 3; + stack_type = STACK_R4; + } else { + type_index = info->op_index; + stack_type = info->stack_type; + } + + if (!strcmp ("op_Implicit", name) || !strcmp ("op_Explicit", name)) { + int source_size = type_size (cfg, fsig->params [0]); + int dest_size = type_size (cfg, fsig->ret); + + switch (info->big_stack_type) { + case STACK_I8: + if (!is_int_type (fsig->params [0]) || !is_int_type (fsig->ret)) + return NULL; + break; + case STACK_R8: + if (!is_float_type (fsig->params [0]) || !is_float_type (fsig->ret)) + return NULL; + break; + default: + g_assert_not_reached (); + } + + //4 -> 4 or 8 -> 8 + if (source_size == dest_size) + return args [0]; + + //4 -> 8 + if (source_size < dest_size) + return emit_widen (cfg, info, args [0]->dreg); + + //8 -> 4 + return emit_narrow (cfg, info, args [0]->dreg); + } + + if (!strcmp (".ctor", name)) { + gboolean is_ldaddr = args [0]->opcode == OP_LDADDR; + int arg0 = args [1]->dreg; + int arg_size = type_size (cfg, fsig->params [0]); + + if (arg_size > SIZEOF_VOID_P) //8 -> 4 + arg0 = emit_narrow (cfg, info, arg0)->dreg; + else if (arg_size < SIZEOF_VOID_P) //4 -> 8 + arg0 = emit_widen (cfg, info, arg0)->dreg; + + if (is_ldaddr) { /*Eliminate LDADDR if it's initing a local var*/ + int dreg = ((MonoInst*)args [0]->inst_p0)->dreg; + NULLIFY_INS (args [0]); + EMIT_NEW_UNALU (cfg, ins, info->move, dreg, arg0); + cfg->has_indirection = TRUE; + } else { + EMIT_NEW_STORE_MEMBASE (cfg, ins, info->store_op, args [0]->dreg, 0, arg0); + } + return ins; + } + + if (!strcmp ("op_Increment", name) || !strcmp ("op_Decrement", name)) { + gboolean inc = !strcmp ("op_Increment", name); + /* FIXME float inc is too complex to bother with*/ + //this is broken with ints too + // if (!info->inc_op) + return NULL; + + /* We have IR for inc/dec */ + MONO_INST_NEW (cfg, ins, inc ? info->inc_op : info->dec_op); + ins->dreg = alloc_dreg (cfg, info->stack_type); + ins->sreg1 = args [0]->dreg; + ins->inst_imm = 1; + ins->type = info->stack_type; + MONO_ADD_INS (cfg->cbb, ins); + return ins; + } + + for (i = 0; i < sizeof (int_binop) / sizeof (IntIntrisic); ++i) { + if (!strcmp (int_binop [i].op_name, name)) { + if (!int_binop [i].op_table [info->op_index]) + return NULL; + g_assert (int_binop [i].op_table [type_index]); + + MONO_INST_NEW (cfg, ins, int_binop [i].op_table [type_index]); + ins->dreg = alloc_dreg (cfg, stack_type); + ins->sreg1 = args [0]->dreg; + ins->sreg2 = args [1]->dreg; + ins->type = stack_type; + MONO_ADD_INS (cfg->cbb, ins); + return mono_decompose_opcode (cfg, ins); + } + } + + for (i = 0; i < sizeof (int_unnop) / sizeof (IntIntrisic); ++i) { + if (!strcmp (int_unnop [i].op_name, name)) { + g_assert (int_unnop [i].op_table [type_index]); + + MONO_INST_NEW (cfg, ins, int_unnop [i].op_table [type_index]); + ins->dreg = alloc_dreg (cfg, stack_type); + ins->sreg1 = args [0]->dreg; + ins->type = stack_type; + MONO_ADD_INS (cfg->cbb, ins); + return ins; + } + } + + for (i = 0; i < sizeof (int_cmpop) / sizeof (IntIntrisic); ++i) { + if (!strcmp (int_cmpop [i].op_name, name)) { + g_assert (int_cmpop [i].op_table [type_index]); + + if (info->compare_op) { + MONO_INST_NEW (cfg, ins, info->compare_op); + ins->dreg = -1; + ins->sreg1 = args [0]->dreg; + ins->sreg2 = args [1]->dreg; + MONO_ADD_INS (cfg->cbb, ins); + + MONO_INST_NEW (cfg, ins, int_cmpop [i].op_table [type_index]); + ins->dreg = alloc_preg (cfg); + ins->type = STACK_I4; + MONO_ADD_INS (cfg->cbb, ins); + } else { + MONO_INST_NEW (cfg, ins, int_cmpop [i].op_table [type_index]); + ins->dreg = alloc_ireg (cfg); + ins->sreg1 = args [0]->dreg; + ins->sreg2 = args [1]->dreg; + MONO_ADD_INS (cfg->cbb, ins); + } + + return ins; + } + } + + return NULL; +} + + MonoInst* mono_emit_native_types_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args) { + if (mono_class_is_magic_int (cmethod->klass)) { + const char *class_name = cmethod->klass->name; + if (!strcmp ("nint", class_name)) + return emit_intrinsics (cfg, cmethod, fsig, args, &type_info [0]); + else + return emit_intrinsics (cfg, cmethod, fsig, args, &type_info [1]); + } else if (mono_class_is_magic_float (cmethod->klass)) + return emit_intrinsics (cfg, cmethod, fsig, args, &type_info [2]); + return NULL; } +#endif /* !DISABLE_JIT */ + +static inline gboolean +mono_class_is_magic_assembly (MonoClass *klass) +{ + if (!klass->image->assembly_name) + return FALSE; + if (!strcmp ("Xamarin.iOS", klass->image->assembly_name)) + return TRUE; + if (!strcmp ("Xamarin.Mac", klass->image->assembly_name)) + return TRUE; + return FALSE; +} + +static inline gboolean +mono_class_is_magic_int (MonoClass *klass) +{ + static MonoClass *magic_nint_class; + static MonoClass *magic_nuint_class; + + if (klass == magic_nint_class) + return TRUE; + + if (klass == magic_nuint_class) + return TRUE; + + if (magic_nint_class && magic_nuint_class) + return FALSE; + + if (!mono_class_is_magic_assembly (klass)) + return FALSE; + + if (strcmp ("System", klass->name_space) != 0) + return FALSE; + + if (strcmp ("nint", klass->name) == 0) { + magic_nint_class = klass; + return TRUE; + } + + if (strcmp ("nuint", klass->name) == 0){ + magic_nuint_class = klass; + return TRUE; + } + return FALSE; +} + +static inline gboolean +mono_class_is_magic_float (MonoClass *klass) +{ + static MonoClass *magic_nfloat_class; + + if (klass == magic_nfloat_class) + return TRUE; + + if (magic_nfloat_class) + return FALSE; + + if (!mono_class_is_magic_assembly (klass)) + return FALSE; + + if (strcmp ("System", klass->name_space) != 0) + return FALSE; + + if (strcmp ("nfloat", klass->name) == 0) { + magic_nfloat_class = klass; + return TRUE; + } + return FALSE; +} + +static gboolean +is_int_type (MonoType *t) +{ + if (t->type != MONO_TYPE_I4 && t->type != MONO_TYPE_I8 && t->type != MONO_TYPE_U4 && t->type != MONO_TYPE_U8 && !mono_class_is_magic_int (mono_class_from_mono_type (t))) + return FALSE; + return TRUE; +} + +static gboolean +is_float_type (MonoType *t) +{ + if (t->type != MONO_TYPE_R4 && t->type != MONO_TYPE_R8 && !mono_class_is_magic_float (mono_class_from_mono_type (t))) + return FALSE; + return TRUE; +} + +MonoType* +mini_native_type_replace_type (MonoType *type) +{ + MonoClass *klass; + + if (type->type != MONO_TYPE_VALUETYPE) + return type; + klass = type->data.klass; + + if (mono_class_is_magic_int (klass)) + return type->byref ? &mono_defaults.int_class->this_arg : &mono_defaults.int_class->byval_arg; + if (mono_class_is_magic_float (klass)) +#if SIZEOF_VOID_P == 8 + return type->byref ? &mono_defaults.double_class->this_arg : &mono_defaults.double_class->byval_arg; +#else + return type->byref ? &mono_defaults.single_class->this_arg : &mono_defaults.single_class->byval_arg; #endif + return type; +} diff --git a/mono/mini/mini-ops.h b/mono/mini/mini-ops.h index 7e1e72ce497..ad48c07158e 100644 --- a/mono/mini/mini-ops.h +++ b/mono/mini/mini-ops.h @@ -2,6 +2,7 @@ * Copyright 2003 Ximian, Inc * Copyright 2003-2011 Novell Inc * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ MINI_OP(OP_LOAD, "load", NONE, NONE, NONE) MINI_OP(OP_LDADDR, "ldaddr", IREG, NONE, NONE) diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c index 63198d79083..7be84488f58 100644 --- a/mono/mini/mini-posix.c +++ b/mono/mini/mini-posix.c @@ -9,6 +9,7 @@ * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) * * See LICENSE for licensing information. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index ba0aad7dce3..06238b4d688 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -1,3 +1,4 @@ + /* * mini-runtime.c: Runtime code for the JIT * @@ -8,6 +9,7 @@ * Copyright 2002-2003 Ximian, Inc. * Copyright 2003-2010 Novell, Inc. * Copyright 2011-2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -2390,7 +2392,7 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com if (!info->dyn_call_info) { if (mono_llvm_only) { -#ifndef ENABLE_GSHAREDVT +#ifndef MONO_ARCH_GSHAREDVT_SUPPORTED g_assert_not_reached (); #endif info->gsharedvt_invoke = TRUE; diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index 346ef6d9221..c464a0033a7 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -2,6 +2,7 @@ * (C) 2003 Ximian, Inc. * (C) 2003-2011 Novell, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/mini-windows.c b/mono/mini/mini-windows.c index 41f12051f90..621a7a5fc31 100644 --- a/mono/mini/mini-windows.c +++ b/mono/mini/mini-windows.c @@ -8,6 +8,7 @@ * Copyright 2003-2008 Ximian, Inc. * * See LICENSE for licensing information. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/mini-x86-gsharedvt.c b/mono/mini/mini-x86-gsharedvt.c new file mode 100644 index 00000000000..130d48e7f56 --- /dev/null +++ b/mono/mini/mini-x86-gsharedvt.c @@ -0,0 +1,210 @@ +/* + * mini-x86-gsharedvt.c: gsharedvt support code for x86 + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include "mini.h" + +#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +/* + * GSHAREDVT + */ + +gboolean +mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig) +{ + /* + if (sig->ret && is_variable_size (sig->ret)) + return FALSE; + */ + return TRUE; +} + +/* + * mono_arch_get_gsharedvt_call_info: + * + * Compute calling convention information for marshalling a call between NORMAL_SIG and GSHAREDVT_SIG. + * If GSHAREDVT_IN is TRUE, then the caller calls using the signature NORMAL_SIG but the call is received by + * a method with signature GSHAREDVT_SIG, otherwise its the other way around. + */ +gpointer +mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) +{ + GSharedVtCallInfo *info; + CallInfo *caller_cinfo, *callee_cinfo; + MonoMethodSignature *caller_sig, *callee_sig; + int i, j; + gboolean var_ret = FALSE; + CallInfo *cinfo, *gcinfo; + MonoMethodSignature *sig, *gsig; + GPtrArray *map; + + if (gsharedvt_in) { + caller_sig = normal_sig; + callee_sig = gsharedvt_sig; + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + } else { + callee_sig = normal_sig; + callee_cinfo = mono_arch_get_call_info (NULL, callee_sig); + caller_sig = gsharedvt_sig; + caller_cinfo = mono_arch_get_call_info (NULL, caller_sig); + } + + /* + * If GSHAREDVT_IN is true, this means we are transitioning from normal to gsharedvt code. The caller uses the + * normal call signature, while the callee uses the gsharedvt signature. + * If GSHAREDVT_IN is false, its the other way around. + */ + + /* sig/cinfo describes the normal call, while gsig/gcinfo describes the gsharedvt call */ + if (gsharedvt_in) { + sig = caller_sig; + gsig = callee_sig; + cinfo = caller_cinfo; + gcinfo = callee_cinfo; + } else { + sig = callee_sig; + gsig = caller_sig; + cinfo = callee_cinfo; + gcinfo = caller_cinfo; + } + + if (gcinfo->vtype_retaddr && gsig->ret && mini_is_gsharedvt_type (gsig->ret)) { + /* + * The return type is gsharedvt + */ + var_ret = TRUE; + } + + /* + * The stack looks like this: + * + * + * + * + * We have to map the stack slots in to the stack slots in . + */ + map = g_ptr_array_new (); + + if (cinfo->vtype_retaddr) { + /* + * Map ret arg. + * This handles the case when the method returns a normal vtype, and when it returns a type arg, and its instantiated + * with a vtype. + */ + g_ptr_array_add (map, GUINT_TO_POINTER (caller_cinfo->vret_arg_offset / sizeof (gpointer))); + g_ptr_array_add (map, GUINT_TO_POINTER (callee_cinfo->vret_arg_offset / sizeof (gpointer))); + } + + for (i = 0; i < cinfo->nargs; ++i) { + ArgInfo *ainfo = &caller_cinfo->args [i]; + ArgInfo *ainfo2 = &callee_cinfo->args [i]; + int nslots; + + switch (ainfo->storage) { + case ArgGSharedVt: + if (ainfo2->storage == ArgOnStack) { + nslots = callee_cinfo->args [i].nslots; + if (!nslots) + nslots = 1; + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo->offset / sizeof (gpointer)) + (1 << 16) + (nslots << 18))); + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo2->offset / sizeof (gpointer)))); + } else { + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo->offset / sizeof (gpointer)))); + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo2->offset / sizeof (gpointer)))); + } + break; + default: + if (ainfo2->storage == ArgOnStack) { + nslots = cinfo->args [i].nslots; + if (!nslots) + nslots = 1; + for (j = 0; j < nslots; ++j) { + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo->offset / sizeof (gpointer)) + j)); + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo2->offset / sizeof (gpointer)) + j)); + } + } else { + g_assert (ainfo2->storage == ArgGSharedVt); + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo->offset / sizeof (gpointer)) + (2 << 16))); + g_ptr_array_add (map, GUINT_TO_POINTER ((ainfo2->offset / sizeof (gpointer)))); + } + break; + } + } + + info = mono_domain_alloc0 (mono_domain_get (), sizeof (GSharedVtCallInfo) + (map->len * sizeof (int))); + info->addr = addr; + info->stack_usage = callee_cinfo->stack_usage; + info->ret_marshal = GSHAREDVT_RET_NONE; + info->gsharedvt_in = gsharedvt_in ? 1 : 0; + info->vret_slot = -1; + info->calli = calli ? 1 : 0; + if (var_ret) + info->vret_arg_slot = gcinfo->vret_arg_offset / sizeof (gpointer); + else + info->vret_arg_slot = -1; + info->vcall_offset = vcall_offset; + info->map_count = map->len / 2; + for (i = 0; i < map->len; ++i) + info->map [i] = GPOINTER_TO_UINT (g_ptr_array_index (map, i)); + g_ptr_array_free (map, TRUE); + + /* Compute return value marshalling */ + if (var_ret) { + switch (cinfo->ret.storage) { + case ArgInIReg: + if (gsharedvt_in && !sig->ret->byref && sig->ret->type == MONO_TYPE_I1) + info->ret_marshal = GSHAREDVT_RET_I1; + else if (gsharedvt_in && !sig->ret->byref && (sig->ret->type == MONO_TYPE_U1 || sig->ret->type == MONO_TYPE_BOOLEAN)) + info->ret_marshal = GSHAREDVT_RET_U1; + else if (gsharedvt_in && !sig->ret->byref && sig->ret->type == MONO_TYPE_I2) + info->ret_marshal = GSHAREDVT_RET_I2; + else if (gsharedvt_in && !sig->ret->byref && (sig->ret->type == MONO_TYPE_U2 || sig->ret->type == MONO_TYPE_CHAR)) + info->ret_marshal = GSHAREDVT_RET_U2; + else if (cinfo->ret.is_pair) + info->ret_marshal = GSHAREDVT_RET_IREGS; + else + info->ret_marshal = GSHAREDVT_RET_IREG; + break; + case ArgOnDoubleFpStack: + info->ret_marshal = GSHAREDVT_RET_DOUBLE_FPSTACK; + break; + case ArgOnFloatFpStack: + info->ret_marshal = GSHAREDVT_RET_FLOAT_FPSTACK; + break; + case ArgOnStack: + /* The caller passes in a vtype ret arg as well */ + g_assert (gcinfo->vtype_retaddr); + /* Just have to pop the arg, as done by normal methods in their epilog */ + info->ret_marshal = GSHAREDVT_RET_STACK_POP; + break; + default: + g_assert_not_reached (); + } + } else if (gsharedvt_in && cinfo->vtype_retaddr) { + info->ret_marshal = GSHAREDVT_RET_STACK_POP; + } + + if (gsharedvt_in && var_ret && !caller_cinfo->vtype_retaddr) { + /* Allocate stack space for the return value */ + info->vret_slot = info->stack_usage / sizeof (gpointer); + // FIXME: + info->stack_usage += sizeof (gpointer) * 3; + } + + info->stack_usage = ALIGN_TO (info->stack_usage, MONO_ARCH_FRAME_ALIGNMENT); + + g_free (caller_cinfo); + g_free (callee_cinfo); + + return info; +} +#endif diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index 1ef8d4614dd..5e9204611d7 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -9,6 +9,7 @@ * Copyright 2003 Ximian, Inc. * Copyright 2003-2011 Novell Inc. * Copyright 2011 Xamarin Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" #include @@ -179,49 +180,6 @@ mono_x86_patch (unsigned char* code, gpointer target) x86_patch (code, (unsigned char*)target); } -typedef enum { - ArgInIReg, - ArgInFloatSSEReg, - ArgInDoubleSSEReg, - ArgOnStack, - ArgValuetypeInReg, - ArgOnFloatFpStack, - ArgOnDoubleFpStack, - /* gsharedvt argument passed by addr */ - ArgGSharedVt, - ArgNone -} ArgStorage; - -typedef struct { - gint16 offset; - gint8 reg; - ArgStorage storage; - int nslots; - gboolean is_pair; - - /* Only if storage == ArgValuetypeInReg */ - ArgStorage pair_storage [2]; - gint8 pair_regs [2]; -} ArgInfo; - -typedef struct { - int nargs; - guint32 stack_usage; - guint32 reg_usage; - guint32 freg_usage; - gboolean need_stack_align; - guint32 stack_align_amount; - gboolean vtype_retaddr; - /* The index of the vret arg in the argument list */ - int vret_arg_index; - int vret_arg_offset; - /* Argument space popped by the callee */ - int callee_stack_pop; - ArgInfo ret; - ArgInfo sig_cookie; - ArgInfo args [1]; -} CallInfo; - #define FLOAT_PARAM_REGS 0 static const guint32 thiscall_param_regs [] = { X86_ECX, X86_NREG }; @@ -761,7 +719,7 @@ mono_arch_init (void) mono_aot_register_jit_icall ("mono_x86_throw_exception", mono_x86_throw_exception); mono_aot_register_jit_icall ("mono_x86_throw_corlib_exception", mono_x86_throw_corlib_exception); -#if defined(ENABLE_GSHAREDVT) +#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) mono_aot_register_jit_icall ("mono_x86_start_gsharedvt_call", mono_x86_start_gsharedvt_call); #endif } @@ -6806,8 +6764,8 @@ mono_arch_opcode_supported (int opcode) } } -#if defined(ENABLE_GSHAREDVT) - -#include "../../../mono-extensions/mono/mini/mini-x86-gsharedvt.c" - -#endif /* !MONOTOUCH */ +CallInfo* +mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) +{ + return get_call_info (mp, sig); +} diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h index 212f844af4c..969b679f29b 100644 --- a/mono/mini/mini-x86.h +++ b/mono/mini/mini-x86.h @@ -300,6 +300,49 @@ typedef struct { int map [MONO_ZERO_LEN_ARRAY]; } GSharedVtCallInfo; +typedef enum { + ArgInIReg, + ArgInFloatSSEReg, + ArgInDoubleSSEReg, + ArgOnStack, + ArgValuetypeInReg, + ArgOnFloatFpStack, + ArgOnDoubleFpStack, + /* gsharedvt argument passed by addr */ + ArgGSharedVt, + ArgNone +} ArgStorage; + +typedef struct { + gint16 offset; + gint8 reg; + ArgStorage storage; + int nslots; + gboolean is_pair; + + /* Only if storage == ArgValuetypeInReg */ + ArgStorage pair_storage [2]; + gint8 pair_regs [2]; +} ArgInfo; + +typedef struct { + int nargs; + guint32 stack_usage; + guint32 reg_usage; + guint32 freg_usage; + gboolean need_stack_align; + guint32 stack_align_amount; + gboolean vtype_retaddr; + /* The index of the vret arg in the argument list */ + int vret_arg_index; + int vret_arg_offset; + /* Argument space popped by the callee */ + int callee_stack_pop; + ArgInfo ret; + ArgInfo sig_cookie; + ArgInfo args [1]; +} CallInfo; + guint8* mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset); @@ -326,5 +369,8 @@ mono_x86_patch (unsigned char* code, gpointer target); gpointer mono_x86_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg); +CallInfo* +mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig); + #endif /* __MONO_MINI_X86_H__ */ diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 046572a3329..7101e69b33c 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -8,6 +8,7 @@ * Copyright 2002-2003 Ximian, Inc. * Copyright 2003-2010 Novell, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 2a1b331f809..23f048881db 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -2,6 +2,7 @@ * Copyright 2002-2003 Ximian Inc * Copyright 2003-2011 Novell Inc * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_MINI_H__ #define __MONO_MINI_H__ @@ -3009,6 +3010,10 @@ mono_method_is_generic_sharable_full (MonoMethod *method, gboolean allow_type_va gboolean mini_class_is_generic_sharable (MonoClass *klass); + +gboolean +mini_generic_inst_is_sharable (MonoGenericInst *inst, gboolean allow_type_vars, gboolean allow_partial); + gboolean mono_is_partially_sharable_inst (MonoGenericInst *inst); @@ -3189,4 +3194,10 @@ gboolean MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal); #define ARCH_VARARG_ICALLS 0 #endif +/* + * Native unwinder integration + */ +void mono_exception_native_unwind (void *ctx, MONO_SIG_HANDLER_INFO_TYPE *info); + + #endif /* __MONO_MINI_H__ */ diff --git a/mono/mini/seq-points.c b/mono/mini/seq-points.c index 434a11f4370..fd9cc01200d 100644 --- a/mono/mini/seq-points.c +++ b/mono/mini/seq-points.c @@ -5,6 +5,7 @@ * Marcos Henrich (marcos.henrich@xamarin.com) * * Copyright 2014 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mini.h" diff --git a/mono/mini/seq-points.h b/mono/mini/seq-points.h index d0e6f5aa157..79915205a2d 100644 --- a/mono/mini/seq-points.h +++ b/mono/mini/seq-points.h @@ -1,5 +1,6 @@ /* * Copyright 2014 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SEQ_POINTS_H__ diff --git a/mono/mini/ssa.c b/mono/mini/ssa.c index a29108872a4..cb100267ef7 100644 --- a/mono/mini/ssa.c +++ b/mono/mini/ssa.c @@ -6,6 +6,7 @@ * * (C) 2003 Ximian, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include diff --git a/mono/mini/trace.c b/mono/mini/trace.c index 765bc111c09..d8e4437b75d 100644 --- a/mono/mini/trace.c +++ b/mono/mini/trace.c @@ -7,6 +7,7 @@ * * (C) 2002 Ximian, Inc. * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/mini/tramp-amd64-gsharedvt.c b/mono/mini/tramp-amd64-gsharedvt.c new file mode 100644 index 00000000000..0b28eebbf69 --- /dev/null +++ b/mono/mini/tramp-amd64-gsharedvt.c @@ -0,0 +1,483 @@ +/* + * tramp-amd64-gsharedvt.c: libcorkscrew-based native unwinder + * + * Authors: + * Zoltan Varga + * Rodrigo Kumpera + * Andi McClure + * + * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mini.h" +#include "mini-amd64.h" +#include "mini-amd64-gsharedvt.h" +#include "debugger-agent.h" + +#if defined (MONO_ARCH_GSHAREDVT_SUPPORTED) + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +#define SRC_REG_SHIFT 0 +#define SRC_REG_MASK 0xFFFF + +#define SRC_DESCRIPTOR_MARSHAL_SHIFT 16 +#define SRC_DESCRIPTOR_MARSHAL_MASK 0x0FF + +#define SLOT_COUNT_SHIFT 24 +#define SLOT_COUNT_MASK 0xFF + +gpointer +mono_amd64_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) +{ + int i; + +#ifdef DEBUG_AMD64_GSHAREDVT + printf ("mono_amd64_start_gsharedvt_call info %p caller %p callee %p ctx %p\n", info, caller, callee, mrgctx_reg); + + for (i = 0; i < PARAM_REGS; ++i) + printf ("\treg [%d] -> %p\n", i, caller [i]); +#endif + + /* Set vtype ret arg */ + if (info->vret_slot != -1) { + DEBUG_AMD64_GSHAREDVT_PRINT ("vret handling\n[%d] < &%d (%p)\n", info->vret_arg_reg, info->vret_slot, &callee [info->vret_slot]); + g_assert (info->vret_slot); + callee [info->vret_arg_reg] = &callee [info->vret_slot]; + } + + for (i = 0; i < info->map_count; ++i) { + int src = info->map [i * 2]; + int dst = info->map [(i * 2) + 1]; + int arg_marshal = (src >> SRC_DESCRIPTOR_MARSHAL_SHIFT) & SRC_DESCRIPTOR_MARSHAL_MASK; + + int source_reg = src & SRC_REG_MASK; + int dest_reg = dst & SRC_REG_MASK; + + DEBUG_AMD64_GSHAREDVT_PRINT ("source %x dest %x marshal %d: ", src, dst, arg_marshal); + switch (arg_marshal) { + case GSHAREDVT_ARG_NONE: + callee [dest_reg] = caller [source_reg]; + DEBUG_AMD64_GSHAREDVT_PRINT ("[%d] <- %d (%p) <- (%p)\n", dest_reg, source_reg, &callee [dest_reg], caller [source_reg]); + break; + case GSHAREDVT_ARG_BYVAL_TO_BYREF: + /* gsharedvt argument passed by addr in reg/stack slot */ + callee [dest_reg] = &caller [source_reg]; + DEBUG_AMD64_GSHAREDVT_PRINT ("[%d] <- &%d (%p) <- (%p)\n", dest_reg, source_reg, &callee [dest_reg], &caller [source_reg]); + break; + case GSHAREDVT_ARG_BYREF_TO_BYVAL: { + int slot_count = (src >> SLOT_COUNT_SHIFT) & SLOT_COUNT_MASK; + int j; + gpointer *addr = caller [source_reg]; + + for (j = 0; j < slot_count; ++j) + callee [dest_reg + j] = addr [j]; + DEBUG_AMD64_GSHAREDVT_PRINT ("[%d] <- [%d] (%d words) (%p) <- (%p)\n", dest_reg, source_reg, slot_count, &callee [dest_reg], &caller [source_reg]); + break; + } + default: + g_error ("cant handle arg marshal %d\n", arg_marshal); + } + } + + //Can't handle for now + if (info->vcall_offset != -1){ + MonoObject *this_obj = caller [0]; + + DEBUG_AMD64_GSHAREDVT_PRINT ("target is a vcall at offset %d\n", info->vcall_offset / 8); + if (G_UNLIKELY (!this_obj)) + return NULL; + if (info->vcall_offset == MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET) + /* delegate invoke */ + return ((MonoDelegate*)this_obj)->invoke_impl; + else + return *(gpointer*)((char*)this_obj->vtable + info->vcall_offset); + } else if (info->calli) { + /* The address to call is passed in the mrgctx reg */ + return mrgctx_reg; + } else { + DEBUG_AMD64_GSHAREDVT_PRINT ("target is %p\n", info->addr); + return info->addr; + } +} + +#ifndef DISABLE_JIT + +// Compiler support + +/* + * mono_arch_get_gsharedvt_arg_trampoline: + * + * See tramp-x86.c for documentation. + */ +gpointer +mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) +{ + guint8 *code, *start; + int buf_len; + + buf_len = 32; + + start = code = mono_domain_code_reserve (domain, buf_len); + + amd64_mov_reg_imm (code, AMD64_RAX, arg); + amd64_jump_code (code, addr); + g_assert ((code - start) < buf_len); + + nacl_domain_code_validate (domain, &start, buf_len, &code); + mono_arch_flush_icache (start, code - start); + mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL); + + g_assert (0); + return start; +} + + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf; + int buf_len, cfa_offset; + GSList *unwind_ops = NULL; + MonoJumpInfo *ji = NULL; + int n_arg_regs, n_arg_fregs, framesize, i; + int info_offset, offset, rgctx_arg_reg_offset; + int caller_reg_area_offset, callee_reg_area_offset, callee_stack_area_offset; + guint8 *br_out, *br [64], *br_ret [64]; + int b_ret_index; + int reg_area_size; + + buf_len = 2048; + buf = code = mono_global_codeman_reserve (buf_len); + + /* + * We are being called by an gsharedvt arg trampoline, the info argument is in AMD64_RAX. + */ + n_arg_regs = PARAM_REGS; + n_arg_fregs = FLOAT_PARAM_REGS; + + /* Compute stack frame size and offsets */ + offset = 0; + /* info reg */ + info_offset = offset; + offset += 8; + + /* rgctx reg */ + rgctx_arg_reg_offset = offset; + offset += 8; + + /*callconv in regs */ + caller_reg_area_offset = offset; + reg_area_size = ALIGN_TO ((n_arg_regs + n_arg_fregs) * 8, MONO_ARCH_FRAME_ALIGNMENT); + offset += reg_area_size; + + framesize = offset; + + g_assert (framesize % MONO_ARCH_FRAME_ALIGNMENT == 0); + g_assert (reg_area_size % MONO_ARCH_FRAME_ALIGNMENT == 0); + + /* unwind markers 1/3 */ + cfa_offset = sizeof (gpointer); + mono_add_unwind_op_def_cfa (unwind_ops, code, buf, AMD64_RSP, cfa_offset); + mono_add_unwind_op_offset (unwind_ops, code, buf, AMD64_RIP, -cfa_offset); + + /* save the old frame pointer */ + amd64_push_reg (code, AMD64_RBP); + + /* unwind markers 2/3 */ + cfa_offset += sizeof (gpointer); + mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset); + mono_add_unwind_op_offset (unwind_ops, code, buf, AMD64_RBP, - cfa_offset); + + /* set it as the new frame pointer */ + amd64_mov_reg_reg (code, AMD64_RBP, AMD64_RSP, sizeof(mgreg_t)); + + /* unwind markers 3/3 */ + mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, AMD64_RBP); + + /* setup the frame */ + amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, framesize); + + /* save stuff */ + + /* save info */ + amd64_mov_membase_reg (code, AMD64_RSP, info_offset, AMD64_RAX, sizeof (mgreg_t)); + /* save rgctx */ + amd64_mov_membase_reg (code, AMD64_RSP, rgctx_arg_reg_offset, MONO_ARCH_RGCTX_REG, sizeof (mgreg_t)); + + for (i = 0; i < n_arg_regs; ++i) + amd64_mov_membase_reg (code, AMD64_RSP, caller_reg_area_offset + i * 8, param_regs [i], sizeof (mgreg_t)); + + for (i = 0; i < n_arg_fregs; ++i) + amd64_sse_movsd_membase_reg (code, AMD64_RSP, caller_reg_area_offset + (i + n_arg_regs) * 8, i); + + /* TODO Allocate stack area used to pass arguments to the method */ + + + /* Allocate callee register area just below the caller area so it can be accessed from start_gsharedvt_call using negative offsets */ + /* XXX figure out alignment */ + callee_reg_area_offset = reg_area_size - ((n_arg_regs + n_arg_fregs) * 8); /* Ensure alignment */ + callee_stack_area_offset = callee_reg_area_offset + reg_area_size; + amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, reg_area_size); + + /* Allocate stack area used to pass arguments to the method */ + amd64_mov_reg_membase (code, AMD64_R11, AMD64_RAX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, stack_usage), 4); + amd64_alu_reg_reg (code, X86_SUB, AMD64_RSP, AMD64_R11); + + /* The stack now looks like this: + + + + + + + + + + */ + + /* Call start_gsharedvt_call () */ + /* arg1 == info */ + amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RAX, sizeof(mgreg_t)); + /* arg2 = caller stack area */ + amd64_lea_membase (code, MONO_AMD64_ARG_REG2, AMD64_RBP, -(framesize - caller_reg_area_offset)); + + /* arg3 == callee stack area */ + amd64_lea_membase (code, MONO_AMD64_ARG_REG3, AMD64_RSP, callee_reg_area_offset); + + /* arg4 = mrgctx reg */ + amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG4, MONO_ARCH_RGCTX_REG, sizeof(mgreg_t)); + + if (aot) { + code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_amd64_start_gsharedvt_call"); + amd64_call_reg (code, AMD64_R11); + } else { + g_error ("no aot"); + } + + /* Method to call is now on RAX. Restore regs and jump */ + amd64_mov_reg_reg (code, AMD64_R11, AMD64_RAX, sizeof(mgreg_t)); + + for (i = 0; i < n_arg_regs; ++i) + amd64_mov_reg_membase (code, param_regs [i], AMD64_RSP, callee_reg_area_offset + i * 8, sizeof (mgreg_t)); + + for (i = 0; i < n_arg_fregs; ++i) + amd64_sse_movsd_reg_membase (code, i, AMD64_RSP, callee_reg_area_offset + (i + n_arg_regs) * 8); + + //load rgctx + amd64_mov_reg_membase (code, MONO_ARCH_RGCTX_REG, AMD64_RBP, -(framesize - rgctx_arg_reg_offset), sizeof (mgreg_t)); + + /* Clear callee reg area */ + amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, reg_area_size); + + /* Call the thing */ + amd64_call_reg (code, AMD64_R11); + + /* Marshal return value. Available registers: R10 and R11 */ + /* Load info struct */ + amd64_mov_reg_membase (code, AMD64_R10, AMD64_RBP, -(framesize - info_offset), sizeof (mgreg_t)); + + /* Branch to the in/out handling code */ + amd64_alu_membase_imm_size (code, X86_CMP, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, gsharedvt_in), 1, 4); + + b_ret_index = 0; + br_out = code; + x86_branch32 (code, X86_CC_NE, 0, TRUE); + + /* + * IN CASE + */ + + /* Load vret_slot */ + amd64_mov_reg_membase (code, AMD64_RDI, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_slot), 4); + amd64_alu_reg_imm (code, X86_SUB, AMD64_RDI, n_arg_regs + n_arg_fregs); + amd64_shift_reg_imm (code, X86_SHL, AMD64_RDI, 3); + + /* vret address is RBP - (framesize - caller_reg_area_offset) */ + amd64_mov_reg_reg (code, AMD64_R11, AMD64_RSP, sizeof(mgreg_t)); + amd64_alu_reg_reg (code, X86_ADD, AMD64_R11, AMD64_RDI); + + /* Load ret marshal type */ + /* Load vret address in R11 */ + amd64_mov_reg_membase (code, AMD64_R10, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal), 4); + + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + amd64_alu_reg_imm (code, X86_CMP, AMD64_R10, i); + br [i] = code; + amd64_branch8 (code, X86_CC_EQ, 0, TRUE); + } + x86_breakpoint (code); /* unhandled case */ + + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + mono_amd64_patch (br [i], code); + switch (i) { + case GSHAREDVT_RET_NONE: + break; + case GSHAREDVT_RET_I1: + amd64_widen_membase (code, AMD64_RAX, AMD64_R11, 0, TRUE, FALSE); + break; + case GSHAREDVT_RET_U1: + amd64_widen_membase (code, AMD64_RAX, AMD64_R11, 0, FALSE, FALSE); + break; + case GSHAREDVT_RET_I2: + amd64_widen_membase (code, AMD64_RAX, AMD64_R11, 0, TRUE, TRUE); + break; + case GSHAREDVT_RET_U2: + amd64_widen_membase (code, AMD64_RAX, AMD64_R11, 0, FALSE, TRUE); + break; + case GSHAREDVT_RET_I4: // CORRECT + case GSHAREDVT_RET_U4: // THIS IS INCORRECT. WHY IS IT NOT FAILING? + amd64_movsxd_reg_membase (code, AMD64_RAX, AMD64_R11, 0); + break; + case GSHAREDVT_RET_I8: + amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, 0, 8); + break; + case GSHAREDVT_RET_IREGS_1: + amd64_mov_reg_membase (code, return_regs [i - GSHAREDVT_RET_IREGS_1], AMD64_R11, 0, 8); + break; + case GSHAREDVT_RET_R8: + amd64_sse_movsd_reg_membase (code, AMD64_XMM0, AMD64_R11, 0); + break; + default: + x86_breakpoint (code); /* can't handle specific case */ + } + + br_ret [b_ret_index ++] = code; + x86_jump32 (code, 0); + } + + /* + * OUT CASE + */ + mono_amd64_patch (br_out, code); + + /* + Address to write return to is in the original value of the register specified by vret_arg_reg. + This will be either RSI or RDI depending on whether this is a static call. + Its location: + We alloc 'framesize' bytes below RBP to save regs, info and rgctx. RSP = RBP - framesize + We store rdi at RSP + caller_reg_area_offset + slot_index_of (register) * 8. + + address: RBP - framesize + caller_reg_area_offset + 8*slot + */ + + int caller_vret_offset = caller_reg_area_offset - framesize; + + /* Load vret address in R11 */ + /* Position to return to is passed as a hidden argument. Load 'vret_arg_slot' to find it */ + amd64_movsxd_reg_membase (code, AMD64_R11, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_arg_reg)); + + // In the GSHAREDVT_RET_NONE case, vret_arg_slot is -1. In this case, skip marshalling. + amd64_alu_reg_imm (code, X86_CMP, AMD64_R11, 0); + br_ret [b_ret_index ++] = code; + amd64_branch32 (code, X86_CC_LT, 0, TRUE); + + /* Compute ret area address in the caller frame, *( ((gpointer *)RBP) [R11+2] ) */ + amd64_shift_reg_imm (code, X86_SHL, AMD64_R11, 3); + amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, caller_vret_offset); + amd64_alu_reg_reg (code, X86_ADD, AMD64_R11, AMD64_RBP); + amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0, sizeof (gpointer)); + + /* Load ret marshal type in R10 */ + amd64_mov_reg_membase (code, AMD64_R10, AMD64_R10, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal), 4); + + // Switch table for ret_marshal value + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + amd64_alu_reg_imm (code, X86_CMP, AMD64_R10, i); + br [i] = code; + amd64_branch8 (code, X86_CC_EQ, 0, TRUE); + } + x86_breakpoint (code); /* unhandled case */ + + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + mono_amd64_patch (br [i], code); + switch (i) { + case GSHAREDVT_RET_NONE: + break; + case GSHAREDVT_RET_IREGS_1: + amd64_mov_membase_reg (code, AMD64_R11, 0, return_regs [i - GSHAREDVT_RET_IREGS_1], 8); + break; + case GSHAREDVT_RET_R8: + amd64_sse_movsd_membase_reg (code, AMD64_R11, 0, AMD64_XMM0); + break; + default: + x86_breakpoint (code); /* can't handle specific case */ + } + + br_ret [b_ret_index ++] = code; + x86_jump32 (code, 0); + } + + /* exit path */ + for (i = 0; i < b_ret_index; ++i) + mono_amd64_patch (br_ret [i], code); + + /* Exit code path */ + amd64_leave (code); + amd64_ret (code); + + g_assert ((code - buf) < buf_len); + + if (info) + *info = mono_tramp_info_create ("gsharedvt_trampoline", buf, code - buf, ji, unwind_ops); + + mono_arch_flush_icache (buf, code - buf); + return buf; +} + +#else + +gpointer +mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +#endif + +#else + +gpointer +mono_amd64_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + *info = NULL; + return NULL; +} + +#endif \ No newline at end of file diff --git a/mono/mini/tramp-amd64.c b/mono/mini/tramp-amd64.c index a5ba7000e40..05fb2cecac2 100644 --- a/mono/mini/tramp-amd64.c +++ b/mono/mini/tramp-amd64.c @@ -8,6 +8,7 @@ * (C) 2001 Ximian, Inc. * Copyright 2003-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -1009,32 +1010,3 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo return buf; } - -#if defined(ENABLE_GSHAREDVT) && defined(MONO_ARCH_GSHAREDVT_SUPPORTED) - -#include "../../../mono-extensions/mono/mini/tramp-amd64-gsharedvt.c" - -#else - -gpointer -mono_amd64_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) -{ - g_assert_not_reached (); - return NULL; -} - -gpointer -mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) -{ - g_assert_not_reached (); - return NULL; -} - -gpointer -mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) -{ - *info = NULL; - return NULL; -} - -#endif /* !ENABLE_GSHAREDVT */ diff --git a/mono/mini/tramp-arm-gsharedvt.c b/mono/mini/tramp-arm-gsharedvt.c new file mode 100644 index 00000000000..f84c5424a14 --- /dev/null +++ b/mono/mini/tramp-arm-gsharedvt.c @@ -0,0 +1,439 @@ +/* + * tramp-arm-gsharedvt.c: gsharedvt support code for arm + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mini.h" +#include "mini-arm.h" + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + + +#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED + +static inline guint8* +emit_bx (guint8* code, int reg) +{ + if (mono_arm_thumb_supported ()) + ARM_BX (code, reg); + else + ARM_MOV_REG_REG (code, ARMREG_PC, reg); + return code; +} + + +gpointer +mono_arm_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) +{ + int i; + + /* + * The caller/callee regs are mapped to slot 0..3, stack slot 0 is mapped to slot 4, etc. + */ + + /* Set vtype ret arg */ + if (info->vret_slot != -1) { + callee [info->vret_arg_reg] = &callee [info->vret_slot]; + } + + for (i = 0; i < info->map_count; ++i) { + int src = info->map [i * 2]; + int dst = info->map [(i * 2) + 1]; + int arg_marshal = (src >> 16) & 0xff; + + switch (arg_marshal) { + case GSHAREDVT_ARG_NONE: + callee [dst] = caller [src]; + break; + case GSHAREDVT_ARG_BYVAL_TO_BYREF: + /* gsharedvt argument passed by addr in reg/stack slot */ + src = src & 0xffff; + callee [dst] = caller + src; + break; + case GSHAREDVT_ARG_BYREF_TO_BYVAL: { + /* gsharedvt argument passed by value */ + int nslots = (src >> 4) & 0xff; + int src_slot = src & 0xf; + int j; + gpointer *addr = caller [src_slot]; + + for (j = 0; j < nslots; ++j) + callee [dst + j] = addr [j]; + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYVAL_I1: { + int src_slot = src & 0xf; + gpointer *addr = caller [src_slot]; + + callee [dst] = GINT_TO_POINTER ((int)*(gint8*)addr); + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYVAL_I2: { + int src_slot = src & 0xf; + gpointer *addr = caller [src_slot]; + + callee [dst] = GINT_TO_POINTER ((int)*(gint16*)addr); + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYVAL_U1: { + int src_slot = src & 0xf; + gpointer *addr = caller [src_slot]; + + callee [dst] = GUINT_TO_POINTER ((guint)*(guint8*)addr); + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYVAL_U2: { + int src_slot = src & 0xf; + gpointer *addr = caller [src_slot]; + + callee [dst] = GUINT_TO_POINTER ((guint)*(guint16*)addr); + break; + } + default: + g_assert_not_reached (); + break; + } + } + + if (info->vcall_offset != -1) { + MonoObject *this_obj = caller [0]; + + if (G_UNLIKELY (!this_obj)) + return NULL; + if (info->vcall_offset == MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET) + /* delegate invoke */ + return ((MonoDelegate*)this_obj)->invoke_impl; + else + return *(gpointer*)((char*)this_obj->vtable + info->vcall_offset); + } else if (info->calli) { + /* The address to call is passed in the mrgctx reg */ + return mrgctx_reg; + } else { + return info->addr; + } +} + +#ifndef DISABLE_JIT + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf; + int buf_len, cfa_offset; + GSList *unwind_ops = NULL; + MonoJumpInfo *ji = NULL; + guint8 *br_out, *br [16], *br_ret [16]; + int i, arg_reg, npushed, info_offset, mrgctx_offset, caller_reg_area_offset, callee_reg_area_offset; + int lr_offset, fp, br_ret_index, args_size; + + buf_len = 512; + buf = code = mono_global_codeman_reserve (buf_len); + + arg_reg = ARMREG_R0; + /* Registers pushed by the arg trampoline */ + npushed = 4; + + // ios abi compatible frame + fp = ARMREG_R7; + cfa_offset = npushed * sizeof (gpointer); + mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset); + ARM_PUSH (code, (1 << fp) | (1 << ARMREG_LR)); + cfa_offset += 2 * sizeof (gpointer); + mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset); + mono_add_unwind_op_offset (unwind_ops, code, buf, fp, (- cfa_offset)); + mono_add_unwind_op_offset (unwind_ops, code, buf, ARMREG_LR, ((- cfa_offset) + 4)); + ARM_MOV_REG_REG (code, fp, ARMREG_SP); + mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, fp); + /* Allocate stack frame */ + ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 32); + info_offset = -4; + mrgctx_offset = -8; + callee_reg_area_offset = - (6 * 4); + caller_reg_area_offset = cfa_offset - (npushed * sizeof (gpointer)); + lr_offset = 4; + /* Save info struct which is in r0 */ + ARM_STR_IMM (code, arg_reg, fp, info_offset); + /* Save rgctx reg */ + ARM_STR_IMM (code, MONO_ARCH_RGCTX_REG, fp, mrgctx_offset); + /* Allocate callee area */ + ARM_LDR_IMM (code, ARMREG_IP, arg_reg, MONO_STRUCT_OFFSET (GSharedVtCallInfo, stack_usage)); + ARM_SUB_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_IP); + /* Allocate callee register area just below the callee area so it can be accessed from start_gsharedvt_call using negative offsets */ + ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 4 * sizeof (gpointer)); + + /* + * The stack now looks like this: + * + * + * <- fp + * + * <- sp + */ + g_assert (mono_arm_thumb_supported ()); + + /* Call start_gsharedvt_call () */ + /* 4 arguments, needs 0 stack slot, need to clean it up after the call */ + args_size = 0 * sizeof (gpointer); + ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, args_size); + /* arg1 == info */ + ARM_LDR_IMM (code, ARMREG_R0, fp, info_offset); + /* arg2 == caller stack area */ + ARM_ADD_REG_IMM8 (code, ARMREG_R1, fp, cfa_offset - 4 * sizeof (gpointer)); + /* arg3 == callee stack area */ + ARM_ADD_REG_IMM8 (code, ARMREG_R2, ARMREG_SP, args_size); + /* arg4 == mrgctx reg */ + ARM_LDR_IMM (code, ARMREG_R3, fp, mrgctx_offset); + /* Make the call */ + if (aot) { + ji = mono_patch_info_list_prepend (ji, code - buf, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_arm_start_gsharedvt_call"); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0); + ARM_B (code, 0); + *(gpointer*)code = NULL; + code += 4; + ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_PC, ARMREG_IP); + } else { + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0); + ARM_B (code, 0); + *(gpointer*)code = mono_arm_start_gsharedvt_call; + code += 4; + } + ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_PC); + code = emit_bx (code, ARMREG_IP); + /* Clean up stack */ + ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, args_size); + + /* Make the real method call */ + /* R0 contains the addr to call */ + ARM_MOV_REG_REG (code, ARMREG_IP, ARMREG_R0); + /* Load argument registers */ + ARM_LDM (code, ARMREG_SP, (1 << ARMREG_R0) | (1 << ARMREG_R1) | (1 << ARMREG_R2) | (1 << ARMREG_R3)); + /* Pop callee register area */ + ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 4 * sizeof (gpointer)); + /* Load rgctx */ + ARM_LDR_IMM (code, MONO_ARCH_RGCTX_REG, fp, mrgctx_offset); + /* Make the call */ +#if 0 + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, addr)); +#endif + /* mono_arch_find_imt_method () depends on this */ + ARM_ADD_REG_IMM8 (code, ARMREG_LR, ARMREG_PC, 4); + ARM_BX (code, ARMREG_IP); + *((gpointer*)code) = NULL; + code += 4; + + br_ret_index = 0; + + /* Branch between IN/OUT cases */ + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, gsharedvt_in)); + + ARM_CMP_REG_IMM8 (code, ARMREG_IP, 1); + br_out = code; + ARM_B_COND (code, ARMCOND_NE, 0); + + /* IN CASE */ + + /* LR == return marshalling type */ + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal)); + + /* Continue if no marshalling required */ + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_NONE); + br_ret [br_ret_index ++] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + + /* Compute vret area address in LR */ + ARM_LDR_IMM (code, ARMREG_LR, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_LR, ARMREG_LR, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_slot)); + /* The slot value is off by 4 */ + ARM_SUB_REG_IMM8 (code, ARMREG_LR, ARMREG_LR, 4); + ARM_SHL_IMM (code, ARMREG_LR, ARMREG_LR, 2); + ARM_ADD_REG_REG (code, ARMREG_LR, ARMREG_LR, ARMREG_SP); + + /* Branch to specific marshalling code */ + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_IREG); + br [0] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_IREGS); + br [1] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_I1); + br [2] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_U1); + br [3] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_I2); + br [4] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_U2); + br [5] = code; + ARM_B_COND (code, ARMCOND_EQ, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + + /* IN IREG case */ + arm_patch (br [0], code); + ARM_LDR_IMM (code, ARMREG_R0, ARMREG_LR, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + /* IN IREGS case */ + arm_patch (br [1], code); + ARM_LDR_IMM (code, ARMREG_R0, ARMREG_LR, 0); + ARM_LDR_IMM (code, ARMREG_R1, ARMREG_LR, 4); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + /* I1 case */ + arm_patch (br [2], code); + ARM_LDRSB_IMM (code, ARMREG_R0, ARMREG_LR, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + /* U1 case */ + arm_patch (br [3], code); + ARM_LDRB_IMM (code, ARMREG_R0, ARMREG_LR, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + /* I2 case */ + arm_patch (br [4], code); + ARM_LDRSH_IMM (code, ARMREG_R0, ARMREG_LR, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + /* U2 case */ + arm_patch (br [5], code); + ARM_LDRH_IMM (code, ARMREG_R0, ARMREG_LR, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + + /* OUT CASE */ + arm_patch (br_out, code); + + /* Marshal return value */ + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal)); + + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_IREGS); + br [0] = code; + ARM_B_COND (code, ARMCOND_NE, 0); + + /* OUT IREGS case */ + /* Load vtype ret addr from the caller arg regs */ + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_arg_reg)); + ARM_SHL_IMM (code, ARMREG_IP, ARMREG_IP, 2); + ARM_ADD_REG_REG (code, ARMREG_IP, ARMREG_IP, fp); + ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_IP, caller_reg_area_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, 0); + /* Save both registers for simplicity */ + ARM_STR_IMM (code, ARMREG_R0, ARMREG_IP, 0); + ARM_STR_IMM (code, ARMREG_R1, ARMREG_IP, 4); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + arm_patch (br [0], code); + + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_IREG); + br [0] = code; + ARM_B_COND (code, ARMCOND_NE, 0); + + /* OUT IREG case */ + /* Load vtype ret addr from the caller arg regs */ + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_arg_reg)); + ARM_SHL_IMM (code, ARMREG_IP, ARMREG_IP, 2); + ARM_ADD_REG_REG (code, ARMREG_IP, ARMREG_IP, fp); + ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_IP, caller_reg_area_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, 0); + /* Save the return value to the buffer pointed to by the vret addr */ + ARM_STR_IMM (code, ARMREG_R0, ARMREG_IP, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + arm_patch (br [0], code); + + ARM_CMP_REG_IMM8 (code, ARMREG_IP, GSHAREDVT_RET_U1); + br [0] = code; + ARM_B_COND (code, ARMCOND_NE, 0); + + /* OUT U1 case */ + /* Load vtype ret addr from the caller arg regs */ + ARM_LDR_IMM (code, ARMREG_IP, fp, info_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_arg_reg)); + ARM_SHL_IMM (code, ARMREG_IP, ARMREG_IP, 2); + ARM_ADD_REG_REG (code, ARMREG_IP, ARMREG_IP, fp); + ARM_ADD_REG_IMM8 (code, ARMREG_IP, ARMREG_IP, caller_reg_area_offset); + ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, 0); + /* Save the return value to the buffer pointed to by the vret addr */ + ARM_STRB_IMM (code, ARMREG_R0, ARMREG_IP, 0); + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + arm_patch (br [0], code); + + /* OUT other cases */ + br_ret [br_ret_index ++] = code; + ARM_B (code, 0); + + for (i = 0; i < br_ret_index; ++i) + arm_patch (br_ret [i], code); + + /* Normal return */ + /* Restore registers + stack */ + ARM_MOV_REG_REG (code, ARMREG_SP, fp); + ARM_LDM (code, fp, (1 << fp) | (1 << ARMREG_LR)); + ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, cfa_offset); + /* Return */ + ARM_BX (code, ARMREG_LR); + + g_assert ((code - buf) < buf_len); + + if (info) + *info = mono_tramp_info_create ("gsharedvt_trampoline", buf, code - buf, ji, unwind_ops); + + mono_arch_flush_icache (buf, code - buf); + return buf; +} + +#else + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +#endif + + +#else + + +gpointer +mono_arm_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + *info = NULL; + return NULL; +} + + +#endif diff --git a/mono/mini/tramp-arm.c b/mono/mini/tramp-arm.c index 1a83343d735..5ff7bbfdfc8 100644 --- a/mono/mini/tramp-arm.c +++ b/mono/mini/tramp-arm.c @@ -7,6 +7,7 @@ * (C) 2001-2003 Ximian, Inc. * Copyright 2003-2011 Novell Inc * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -1134,25 +1135,3 @@ mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpoint } #endif - -#if defined(ENABLE_GSHAREDVT) - -#include "../../../mono-extensions/mono/mini/tramp-arm-gsharedvt.c" - -#else - -gpointer -mono_arm_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) -{ - g_assert_not_reached (); - return NULL; -} - -gpointer -mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) -{ - *info = NULL; - return NULL; -} - -#endif /* !MONOTOUCH */ diff --git a/mono/mini/tramp-arm64-gsharedvt.c b/mono/mini/tramp-arm64-gsharedvt.c new file mode 100644 index 00000000000..d93b6520da3 --- /dev/null +++ b/mono/mini/tramp-arm64-gsharedvt.c @@ -0,0 +1,574 @@ +/* + * tramp-arm64-gsharedvt.c: gsharedvt support code for arm64 + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include + +#include "mini.h" +#include "mini-arm64.h" +#include "mini-arm64-gsharedvt.h" + +/* + * GSHAREDVT + */ +#ifdef MONO_ARCH_GSHARED_SUPPORTED + +/* + * mono_arch_get_gsharedvt_arg_trampoline: + * + * See tramp-x86.c for documentation. + */ +gpointer +mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) +{ + guint8 *code, *buf; + int buf_len = 40; + + /* + * Return a trampoline which calls ADDR passing in ARG. + * Pass the argument in ip1, clobbering ip0. + */ + buf = code = mono_global_codeman_reserve (buf_len); + + code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); + + arm_brx (code, ARMREG_IP0); + + g_assert ((code - buf) < buf_len); + mono_arch_flush_icache (buf, code - buf); + + return buf; +} + +gpointer +mono_arm_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) +{ + int i; + + /* Set vtype ret arg */ + if (info->vret_slot != -1) { + g_assert (info->vret_slot); + callee [info->vret_arg_reg] = &callee [info->vret_slot]; + } + + for (i = 0; i < info->map_count; ++i) { + int src = info->map [i * 2]; + int dst = info->map [(i * 2) + 1]; + int arg_marshal = (src >> 18) & 0xf; + int arg_size = (src >> 22) & 0xf; + + if (G_UNLIKELY (arg_size)) { + int src_offset = (src >> 26) & 0xf; + int dst_offset = (dst >> 26) & 0xf; + int src_slot, dst_slot; + guint8 *src_ptr, *dst_ptr; + + /* + * Argument passed in part of a stack slot on ios. + * src_offset/dst_offset is the offset within the stack slot. + */ + switch (arg_marshal) { + case GSHAREDVT_ARG_NONE: + src_slot = src & 0xffff; + dst_slot = dst & 0xffff; + src_ptr = (guint8*)(caller + src_slot) + src_offset; + dst_ptr = (guint8*)(callee + dst_slot) + dst_offset; + break; + case GSHAREDVT_ARG_BYREF_TO_BYVAL: + src_slot = src & 0x3f; + dst_slot = dst & 0xffff; + src_ptr = caller [src_slot]; + dst_ptr = (guint8*)(callee + dst_slot) + dst_offset; + break; + case GSHAREDVT_ARG_BYVAL_TO_BYREF_HFAR4: + case GSHAREDVT_ARG_BYREF_TO_BYVAL_HFAR4: + case GSHAREDVT_ARG_BYREF_TO_BYREF: + g_assert_not_reached (); + break; + default: + NOT_IMPLEMENTED; + break; + } + + switch (arg_size) { + case GSHAREDVT_ARG_SIZE_I1: + *(gint8*)dst_ptr = *(gint8*)src_ptr; + break; + case GSHAREDVT_ARG_SIZE_U1: + *(guint8*)dst_ptr = *(guint8*)src_ptr; + break; + case GSHAREDVT_ARG_SIZE_I2: + *(gint16*)dst_ptr = *(gint16*)src_ptr; + break; + case GSHAREDVT_ARG_SIZE_U2: + *(guint16*)dst_ptr = *(guint16*)src_ptr; + break; + case GSHAREDVT_ARG_SIZE_I4: + *(gint32*)dst_ptr = *(gint32*)src_ptr; + break; + case GSHAREDVT_ARG_SIZE_U4: + *(guint32*)dst_ptr = *(guint32*)src_ptr; + break; + default: + g_assert_not_reached (); + } + continue; + } + + switch (arg_marshal) { + case GSHAREDVT_ARG_NONE: + callee [dst] = caller [src]; + break; + case GSHAREDVT_ARG_BYVAL_TO_BYREF: + /* gsharedvt argument passed by addr in reg/stack slot */ + src = src & 0x3f; + callee [dst] = caller + src; + break; + case GSHAREDVT_ARG_BYVAL_TO_BYREF_HFAR4: { + int nslots = (src >> 6) & 0xff; + int src_slot = src & 0x3f; + int j; + float *dst_arr = (float*)(caller + src_slot); + + /* The r4 hfa is in separate slots, need to compress them together in place */ + for (j = 0; j < nslots; ++j) + dst_arr [j] = *(float*)(caller + src_slot + j); + + callee [dst] = caller + src_slot; + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYVAL: { + int nslots = (src >> 6) & 0xff; + int src_slot = src & 0x3f; + int j; + gpointer *addr = caller [src_slot]; + + for (j = 0; j < nslots; ++j) + callee [dst + j] = addr [j]; + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYVAL_HFAR4: { + int nslots = (src >> 6) & 0xff; + int src_slot = src & 0x3f; + int j; + guint32 *addr = (guint32*)(caller [src_slot]); + + /* addr points to an array of floats, need to load them to registers */ + for (j = 0; j < nslots; ++j) + callee [dst + j] = GUINT_TO_POINTER (addr [j]); + break; + } + case GSHAREDVT_ARG_BYREF_TO_BYREF: { + int src_slot = src & 0x3f; + + callee [dst] = caller [src_slot]; + break; + } + default: + g_assert_not_reached (); + break; + } + } + + if (info->vcall_offset != -1) { + MonoObject *this_obj = caller [0]; + + if (G_UNLIKELY (!this_obj)) + return NULL; + if (info->vcall_offset == MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET) + /* delegate invoke */ + return ((MonoDelegate*)this_obj)->invoke_impl; + else + return *(gpointer*)((char*)this_obj->vtable + info->vcall_offset); + } else if (info->calli) { + /* The address to call is passed in the mrgctx reg */ + return mrgctx_reg; + } else { + return info->addr; + } +} + +#ifndef DISABLE_JIT + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf; + int buf_len, cfa_offset; + GSList *unwind_ops = NULL; + MonoJumpInfo *ji = NULL; + guint8 *br_out, *br [64], *br_ret [64], *bcc_ret [64]; + int i, n_arg_regs, n_arg_fregs, offset, arg_reg, info_offset, rgctx_arg_reg_offset; + int caller_reg_area_offset, callee_reg_area_offset, callee_stack_area_offset; + int br_ret_index, bcc_ret_index; + + buf_len = 2048; + buf = code = mono_global_codeman_reserve (buf_len); + + /* + * We are being called by an gsharedvt arg trampoline, the info argument is in IP1. + */ + arg_reg = ARMREG_IP1; + n_arg_regs = NUM_GSHAREDVT_ARG_GREGS; + n_arg_fregs = NUM_GSHAREDVT_ARG_FREGS; + + /* Compute stack frame size and offsets */ + offset = 0; + /* frame block */ + offset += 2 * 8; + /* info argument */ + info_offset = offset; + offset += 8; + /* saved rgctx */ + rgctx_arg_reg_offset = offset; + offset += 8; + /* alignment */ + offset += 8; + /* argument regs */ + caller_reg_area_offset = offset; + offset += (n_arg_regs + n_arg_fregs) * 8; + + /* We need the argument regs to be saved at the top of the frame */ + g_assert (offset % MONO_ARCH_FRAME_ALIGNMENT == 0); + + cfa_offset = offset; + + /* Setup frame */ + arm_stpx_pre (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, -cfa_offset); + mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset); + mono_add_unwind_op_offset (unwind_ops, code, buf, ARMREG_FP, -cfa_offset + 0); + mono_add_unwind_op_offset (unwind_ops, code, buf, ARMREG_LR, -cfa_offset + 8); + arm_movspx (code, ARMREG_FP, ARMREG_SP); + mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, ARMREG_FP); + + /* Save info argument */ + arm_strx (code, arg_reg, ARMREG_FP, info_offset); + + /* Save rgxctx */ + arm_strx (code, MONO_ARCH_RGCTX_REG, ARMREG_FP, rgctx_arg_reg_offset); + + /* Save argument regs below the stack arguments */ + for (i = 0; i < n_arg_regs; ++i) + arm_strx (code, i, ARMREG_SP, caller_reg_area_offset + (i * 8)); + // FIXME: Only do this if fp regs are used + for (i = 0; i < n_arg_fregs; ++i) + arm_strfpx (code, i, ARMREG_SP, caller_reg_area_offset + ((n_arg_regs + i) * 8)); + + /* Allocate callee area */ + arm_ldrw (code, ARMREG_IP0, arg_reg, MONO_STRUCT_OFFSET (GSharedVtCallInfo, stack_usage)); + arm_movspx (code, ARMREG_LR, ARMREG_SP); + arm_subx (code, ARMREG_LR, ARMREG_LR, ARMREG_IP0); + arm_movspx (code, ARMREG_SP, ARMREG_LR); + /* Allocate callee register area just below the callee area so it can be accessed from start_gsharedvt_call using negative offsets */ + /* The + 8 is for alignment */ + callee_reg_area_offset = 8; + callee_stack_area_offset = callee_reg_area_offset + (n_arg_regs * sizeof (gpointer)); + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, ((n_arg_regs + n_arg_fregs) * sizeof (gpointer)) + 8); + + /* + * The stack now looks like this: + * + * + * + * <- fp + * <- sp + */ + + /* Call start_gsharedvt_call () */ + /* arg1 == info */ + arm_ldrx (code, ARMREG_R0, ARMREG_FP, info_offset); + /* arg2 = caller stack area */ + arm_addx_imm (code, ARMREG_R1, ARMREG_FP, caller_reg_area_offset); + /* arg3 == callee stack area */ + arm_addx_imm (code, ARMREG_R2, ARMREG_SP, callee_reg_area_offset); + /* arg4 = mrgctx reg */ + arm_ldrx (code, ARMREG_R3, ARMREG_FP, rgctx_arg_reg_offset); + + if (aot) + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_arm_start_gsharedvt_call"); + else + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)mono_arm_start_gsharedvt_call); + arm_blrx (code, ARMREG_IP0); + + /* Make the real method call */ + /* R0 contains the addr to call */ + arm_movx (code, ARMREG_IP1, ARMREG_R0); + /* Load rgxctx */ + arm_ldrx (code, MONO_ARCH_RGCTX_REG, ARMREG_FP, rgctx_arg_reg_offset); + /* Load argument registers */ + // FIXME: + for (i = 0; i < n_arg_regs; ++i) + arm_ldrx (code, i, ARMREG_SP, callee_reg_area_offset + (i * 8)); + // FIXME: Only do this if needed + for (i = 0; i < n_arg_fregs; ++i) + arm_ldrfpx (code, i, ARMREG_SP, callee_reg_area_offset + ((n_arg_regs + i) * 8)); + /* Clear callee reg area */ + arm_addx_imm (code, ARMREG_SP, ARMREG_SP, ((n_arg_regs + n_arg_fregs) * sizeof (gpointer)) + 8); + /* Make the call */ + arm_blrx (code, ARMREG_IP1); + + br_ret_index = 0; + bcc_ret_index = 0; + + // FIXME: Use a switch + /* Branch between IN/OUT cases */ + arm_ldrx (code, ARMREG_IP1, ARMREG_FP, info_offset); + arm_ldrw (code, ARMREG_IP1, ARMREG_IP1, MONO_STRUCT_OFFSET (GSharedVtCallInfo, gsharedvt_in)); + br_out = code; + arm_cbzx (code, ARMREG_IP1, 0); + + /* IN CASE */ + + /* IP1 == return marshalling type */ + arm_ldrx (code, ARMREG_IP1, ARMREG_FP, info_offset); + arm_ldrw (code, ARMREG_IP1, ARMREG_IP1, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal)); + + /* Continue if no marshalling required */ + // FIXME: Use cmpx_imm + code = mono_arm_emit_imm64 (code, ARMREG_IP0, GSHAREDVT_RET_NONE); + arm_cmpx (code, ARMREG_IP0, ARMREG_IP1); + bcc_ret [bcc_ret_index ++] = code; + arm_bcc (code, ARMCOND_EQ, 0); + + /* Compute vret area address in LR */ + arm_ldrx (code, ARMREG_LR, ARMREG_FP, info_offset); + arm_ldrw (code, ARMREG_LR, ARMREG_LR, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_slot)); + arm_subx_imm (code, ARMREG_LR, ARMREG_LR, n_arg_regs + n_arg_fregs); + arm_lslx (code, ARMREG_LR, ARMREG_LR, 3); + arm_movspx (code, ARMREG_IP0, ARMREG_SP); + arm_addx (code, ARMREG_LR, ARMREG_IP0, ARMREG_LR); + + /* Branch to specific marshalling code */ + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + code = mono_arm_emit_imm64 (code, ARMREG_IP0, i); + arm_cmpx (code, ARMREG_IP0, ARMREG_IP1); + br [i] = code; + arm_bcc (code, ARMCOND_EQ, 0); + } + + arm_brk (code, 0); + + /* + * The address of the return value area is in LR, have to load it into + * registers. + */ + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + mono_arm_patch (br [i], code, MONO_R_ARM64_BCC); + switch (i) { + case GSHAREDVT_RET_NONE: + break; + case GSHAREDVT_RET_I8: + arm_ldrx (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_I1: + arm_ldrsbx (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_U1: + arm_ldrb (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_I2: + arm_ldrshx (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_U2: + arm_ldrh (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_I4: + arm_ldrswx (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_U4: + arm_ldrw (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_R8: + arm_ldrfpx (code, ARMREG_D0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_R4: + arm_ldrfpw (code, ARMREG_D0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_IREGS_1: + case GSHAREDVT_RET_IREGS_2: + case GSHAREDVT_RET_IREGS_3: + case GSHAREDVT_RET_IREGS_4: + case GSHAREDVT_RET_IREGS_5: + case GSHAREDVT_RET_IREGS_6: + case GSHAREDVT_RET_IREGS_7: + case GSHAREDVT_RET_IREGS_8: { + int j; + + for (j = 0; j < i - GSHAREDVT_RET_IREGS_1 + 1; ++j) + arm_ldrx (code, j, ARMREG_LR, j * 8); + break; + } + case GSHAREDVT_RET_HFAR8_1: + case GSHAREDVT_RET_HFAR8_2: + case GSHAREDVT_RET_HFAR8_3: + case GSHAREDVT_RET_HFAR8_4: { + int j; + + for (j = 0; j < i - GSHAREDVT_RET_HFAR8_1 + 1; ++j) + arm_ldrfpx (code, j, ARMREG_LR, j * 8); + break; + } + case GSHAREDVT_RET_HFAR4_1: + case GSHAREDVT_RET_HFAR4_2: + case GSHAREDVT_RET_HFAR4_3: + case GSHAREDVT_RET_HFAR4_4: { + int j; + + for (j = 0; j < i - GSHAREDVT_RET_HFAR4_1 + 1; ++j) + arm_ldrfpw (code, j, ARMREG_LR, j * 4); + break; + } + default: + g_assert_not_reached (); + break; + } + br_ret [br_ret_index ++] = code; + arm_b (code, 0); + } + + /* OUT CASE */ + mono_arm_patch (br_out, code, MONO_R_ARM64_CBZ); + + /* Compute vret area address in LR */ + arm_ldrx (code, ARMREG_LR, ARMREG_FP, caller_reg_area_offset + (ARMREG_R8 * 8)); + + /* IP1 == return marshalling type */ + arm_ldrx (code, ARMREG_IP1, ARMREG_FP, info_offset); + arm_ldrw (code, ARMREG_IP1, ARMREG_IP1, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal)); + + /* Branch to specific marshalling code */ + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + code = mono_arm_emit_imm64 (code, ARMREG_IP0, i); + arm_cmpx (code, ARMREG_IP0, ARMREG_IP1); + br [i] = code; + arm_bcc (code, ARMCOND_EQ, 0); + } + + /* + * The return value is in registers, need to save to the return area passed by the caller in + * R8. + */ + for (i = GSHAREDVT_RET_NONE; i < GSHAREDVT_RET_NUM; ++i) { + mono_arm_patch (br [i], code, MONO_R_ARM64_BCC); + switch (i) { + case GSHAREDVT_RET_NONE: + break; + case GSHAREDVT_RET_I8: + arm_strx (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_I1: + case GSHAREDVT_RET_U1: + arm_strb (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_I2: + case GSHAREDVT_RET_U2: + arm_strh (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_I4: + case GSHAREDVT_RET_U4: + arm_strw (code, ARMREG_R0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_R8: + arm_strfpx (code, ARMREG_D0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_R4: + arm_strfpw (code, ARMREG_D0, ARMREG_LR, 0); + break; + case GSHAREDVT_RET_IREGS_1: + case GSHAREDVT_RET_IREGS_2: + case GSHAREDVT_RET_IREGS_3: + case GSHAREDVT_RET_IREGS_4: + case GSHAREDVT_RET_IREGS_5: + case GSHAREDVT_RET_IREGS_6: + case GSHAREDVT_RET_IREGS_7: + case GSHAREDVT_RET_IREGS_8: { + int j; + + for (j = 0; j < i - GSHAREDVT_RET_IREGS_1 + 1; ++j) + arm_strx (code, j, ARMREG_LR, j * 8); + break; + } + case GSHAREDVT_RET_HFAR8_1: + case GSHAREDVT_RET_HFAR8_2: + case GSHAREDVT_RET_HFAR8_3: + case GSHAREDVT_RET_HFAR8_4: { + int j; + + for (j = 0; j < i - GSHAREDVT_RET_HFAR8_1 + 1; ++j) + arm_strfpx (code, j, ARMREG_LR, j * 8); + break; + } + case GSHAREDVT_RET_HFAR4_1: + case GSHAREDVT_RET_HFAR4_2: + case GSHAREDVT_RET_HFAR4_3: + case GSHAREDVT_RET_HFAR4_4: { + int j; + + for (j = 0; j < i - GSHAREDVT_RET_HFAR4_1 + 1; ++j) + arm_strfpw (code, j, ARMREG_LR, j * 4); + break; + } + default: + arm_brk (code, i); + break; + } + br_ret [br_ret_index ++] = code; + arm_b (code, 0); + } + + arm_brk (code, 0); + + for (i = 0; i < br_ret_index; ++i) + mono_arm_patch (br_ret [i], code, MONO_R_ARM64_B); + for (i = 0; i < bcc_ret_index; ++i) + mono_arm_patch (bcc_ret [i], code, MONO_R_ARM64_BCC); + + /* Normal return */ + arm_movspx (code, ARMREG_SP, ARMREG_FP); + arm_ldpx_post (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, offset); + arm_retx (code, ARMREG_LR); + + g_assert ((code - buf) < buf_len); + + if (info) + *info = mono_tramp_info_create ("gsharedvt_trampoline", buf, code - buf, ji, unwind_ops); + + mono_arch_flush_icache (buf, code - buf); + return buf; +} + +#else + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +#endif + +#else + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + if (info) + *info = NULL; + return NULL; +} + +gpointer +mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr) +{ + g_assert_not_reached (); + return NULL; +} + +#endif /* MONO_ARCH_GSHARED_SUPPORTED */ \ No newline at end of file diff --git a/mono/mini/tramp-arm64.c b/mono/mini/tramp-arm64.c index 16504375d84..5088fea2297 100644 --- a/mono/mini/tramp-arm64.c +++ b/mono/mini/tramp-arm64.c @@ -1 +1,616 @@ -#include "../../../mono-extensions/mono/mini/tramp-arm64.c" +/* + * tramp-arm64.c: JIT trampoline code for ARM64 + * + * Copyright 2013 Xamarin Inc + * + * Based on tramp-arm.c: + * + * Authors: + * Paolo Molaro (lupus@ximian.com) + * + * (C) 2001-2003 Ximian, Inc. + * Copyright 2003-2011 Novell Inc + * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ + +#include "mini.h" +#include "debugger-agent.h" + +#include +#include + +#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) + +void +mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr) +{ + mono_arm_patch (code_ptr - 4, addr, MONO_R_ARM64_BL); + mono_arch_flush_icache (code_ptr - 4, 4); +} + +void +mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr) +{ + guint32 ins; + guint64 slot_addr; + int disp; + + /* + * Decode the address loaded by the PLT entry emitted by arch_emit_plt_entry () in + * aot-compiler.c + */ + + /* adrp */ + ins = ((guint32*)code) [0]; + g_assert (((ins >> 24) & 0x1f) == 0x10); + disp = (((ins >> 5) & 0x7ffff) << 2) | ((ins >> 29) & 0x3); + /* FIXME: disp is signed */ + g_assert ((disp >> 20) == 0); + + slot_addr = ((guint64)code + (disp << 12)) & ~0xfff; + + /* add x16, x16, :lo12:got */ + ins = ((guint32*)code) [1]; + g_assert (((ins >> 22) & 0x3) == 0); + slot_addr += (ins >> 10) & 0xfff; + + /* ldr x16, [x16, ] */ + ins = ((guint32*)code) [2]; + g_assert (((ins >> 24) & 0x3f) == 0x39); + slot_addr += ((ins >> 10) & 0xfff) * 8; + + g_assert (*(guint64*)slot_addr); + *(gpointer*)slot_addr = addr; +} + +guint8* +mono_arch_get_call_target (guint8 *code) +{ + guint32 imm; + int disp; + + code -= 4; + + imm = *(guint32*)code; + /* Should be a bl */ + g_assert (((imm >> 31) & 0x1) == 0x1); + g_assert (((imm >> 26) & 0x7) == 0x5); + + disp = (imm & 0x3ffffff); + if ((disp >> 25) != 0) + /* Negative, sing extend to 32 bits */ + disp = disp | 0xfc000000; + + return code + (disp * 4); +} + +guint32 +mono_arch_get_plt_info_offset (guint8 *plt_entry, mgreg_t *regs, guint8 *code) +{ + /* The offset is stored as the 5th word of the plt entry */ + return ((guint32*)plt_entry) [4]; +} + +#ifndef DISABLE_JIT + +guchar* +mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf, *tramp; + int i, buf_len, imm; + int frame_size, offset, gregs_offset, num_fregs, fregs_offset, arg_offset, lmf_offset; + guint64 gregs_regset; + GSList *unwind_ops = NULL; + MonoJumpInfo *ji = NULL; + char *tramp_name; + + buf_len = 768; + buf = code = mono_global_codeman_reserve (buf_len); + + /* + * We are getting called by a specific trampoline, ip1 contains the trampoline argument. + */ + + /* Compute stack frame size and offsets */ + offset = 0; + /* frame block */ + offset += 2 * 8; + /* gregs */ + gregs_offset = offset; + offset += 32 * 8; + /* fregs */ + // FIXME: Save 128 bits + /* Only have to save the argument regs */ + num_fregs = 8; + fregs_offset = offset; + offset += num_fregs * 8; + /* arg */ + arg_offset = offset; + offset += 8; + /* LMF */ + lmf_offset = offset; + offset += sizeof (MonoLMF); + //offset += 22 * 8; + frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + + /* Setup stack frame */ + imm = frame_size; + while (imm > 256) { + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, 256); + imm -= 256; + } + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, imm); + arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0); + arm_movspx (code, ARMREG_FP, ARMREG_SP); + + /* Save gregs */ + // FIXME: Optimize this + gregs_regset = ~((1 << ARMREG_FP) | (1 << ARMREG_SP)); + code = mono_arm_emit_store_regarray (code, gregs_regset, ARMREG_FP, gregs_offset); + /* Save fregs */ + for (i = 0; i < num_fregs; ++i) + arm_strfpx (code, i, ARMREG_FP, fregs_offset + (i * 8)); + /* Save trampoline arg */ + arm_strx (code, ARMREG_IP1, ARMREG_FP, arg_offset); + + /* Setup LMF */ + arm_addx_imm (code, ARMREG_IP0, ARMREG_FP, lmf_offset); + code = mono_arm_emit_store_regset (code, MONO_ARCH_LMF_REGS, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, gregs)); + /* Save caller fp */ + arm_ldrx (code, ARMREG_IP1, ARMREG_FP, 0); + arm_strx (code, ARMREG_IP1, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, gregs) + (MONO_ARCH_LMF_REG_FP * 8)); + /* Save caller sp */ + arm_movx (code, ARMREG_IP1, ARMREG_FP); + imm = frame_size; + while (imm > 256) { + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 256); + imm -= 256; + } + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, imm); + arm_strx (code, ARMREG_IP1, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, gregs) + (MONO_ARCH_LMF_REG_SP * 8)); + /* Save caller pc */ + if (tramp_type == MONO_TRAMPOLINE_JUMP) + arm_movx (code, ARMREG_LR, ARMREG_RZR); + else + arm_ldrx (code, ARMREG_LR, ARMREG_FP, 8); + arm_strx (code, ARMREG_LR, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, pc)); + + /* Save LMF */ + /* Similar to emit_save_lmf () */ + if (aot) { + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_get_lmf_addr"); + } else { + tramp = (guint8*)mono_get_lmf_addr; + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); + } + arm_blrx (code, ARMREG_IP0); + /* r0 contains the address of the tls slot holding the current lmf */ + /* ip0 = lmf */ + arm_addx_imm (code, ARMREG_IP0, ARMREG_FP, lmf_offset); + /* lmf->lmf_addr = lmf_addr */ + arm_strx (code, ARMREG_R0, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr)); + /* lmf->previous_lmf = *lmf_addr */ + arm_ldrx (code, ARMREG_IP1, ARMREG_R0, 0); + arm_strx (code, ARMREG_IP1, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); + /* *lmf_addr = lmf */ + arm_strx (code, ARMREG_IP0, ARMREG_R0, 0); + + /* Call the C trampoline function */ + /* Arg 1 = gregs */ + arm_addx_imm (code, ARMREG_R0, ARMREG_FP, gregs_offset); + /* Arg 2 = caller */ + if (tramp_type == MONO_TRAMPOLINE_JUMP) + arm_movx (code, ARMREG_R1, ARMREG_RZR); + else + arm_ldrx (code, ARMREG_R1, ARMREG_FP, gregs_offset + (ARMREG_LR * 8)); + /* Arg 3 = arg */ + if (MONO_TRAMPOLINE_TYPE_HAS_ARG (tramp_type)) + /* Passed in r0 */ + arm_ldrx (code, ARMREG_R2, ARMREG_FP, gregs_offset + (ARMREG_R0 * 8)); + else + arm_ldrx (code, ARMREG_R2, ARMREG_FP, arg_offset); + /* Arg 4 = trampoline addr */ + arm_movx (code, ARMREG_R3, ARMREG_RZR); + + if (aot) { + char *icall_name = g_strdup_printf ("trampoline_func_%d", tramp_type); + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name); + } else { + tramp = (guint8*)mono_get_trampoline_func (tramp_type); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); + } + arm_blrx (code, ARMREG_IP0); + + /* Restore LMF */ + /* Similar to emit_restore_lmf () */ + /* Clobbers ip0/ip1 */ + /* ip0 = lmf */ + arm_addx_imm (code, ARMREG_IP0, ARMREG_FP, lmf_offset); + /* ip1 = lmf->previous_lmf */ + arm_ldrx (code, ARMREG_IP1, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf)); + /* ip0 = lmf->lmf_addr */ + arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr)); + /* *lmf_addr = previous_lmf */ + arm_strx (code, ARMREG_IP1, ARMREG_IP0, 0); + + /* Save the result to ip1 */ + arm_movx (code, ARMREG_IP1, ARMREG_R0); + + /* Restore gregs */ + /* Only have to load the argument regs (r0..r8) and the rgctx reg */ + code = mono_arm_emit_load_regarray (code, 0x1ff | (1 << ARMREG_LR) | (1 << MONO_ARCH_RGCTX_REG), ARMREG_FP, gregs_offset); + /* Restore fregs */ + for (i = 0; i < num_fregs; ++i) + arm_ldrfpx (code, i, ARMREG_FP, fregs_offset + (i * 8)); + + /* These trampolines return a value */ + if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH) + arm_movx (code, ARMREG_R0, ARMREG_IP1); + + /* Cleanup frame */ + code = mono_arm_emit_destroy_frame (code, frame_size, ((1 << ARMREG_IP0))); + + if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH) + arm_retx (code, ARMREG_LR); + else + arm_brx (code, ARMREG_IP1); + + g_assert ((code - buf) < buf_len); + mono_arch_flush_icache (buf, code - buf); + + if (info) { + tramp_name = mono_get_generic_trampoline_name (tramp_type); + *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops); + g_free (tramp_name); + } + + return buf; +} + +gpointer +mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) +{ + guint8 *code, *buf, *tramp; + int buf_len = 64; + + /* + * Return a trampoline which calls generic trampoline TRAMP_TYPE passing in ARG1. + * Pass the argument in ip1, clobbering ip0. + */ + tramp = mono_get_trampoline_code (tramp_type); + + buf = code = mono_global_codeman_reserve (buf_len); + + code = mono_arm_emit_imm64 (code, ARMREG_IP1, (guint64)arg1); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); + + arm_brx (code, ARMREG_IP0); + + g_assert ((code - buf) < buf_len); + mono_arch_flush_icache (buf, code - buf); + if (code_len) + *code_len = code - buf; + + return buf; +} + +gpointer +mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) +{ + guint8 *code, *start; + guint32 size = 32; + MonoDomain *domain = mono_domain_get (); + + start = code = mono_domain_code_reserve (domain, size); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); + arm_addx_imm (code, ARMREG_R0, ARMREG_R0, sizeof (MonoObject)); + arm_brx (code, ARMREG_IP0); + + g_assert ((code - start) <= size); + mono_arch_flush_icache (start, code - start); + return start; +} + +gpointer +mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr) +{ + guint8 *code, *start; + guint32 buf_len = 32; + MonoDomain *domain = mono_domain_get (); + + start = code = mono_domain_code_reserve (domain, buf_len); + code = mono_arm_emit_imm64 (code, MONO_ARCH_RGCTX_REG, (guint64)mrgctx); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); + arm_brx (code, ARMREG_IP0); + + g_assert ((code - start) <= buf_len); + + mono_arch_flush_icache (start, code - start); + + return start; +} + +gpointer +mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf; + int buf_size; + int i, depth, index, njumps; + gboolean is_mrgctx; + guint8 **rgctx_null_jumps; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + guint8 *tramp; + guint32 code_len; + + is_mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot); + index = MONO_RGCTX_SLOT_INDEX (slot); + if (is_mrgctx) + index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer); + for (depth = 0; ; ++depth) { + int size = mono_class_rgctx_get_array_size (depth, is_mrgctx); + + if (index < size - 1) + break; + index -= size - 1; + } + + buf_size = 64 + 16 * depth; + code = buf = mono_global_codeman_reserve (buf_size); + + rgctx_null_jumps = g_malloc0 (sizeof (guint8*) * (depth + 2)); + njumps = 0; + + /* The vtable/mrgtx is in R0 */ + g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0); + + if (is_mrgctx) { + /* get mrgctx ptr */ + arm_movx (code, ARMREG_IP1, ARMREG_R0); + } else { + /* load rgctx ptr from vtable */ + code = mono_arm_emit_ldrx (code, ARMREG_IP1, ARMREG_R0, MONO_STRUCT_OFFSET (MonoVTable, runtime_generic_context)); + /* is the rgctx ptr null? */ + /* if yes, jump to actual trampoline */ + rgctx_null_jumps [njumps ++] = code; + arm_cbzx (code, ARMREG_IP1, 0); + } + + for (i = 0; i < depth; ++i) { + /* load ptr to next array */ + if (is_mrgctx && i == 0) { + code = mono_arm_emit_ldrx (code, ARMREG_IP1, ARMREG_IP1, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT); + } else { + code = mono_arm_emit_ldrx (code, ARMREG_IP1, ARMREG_IP1, 0); + } + /* is the ptr null? */ + /* if yes, jump to actual trampoline */ + rgctx_null_jumps [njumps ++] = code; + arm_cbzx (code, ARMREG_IP1, 0); + } + + /* fetch slot */ + code = mono_arm_emit_ldrx (code, ARMREG_IP1, ARMREG_IP1, sizeof (gpointer) * (index + 1)); + /* is the slot null? */ + /* if yes, jump to actual trampoline */ + rgctx_null_jumps [njumps ++] = code; + arm_cbzx (code, ARMREG_IP1, 0); + /* otherwise return, result is in IP1 */ + arm_movx (code, ARMREG_R0, ARMREG_IP1); + arm_brx (code, ARMREG_LR); + + g_assert (njumps <= depth + 2); + for (i = 0; i < njumps; ++i) + mono_arm_patch (rgctx_null_jumps [i], code, MONO_R_ARM64_CBZ); + + g_free (rgctx_null_jumps); + + /* Slowpath */ + + /* Call mono_rgctx_lazy_fetch_trampoline (), passing in the slot as argument */ + /* The vtable/mrgctx is still in R0 */ + if (aot) { + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, g_strdup_printf ("specific_trampoline_lazy_fetch_%u", slot)); + } else { + tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), &code_len); + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)tramp); + } + arm_brx (code, ARMREG_IP0); + + mono_arch_flush_icache (buf, code - buf); + + g_assert (code - buf <= buf_size); + + if (info) { + char *name = mono_get_rgctx_fetch_trampoline_name (slot); + *info = mono_tramp_info_create (name, buf, code - buf, ji, unwind_ops); + g_free (name); + } + + return buf; +} + +gpointer +mono_arch_create_general_rgctx_lazy_fetch_trampoline (MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf; + int tramp_size; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + + g_assert (aot); + + tramp_size = 32; + + code = buf = mono_global_codeman_reserve (tramp_size); + + mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0); + + // FIXME: Currently, we always go to the slow path. + /* Load trampoline addr */ + arm_ldrx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG, 8); + /* The vtable/mrgctx is in R0 */ + g_assert (MONO_ARCH_VTABLE_REG == ARMREG_R0); + arm_brx (code, ARMREG_IP0); + + mono_arch_flush_icache (buf, code - buf); + + g_assert (code - buf <= tramp_size); + + if (info) + *info = mono_tramp_info_create ("rgctx_fetch_trampoline_general", buf, code - buf, ji, unwind_ops); + + return buf; +} + +/* + * mono_arch_create_sdb_trampoline: + * + * Return a trampoline which captures the current context, passes it to + * debugger_agent_single_step_from_context ()/debugger_agent_breakpoint_from_context (), + * then restores the (potentially changed) context. + */ +guint8* +mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot) +{ + int tramp_size = 512; + int offset, imm, frame_size, ctx_offset; + guint64 gregs_regset; + guint8 *code, *buf; + GSList *unwind_ops = NULL; + MonoJumpInfo *ji = NULL; + + code = buf = mono_global_codeman_reserve (tramp_size); + + /* Compute stack frame size and offsets */ + offset = 0; + /* frame block */ + offset += 2 * 8; + /* MonoContext */ + ctx_offset = offset; + offset += sizeof (MonoContext); + offset = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + frame_size = offset; + + // FIXME: Unwind info + + /* Setup stack frame */ + imm = frame_size; + while (imm > 256) { + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, 256); + imm -= 256; + } + arm_subx_imm (code, ARMREG_SP, ARMREG_SP, imm); + arm_stpx (code, ARMREG_FP, ARMREG_LR, ARMREG_SP, 0); + arm_movspx (code, ARMREG_FP, ARMREG_SP); + + /* Initialize a MonoContext structure on the stack */ + /* No need to save fregs */ + gregs_regset = ~((1 << ARMREG_FP) | (1 << ARMREG_SP)); + code = mono_arm_emit_store_regarray (code, gregs_regset, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, regs)); + /* Save caller fp */ + arm_ldrx (code, ARMREG_IP1, ARMREG_FP, 0); + arm_strx (code, ARMREG_IP1, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_FP * 8)); + /* Save caller sp */ + arm_movx (code, ARMREG_IP1, ARMREG_FP); + imm = frame_size; + while (imm > 256) { + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 256); + imm -= 256; + } + arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, imm); + arm_strx (code, ARMREG_IP1, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_SP * 8)); + /* Save caller ip */ + arm_ldrx (code, ARMREG_IP1, ARMREG_FP, 8); + arm_strx (code, ARMREG_IP1, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, pc)); + + /* Call the single step/breakpoint function in sdb */ + /* Arg1 = ctx */ + arm_addx_imm (code, ARMREG_R0, ARMREG_FP, ctx_offset); + if (aot) { + if (single_step) + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, "debugger_agent_single_step_from_context"); + else + code = mono_arm_emit_aotconst (&ji, code, buf, ARMREG_IP0, MONO_PATCH_INFO_JIT_ICALL_ADDR, "debugger_agent_breakpoint_from_context"); + } else { + gpointer addr = single_step ? debugger_agent_single_step_from_context : debugger_agent_breakpoint_from_context; + + code = mono_arm_emit_imm64 (code, ARMREG_IP0, (guint64)addr); + } + arm_blrx (code, ARMREG_IP0); + + /* Restore ctx */ + /* Save fp/pc into the frame block */ + arm_ldrx (code, ARMREG_IP0, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, regs) + (ARMREG_FP * 8)); + arm_strx (code, ARMREG_IP0, ARMREG_FP, 0); + arm_ldrx (code, ARMREG_IP0, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, pc)); + arm_strx (code, ARMREG_IP0, ARMREG_FP, 8); + gregs_regset = ~((1 << ARMREG_FP) | (1 << ARMREG_SP)); + code = mono_arm_emit_load_regarray (code, gregs_regset, ARMREG_FP, ctx_offset + G_STRUCT_OFFSET (MonoContext, regs)); + + code = mono_arm_emit_destroy_frame (code, frame_size, ((1 << ARMREG_IP0) | (1 << ARMREG_IP1))); + + arm_retx (code, ARMREG_LR); + + mono_arch_flush_icache (code, code - buf); + g_assert (code - buf <= tramp_size); + + const char *tramp_name = single_step ? "sdb_single_step_trampoline" : "sdb_breakpoint_trampoline"; + *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops); + + return buf; +} + +#else /* DISABLE_JIT */ + +guchar* +mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +gpointer +mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info) +{ + g_assert_not_reached (); + return NULL; +} + +guint8* +mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} + +#endif /* !DISABLE_JIT */ diff --git a/mono/mini/tramp-s390x.c b/mono/mini/tramp-s390x.c index eb61dc05cd4..408997daace 100644 --- a/mono/mini/tramp-s390x.c +++ b/mono/mini/tramp-s390x.c @@ -13,7 +13,7 @@ /* Dietmar Maurer (dietmar@ximian.com) */ /* */ /* Copyright - 2001 Ximian, Inc. */ -/* */ +/* Licensed under the MIT license. See LICENSE file in the project root for full license information.*/ /*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/ diff --git a/mono/mini/tramp-x86-gsharedvt.c b/mono/mini/tramp-x86-gsharedvt.c new file mode 100644 index 00000000000..757325c27f0 --- /dev/null +++ b/mono/mini/tramp-x86-gsharedvt.c @@ -0,0 +1,369 @@ +/* + * tramp-x86-gsharedvt.c: gsharedvt support code for x86 + * + * Authors: + * Zoltan Varga + * + * Copyright 2013 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + */ +#include "mini.h" +#include + +#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED + +gpointer +mono_x86_start_gsharedvt_call (GSharedVtCallInfo *info, gpointer *caller, gpointer *callee, gpointer mrgctx_reg) +{ + int i; + int *map = info->map; + + /* Set vtype ret arg */ + if (info->vret_arg_slot != -1) { + callee [info->vret_arg_slot] = &callee [info->vret_slot]; + } + /* Copy data from the caller argument area to the callee */ + for (i = 0; i < info->map_count; ++i) { + int src = map [i * 2]; + int dst = map [i * 2 + 1]; + + switch ((src >> 16) & 0x3) { + case 0: + callee [dst] = caller [src]; + break; + case 1: { + int j, nslots; + gpointer *arg; + + /* gsharedvt->normal */ + nslots = src >> 18; + arg = (gpointer*)caller [src & 0xffff]; + for (j = 0; j < nslots; ++j) + callee [dst + j] = arg [j]; + break; + } + case 2: + /* gsharedvt arg, have to take its address */ + callee [dst] = caller + (src & 0xffff); + break; +#if 0 + int dst = map [i * 2 + 1]; + if (dst >= 0xffff) { + /* gsharedvt arg, have to take its address */ + callee [dst - 0xffff] = caller + map [i * 2]; + } else { + callee [dst] = caller [map [i * 2]]; + } +#endif + } + } + + if (info->vcall_offset != -1) { + MonoObject *this_obj = caller [0]; + + if (G_UNLIKELY (!this_obj)) + return NULL; + if (info->vcall_offset == MONO_GSHAREDVT_DEL_INVOKE_VT_OFFSET) + /* delegate invoke */ + return ((MonoDelegate*)this_obj)->invoke_impl; + else + return *(gpointer*)((char*)this_obj->vtable + info->vcall_offset); + } else if (info->calli) { + /* The address to call is passed in the mrgctx reg */ + return mrgctx_reg; + } else { + return info->addr; + } + +} + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + guint8 *code, *buf; + int buf_len, cfa_offset; + GSList *unwind_ops = NULL; + MonoJumpInfo *ji = NULL; + guint8 *br_out, *br [16]; + int info_offset, mrgctx_offset; + + buf_len = 320; + buf = code = mono_global_codeman_reserve (buf_len); + + /* + * This trampoline is responsible for marshalling calls between normal code and gsharedvt code. The + * caller is a normal or gshared method which uses the signature of the inflated method to make the call, while + * the callee is a gsharedvt method which has a signature which uses valuetypes in place of type parameters, i.e. + * caller: + * foo (bool b) + * callee: + * T= + * foo (T b) + * The trampoline is responsible for marshalling the arguments and marshalling the result back. To simplify + * things, we create our own stack frame, and do most of the work in a C function, which receives a + * GSharedVtCallInfo structure as an argument. The structure should contain information to execute the C function to + * be as fast as possible. The argument is received in EAX from a gsharedvt trampoline. So the real + * call sequence looks like this: + * caller -> gsharedvt trampoline -> gsharevt in trampoline -> start_gsharedvt_call + * FIXME: Optimize this. + */ + + cfa_offset = sizeof (gpointer); + mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset); + mono_add_unwind_op_offset (unwind_ops, code, buf, X86_NREG, -cfa_offset); + x86_push_reg (code, X86_EBP); + cfa_offset += sizeof (gpointer); + mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset); + mono_add_unwind_op_offset (unwind_ops, code, buf, X86_EBP, - cfa_offset); + x86_mov_reg_reg (code, X86_EBP, X86_ESP, sizeof (gpointer)); + mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, X86_EBP); + /* Alloc stack frame/align stack */ + x86_alu_reg_imm (code, X86_SUB, X86_ESP, 8); + info_offset = -4; + mrgctx_offset = - 8; + /* The info struct is put into EAX by the gsharedvt trampoline */ + /* Save info struct addr */ + x86_mov_membase_reg (code, X86_EBP, info_offset, X86_EAX, 4); + /* Save rgctx */ + x86_mov_membase_reg (code, X86_EBP, mrgctx_offset, MONO_ARCH_RGCTX_REG, 4); + + /* Allocate stack area used to pass arguments to the method */ + x86_mov_reg_membase (code, X86_EAX, X86_EAX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, stack_usage), sizeof (gpointer)); + x86_alu_reg_reg (code, X86_SUB, X86_ESP, X86_EAX); + +#if 0 + /* Stack alignment check */ + x86_mov_reg_reg (code, X86_ECX, X86_ESP, 4); + x86_alu_reg_imm (code, X86_AND, X86_ECX, MONO_ARCH_FRAME_ALIGNMENT - 1); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, 0); + x86_branch_disp (code, X86_CC_EQ, 3, FALSE); + x86_breakpoint (code); +#endif + + /* ecx = caller argument area */ + x86_mov_reg_reg (code, X86_ECX, X86_EBP, 4); + x86_alu_reg_imm (code, X86_ADD, X86_ECX, 8); + /* eax = callee argument area */ + x86_mov_reg_reg (code, X86_EAX, X86_ESP, 4); + + /* Call start_gsharedvt_call */ + /* Arg 4 */ + x86_push_membase (code, X86_EBP, mrgctx_offset); + /* Arg3 */ + x86_push_reg (code, X86_EAX); + /* Arg2 */ + x86_push_reg (code, X86_ECX); + /* Arg1 */ + x86_push_membase (code, X86_EBP, info_offset); + if (aot) { + code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_x86_start_gsharedvt_call"); + x86_call_reg (code, X86_EAX); + } else { + x86_call_code (code, mono_x86_start_gsharedvt_call); + } + x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4 * 4); + /* The address to call is in eax */ + /* The stack is now setup for the real call */ + /* Load info struct */ + x86_mov_reg_membase (code, X86_ECX, X86_EBP, info_offset, 4); + /* Load rgctx */ + x86_mov_reg_membase (code, MONO_ARCH_RGCTX_REG, X86_EBP, mrgctx_offset, sizeof (gpointer)); + /* Make the call */ + x86_call_reg (code, X86_EAX); + /* The return value is either in registers, or stored to an area beginning at sp [info->vret_slot] */ + /* EAX/EDX might contain the return value, only ECX is free */ + /* Load info struct */ + x86_mov_reg_membase (code, X86_ECX, X86_EBP, info_offset, 4); + + /* Branch to the in/out handling code */ + x86_alu_membase_imm (code, X86_CMP, X86_ECX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, gsharedvt_in), 1); + br_out = code; + x86_branch32 (code, X86_CC_NE, 0, TRUE); + + /* + * IN CASE + */ + + /* Load ret marshal type */ + x86_mov_reg_membase (code, X86_ECX, X86_ECX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal), 4); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_NONE); + br [0] = code; + x86_branch8 (code, X86_CC_NE, 0, TRUE); + + /* Normal return, no marshalling required */ + x86_leave (code); + x86_ret (code); + + /* Return value marshalling */ + x86_patch (br [0], code); + /* Load info struct */ + x86_mov_reg_membase (code, X86_EAX, X86_EBP, info_offset, 4); + /* Load 'vret_slot' */ + x86_mov_reg_membase (code, X86_EAX, X86_EAX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_slot), 4); + /* Compute ret area address */ + x86_shift_reg_imm (code, X86_SHL, X86_EAX, 2); + x86_alu_reg_reg (code, X86_ADD, X86_EAX, X86_ESP); + /* The callee does a ret $4, so sp is off by 4 */ + x86_alu_reg_imm (code, X86_SUB, X86_EAX, sizeof (gpointer)); + + /* Branch to specific marshalling code */ + // FIXME: Move the I4 case to the top */ + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_DOUBLE_FPSTACK); + br [1] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_FLOAT_FPSTACK); + br [2] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_STACK_POP); + br [3] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_I1); + br [4] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_U1); + br [5] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_I2); + br [6] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_U2); + br [7] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + /* IREGS case */ + /* Load both eax and edx for simplicity */ + x86_mov_reg_membase (code, X86_EDX, X86_EAX, sizeof (gpointer), sizeof (gpointer)); + x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0, sizeof (gpointer)); + x86_leave (code); + x86_ret (code); + /* DOUBLE_FPSTACK case */ + x86_patch (br [1], code); + x86_fld_membase (code, X86_EAX, 0, TRUE); + x86_jump8 (code, 0); + x86_leave (code); + x86_ret (code); + /* FLOAT_FPSTACK case */ + x86_patch (br [2], code); + x86_fld_membase (code, X86_EAX, 0, FALSE); + x86_leave (code); + x86_ret (code); + /* STACK_POP case */ + x86_patch (br [3], code); + x86_leave (code); + x86_ret_imm (code, 4); + /* I1 case */ + x86_patch (br [4], code); + x86_widen_membase (code, X86_EAX, X86_EAX, 0, TRUE, FALSE); + x86_leave (code); + x86_ret (code); + /* U1 case */ + x86_patch (br [5], code); + x86_widen_membase (code, X86_EAX, X86_EAX, 0, FALSE, FALSE); + x86_leave (code); + x86_ret (code); + /* I2 case */ + x86_patch (br [6], code); + x86_widen_membase (code, X86_EAX, X86_EAX, 0, TRUE, TRUE); + x86_leave (code); + x86_ret (code); + /* U2 case */ + x86_patch (br [7], code); + x86_widen_membase (code, X86_EAX, X86_EAX, 0, FALSE, TRUE); + x86_leave (code); + x86_ret (code); + + /* + * OUT CASE + */ + + x86_patch (br_out, code); + /* Load ret marshal type into ECX */ + x86_mov_reg_membase (code, X86_ECX, X86_ECX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, ret_marshal), 4); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_NONE); + br [0] = code; + x86_branch8 (code, X86_CC_NE, 0, TRUE); + + /* Normal return, no marshalling required */ + x86_leave (code); + x86_ret (code); + + /* Return value marshalling */ + x86_patch (br [0], code); + + /* EAX might contain the return value */ + // FIXME: Use moves + x86_push_reg (code, X86_EAX); + + /* Load info struct */ + x86_mov_reg_membase (code, X86_EAX, X86_EBP, info_offset, 4); + /* Load 'vret_arg_slot' */ + x86_mov_reg_membase (code, X86_EAX, X86_EAX, MONO_STRUCT_OFFSET (GSharedVtCallInfo, vret_arg_slot), 4); + /* Compute ret area address in the caller frame in EAX */ + x86_shift_reg_imm (code, X86_SHL, X86_EAX, 2); + x86_alu_reg_reg (code, X86_ADD, X86_EAX, X86_EBP); + x86_alu_reg_imm (code, X86_ADD, X86_EAX, 8); + x86_mov_reg_membase (code, X86_EAX, X86_EAX, 0, sizeof (gpointer)); + + /* Branch to specific marshalling code */ + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_DOUBLE_FPSTACK); + br [1] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_FLOAT_FPSTACK); + br [2] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_STACK_POP); + br [3] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + x86_alu_reg_imm (code, X86_CMP, X86_ECX, GSHAREDVT_RET_IREGS); + br [4] = code; + x86_branch8 (code, X86_CC_E, 0, TRUE); + /* IREG case */ + x86_mov_reg_reg (code, X86_ECX, X86_EAX, sizeof (gpointer)); + x86_pop_reg (code, X86_EAX); + x86_mov_membase_reg (code, X86_ECX, 0, X86_EAX, sizeof (gpointer)); + x86_leave (code); + x86_ret_imm (code, 4); + /* IREGS case */ + x86_patch (br [4], code); + x86_mov_reg_reg (code, X86_ECX, X86_EAX, sizeof (gpointer)); + x86_pop_reg (code, X86_EAX); + x86_mov_membase_reg (code, X86_ECX, sizeof (gpointer), X86_EDX, sizeof (gpointer)); + x86_mov_membase_reg (code, X86_ECX, 0, X86_EAX, sizeof (gpointer)); + x86_leave (code); + x86_ret_imm (code, 4); + /* DOUBLE_FPSTACK case */ + x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4); + x86_patch (br [1], code); + x86_fst_membase (code, X86_EAX, 0, TRUE, TRUE); + x86_jump8 (code, 0); + x86_leave (code); + x86_ret_imm (code, 4); + /* FLOAT_FPSTACK case */ + x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4); + x86_patch (br [2], code); + x86_fst_membase (code, X86_EAX, 0, FALSE, TRUE); + x86_leave (code); + x86_ret_imm (code, 4); + /* STACK_POP case */ + x86_patch (br [3], code); + x86_leave (code); + x86_ret_imm (code, 4); + + g_assert ((code - buf) < buf_len); + + if (info) + *info = mono_tramp_info_create ("gsharedvt_trampoline", buf, code - buf, ji, unwind_ops); + + mono_arch_flush_icache (buf, code - buf); + return buf; +} + +#else + +gpointer +mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) +{ + *info = NULL; + return NULL; +} + +#endif /* MONO_ARCH_GSHAREDVT_SUPPORTED */ diff --git a/mono/mini/tramp-x86.c b/mono/mini/tramp-x86.c index e416527c2b3..dd560843018 100644 --- a/mono/mini/tramp-x86.c +++ b/mono/mini/tramp-x86.c @@ -878,17 +878,3 @@ mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gbo return buf; } -#if defined(ENABLE_GSHAREDVT) - -#include "../../../mono-extensions/mono/mini/tramp-x86-gsharedvt.c" - -#else - -gpointer -mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot) -{ - *info = NULL; - return NULL; -} - -#endif /* !MONOTOUCH */ diff --git a/mono/profiler/decode.c b/mono/profiler/decode.c index e57211635ee..d88694d198e 100644 --- a/mono/profiler/decode.c +++ b/mono/profiler/decode.c @@ -6,6 +6,7 @@ * Alex Rønne Petersen (alexrp@xamarin.com) * * Copyright 2010 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/profiler/mono-profiler-aot.c b/mono/profiler/mono-profiler-aot.c index 79d80717aaa..4cf48bbd1b2 100644 --- a/mono/profiler/mono-profiler-aot.c +++ b/mono/profiler/mono-profiler-aot.c @@ -9,6 +9,7 @@ * The AOT compiler can load these files during compilation. * Currently, only the order in which methods were compiled is saved, * allowing more efficient function ordering in the AOT files. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/profiler/mono-profiler-iomap.c b/mono/profiler/mono-profiler-iomap.c index 7030a4b3e5f..445e1bf1f89 100644 --- a/mono/profiler/mono-profiler-iomap.c +++ b/mono/profiler/mono-profiler-iomap.c @@ -8,6 +8,7 @@ * * Note: this profiler is completely unsafe wrt handling managed objects, * don't use and don't copy code from here. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/profiler/proflog.c b/mono/profiler/proflog.c index cb2ea092fb3..ed46b6d4cc9 100644 --- a/mono/profiler/proflog.c +++ b/mono/profiler/proflog.c @@ -7,6 +7,7 @@ * * Copyright 2010 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/profiler/utils.c b/mono/profiler/utils.c index 9266dee403c..753024dcf72 100644 --- a/mono/profiler/utils.c +++ b/mono/profiler/utils.c @@ -12,6 +12,7 @@ * Paolo Molaro (lupus@ximian.com) * * Copyright 2010 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "utils.h" #include diff --git a/mono/sgen/gc-internal-agnostic.h b/mono/sgen/gc-internal-agnostic.h index a609c69d86f..9fe2f3ceeb4 100644 --- a/mono/sgen/gc-internal-agnostic.h +++ b/mono/sgen/gc-internal-agnostic.h @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_METADATA_GCINTERNALAGNOSTIC_H__ diff --git a/mono/sgen/sgen-alloc.c b/mono/sgen/sgen-alloc.c index 9d3f45195e1..2bc3214f143 100644 --- a/mono/sgen/sgen-alloc.c +++ b/mono/sgen/sgen-alloc.c @@ -10,18 +10,7 @@ * Copyright 2011 Xamarin, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/sgen/sgen-archdep.h b/mono/sgen/sgen-archdep.h index 5e349f8416e..b4c058f13a4 100644 --- a/mono/sgen/sgen-archdep.h +++ b/mono/sgen/sgen-archdep.h @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGENARCHDEP_H__ #define __MONO_SGENARCHDEP_H__ diff --git a/mono/sgen/sgen-cardtable.c b/mono/sgen/sgen-cardtable.c index 16f4ea6a7d9..05dfe7d9074 100644 --- a/mono/sgen/sgen-cardtable.c +++ b/mono/sgen/sgen-cardtable.c @@ -9,18 +9,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-cardtable.h b/mono/sgen/sgen-cardtable.h index fde8ac11eff..059fb77fa64 100644 --- a/mono/sgen/sgen-cardtable.h +++ b/mono/sgen/sgen-cardtable.h @@ -2,24 +2,7 @@ * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_CARD_TABLE_INLINES_H__ #define __MONO_SGEN_CARD_TABLE_INLINES_H__ diff --git a/mono/sgen/sgen-client.h b/mono/sgen/sgen-client.h index a975040734d..4cf9f003d55 100644 --- a/mono/sgen/sgen-client.h +++ b/mono/sgen/sgen-client.h @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/sgen/sgen-pointer-queue.h" diff --git a/mono/sgen/sgen-conf.h b/mono/sgen/sgen-conf.h index 11a8998478e..429dcb26af3 100644 --- a/mono/sgen/sgen-conf.h +++ b/mono/sgen/sgen-conf.h @@ -6,18 +6,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGENCONF_H__ #define __MONO_SGENCONF_H__ diff --git a/mono/sgen/sgen-copy-object.h b/mono/sgen/sgen-copy-object.h index 2b7bc60670a..016fc462e0e 100644 --- a/mono/sgen/sgen-copy-object.h +++ b/mono/sgen/sgen-copy-object.h @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ extern guint64 stat_copy_object_called_nursery; diff --git a/mono/sgen/sgen-debug.c b/mono/sgen/sgen-debug.c index 27e8cb0addf..28e77a77e87 100644 --- a/mono/sgen/sgen-debug.c +++ b/mono/sgen/sgen-debug.c @@ -10,18 +10,7 @@ * Copyright 2011 Xamarin, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-descriptor.c b/mono/sgen/sgen-descriptor.c index 1d5b36637ee..852a4a63329 100644 --- a/mono/sgen/sgen-descriptor.c +++ b/mono/sgen/sgen-descriptor.c @@ -6,18 +6,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" #ifdef HAVE_SGEN_GC diff --git a/mono/sgen/sgen-descriptor.h b/mono/sgen/sgen-descriptor.h index c61fa5f74d6..2b1f9e4da49 100644 --- a/mono/sgen/sgen-descriptor.h +++ b/mono/sgen/sgen-descriptor.h @@ -7,18 +7,7 @@ * * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_DESCRIPTOR_H__ #define __MONO_SGEN_DESCRIPTOR_H__ diff --git a/mono/sgen/sgen-fin-weak-hash.c b/mono/sgen/sgen-fin-weak-hash.c index 5130b1c6b38..dd7cca93dbe 100644 --- a/mono/sgen/sgen-fin-weak-hash.c +++ b/mono/sgen/sgen-fin-weak-hash.c @@ -10,18 +10,7 @@ * Copyright 2011 Xamarin, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-gc.c b/mono/sgen/sgen-gc.c index 62e1e88fe8e..f3077a6759c 100644 --- a/mono/sgen/sgen-gc.c +++ b/mono/sgen/sgen-gc.c @@ -18,18 +18,7 @@ * Copyright 2011 Xamarin, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. * * Important: allocation provides always zeroed memory, having to do * a memset after allocation is deadly for performance. diff --git a/mono/sgen/sgen-gc.h b/mono/sgen/sgen-gc.h index 381e24d6f45..f3d868a5416 100644 --- a/mono/sgen/sgen-gc.h +++ b/mono/sgen/sgen-gc.h @@ -6,18 +6,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGENGC_H__ #define __MONO_SGENGC_H__ diff --git a/mono/sgen/sgen-gchandles.c b/mono/sgen/sgen-gchandles.c index 68be8b5c243..223116861a6 100644 --- a/mono/sgen/sgen-gchandles.c +++ b/mono/sgen/sgen-gchandles.c @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-gray.c b/mono/sgen/sgen-gray.c index cb6694342fe..809215136f9 100644 --- a/mono/sgen/sgen-gray.c +++ b/mono/sgen/sgen-gray.c @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" #ifdef HAVE_SGEN_GC diff --git a/mono/sgen/sgen-gray.h b/mono/sgen/sgen-gray.h index 79d2c701a0e..019f44c927c 100644 --- a/mono/sgen/sgen-gray.h +++ b/mono/sgen/sgen-gray.h @@ -4,18 +4,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_GRAY_H__ #define __MONO_SGEN_GRAY_H__ diff --git a/mono/sgen/sgen-internal.c b/mono/sgen/sgen-internal.c index e5327399c58..256e32b20a1 100644 --- a/mono/sgen/sgen-internal.c +++ b/mono/sgen/sgen-internal.c @@ -3,18 +3,7 @@ * * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-layout-stats.c b/mono/sgen/sgen-layout-stats.c index 2f9ca117783..74c5c02a027 100644 --- a/mono/sgen/sgen-layout-stats.c +++ b/mono/sgen/sgen-layout-stats.c @@ -1,24 +1,7 @@ /* * Copyright Xamarin Inc (http://www.xamarin.com) * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-layout-stats.h b/mono/sgen/sgen-layout-stats.h index 3853d346348..024e0192442 100644 --- a/mono/sgen/sgen-layout-stats.h +++ b/mono/sgen/sgen-layout-stats.h @@ -1,24 +1,7 @@ /* * Copyright Xamarin Inc (http://www.xamarin.com) * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_LAYOUT_STATS_H__ #define __MONO_SGEN_LAYOUT_STATS_H__ diff --git a/mono/sgen/sgen-los.c b/mono/sgen/sgen-los.c index eb620281410..5cb3c71253d 100644 --- a/mono/sgen/sgen-los.c +++ b/mono/sgen/sgen-los.c @@ -15,18 +15,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-major-copy-object.h b/mono/sgen/sgen-major-copy-object.h index a4b10ff85df..826aca9dfd1 100644 --- a/mono/sgen/sgen-major-copy-object.h +++ b/mono/sgen/sgen-major-copy-object.h @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #define collector_pin_object(obj, queue) do { \ diff --git a/mono/sgen/sgen-marksweep-drain-gray-stack.h b/mono/sgen/sgen-marksweep-drain-gray-stack.h index a0bff286fa3..ad2bb6fe272 100644 --- a/mono/sgen/sgen-marksweep-drain-gray-stack.h +++ b/mono/sgen/sgen-marksweep-drain-gray-stack.h @@ -4,18 +4,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/sgen/sgen-marksweep.c b/mono/sgen/sgen-marksweep.c index b475ef3ad79..9f4cbfc129d 100644 --- a/mono/sgen/sgen-marksweep.c +++ b/mono/sgen/sgen-marksweep.c @@ -7,18 +7,7 @@ * Copyright 2009-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-memory-governor.c b/mono/sgen/sgen-memory-governor.c index 611ae5c118f..398c36e2ab2 100644 --- a/mono/sgen/sgen-memory-governor.c +++ b/mono/sgen/sgen-memory-governor.c @@ -10,18 +10,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-memory-governor.h b/mono/sgen/sgen-memory-governor.h index 669b59734e9..4ce17f5993b 100644 --- a/mono/sgen/sgen-memory-governor.h +++ b/mono/sgen/sgen-memory-governor.h @@ -2,24 +2,7 @@ * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_MEMORY_GOVERNOR_H__ #define __MONO_SGEN_MEMORY_GOVERNOR_H__ diff --git a/mono/sgen/sgen-minor-copy-object.h b/mono/sgen/sgen-minor-copy-object.h index 49b42265c7a..a77d53b4744 100644 --- a/mono/sgen/sgen-minor-copy-object.h +++ b/mono/sgen/sgen-minor-copy-object.h @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #define collector_pin_object(obj, queue) sgen_pin_object (obj, queue); diff --git a/mono/sgen/sgen-minor-scan-object.h b/mono/sgen/sgen-minor-scan-object.h index 9b23ce4ab70..4b62a739f27 100644 --- a/mono/sgen/sgen-minor-scan-object.h +++ b/mono/sgen/sgen-minor-scan-object.h @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ extern guint64 stat_scan_object_called_nursery; diff --git a/mono/sgen/sgen-nursery-allocator.c b/mono/sgen/sgen-nursery-allocator.c index e42e3bf64aa..785f46d5645 100644 --- a/mono/sgen/sgen-nursery-allocator.c +++ b/mono/sgen/sgen-nursery-allocator.c @@ -7,18 +7,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/sgen/sgen-pinning-stats.c b/mono/sgen/sgen-pinning-stats.c index 5edccfaabec..26fcfd116af 100644 --- a/mono/sgen/sgen-pinning-stats.c +++ b/mono/sgen/sgen-pinning-stats.c @@ -3,24 +3,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-pinning.c b/mono/sgen/sgen-pinning.c index 4ed5d0a6b5b..eedd1f0343a 100644 --- a/mono/sgen/sgen-pinning.c +++ b/mono/sgen/sgen-pinning.c @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-pinning.h b/mono/sgen/sgen-pinning.h index 50d0f966ac0..00eb20dd819 100644 --- a/mono/sgen/sgen-pinning.h +++ b/mono/sgen/sgen-pinning.h @@ -4,18 +4,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_PINNING_H__ #define __MONO_SGEN_PINNING_H__ diff --git a/mono/sgen/sgen-pointer-queue.c b/mono/sgen/sgen-pointer-queue.c index 196bc301071..5fb25b0bdc5 100644 --- a/mono/sgen/sgen-pointer-queue.c +++ b/mono/sgen/sgen-pointer-queue.c @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifdef HAVE_SGEN_GC diff --git a/mono/sgen/sgen-pointer-queue.h b/mono/sgen/sgen-pointer-queue.h index 3352dab3c58..5127b5bdc1d 100644 --- a/mono/sgen/sgen-pointer-queue.h +++ b/mono/sgen/sgen-pointer-queue.h @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_POINTER_QUEUE_H__ diff --git a/mono/sgen/sgen-protocol.c b/mono/sgen/sgen-protocol.c index 963035950b3..ffc47f248de 100644 --- a/mono/sgen/sgen-protocol.c +++ b/mono/sgen/sgen-protocol.c @@ -6,18 +6,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifdef HAVE_SGEN_GC diff --git a/mono/sgen/sgen-protocol.h b/mono/sgen/sgen-protocol.h index 220418e8167..5ec3680fc5a 100644 --- a/mono/sgen/sgen-protocol.h +++ b/mono/sgen/sgen-protocol.h @@ -6,18 +6,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGENPROTOCOL_H__ diff --git a/mono/sgen/sgen-qsort.c b/mono/sgen/sgen-qsort.c index 7566bddbc1d..802dd561e9e 100644 --- a/mono/sgen/sgen-qsort.c +++ b/mono/sgen/sgen-qsort.c @@ -3,18 +3,7 @@ * * Copyright (C) 2013 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-qsort.h b/mono/sgen/sgen-qsort.h index 75577e57122..b9d0f648138 100644 --- a/mono/sgen/sgen-qsort.h +++ b/mono/sgen/sgen-qsort.h @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGENQSORT_H__ #define __MONO_SGENQSORT_H__ diff --git a/mono/sgen/sgen-scan-object.h b/mono/sgen/sgen-scan-object.h index b7f97364631..b5cbedaa92e 100644 --- a/mono/sgen/sgen-scan-object.h +++ b/mono/sgen/sgen-scan-object.h @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2013 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. * * * Scans one object, using the OBJ_XXX macros. The start of the diff --git a/mono/sgen/sgen-simple-nursery.c b/mono/sgen/sgen-simple-nursery.c index 40639d7050b..56a235aa30f 100644 --- a/mono/sgen/sgen-simple-nursery.c +++ b/mono/sgen/sgen-simple-nursery.c @@ -6,18 +6,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-split-nursery.c b/mono/sgen/sgen-split-nursery.c index 588651fbc0b..3606607809e 100644 --- a/mono/sgen/sgen-split-nursery.c +++ b/mono/sgen/sgen-split-nursery.c @@ -9,18 +9,7 @@ * Copyright 2011-2012 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-tagged-pointer.h b/mono/sgen/sgen-tagged-pointer.h index 2d55abbbcc1..8b28fde0170 100644 --- a/mono/sgen/sgen-tagged-pointer.h +++ b/mono/sgen/sgen-tagged-pointer.h @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_TAGGED_POINTER_H__ diff --git a/mono/sgen/sgen-thread-pool.c b/mono/sgen/sgen-thread-pool.c index 3371d2bfab7..f1664f6a23f 100644 --- a/mono/sgen/sgen-thread-pool.c +++ b/mono/sgen/sgen-thread-pool.c @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-thread-pool.h b/mono/sgen/sgen-thread-pool.h index 6e227521a3f..339526ca598 100644 --- a/mono/sgen/sgen-thread-pool.h +++ b/mono/sgen/sgen-thread-pool.h @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_THREAD_POOL_H__ diff --git a/mono/sgen/sgen-workers.c b/mono/sgen/sgen-workers.c index 33907204c8a..adc600a090f 100644 --- a/mono/sgen/sgen-workers.c +++ b/mono/sgen/sgen-workers.c @@ -5,18 +5,7 @@ * Copyright 2003-2010 Novell, Inc. * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/sgen/sgen-workers.h b/mono/sgen/sgen-workers.h index 61538f913aa..780d2eb6df9 100644 --- a/mono/sgen/sgen-workers.h +++ b/mono/sgen/sgen-workers.h @@ -4,18 +4,7 @@ * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * Copyright (C) 2012 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SGEN_WORKER_H__ diff --git a/mono/tests/pinvoke2.cs b/mono/tests/pinvoke2.cs index cf87dbd103e..5e0f474ec40 100644 --- a/mono/tests/pinvoke2.cs +++ b/mono/tests/pinvoke2.cs @@ -1,5 +1,6 @@ // // Copyright 2011 Xamarin Inc (http://www.xamarin.com). +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; diff --git a/mono/tests/pinvoke_ppcc.cs b/mono/tests/pinvoke_ppcc.cs index 96901791806..da90ba1c35f 100644 --- a/mono/tests/pinvoke_ppcc.cs +++ b/mono/tests/pinvoke_ppcc.cs @@ -10,7 +10,7 @@ // // Bill Seurer (seurer@linux.vnet.ibm.com) // -// (C) {Copyright holder} +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; diff --git a/mono/tests/pinvoke_ppcd.cs b/mono/tests/pinvoke_ppcd.cs index c4bafea0989..602706345e9 100644 --- a/mono/tests/pinvoke_ppcd.cs +++ b/mono/tests/pinvoke_ppcd.cs @@ -10,7 +10,7 @@ // // Bill Seurer (seurer@linux.vnet.ibm.com) // -// (C) {Copyright holder} +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; diff --git a/mono/tests/pinvoke_ppcf.cs b/mono/tests/pinvoke_ppcf.cs index a529a5331fe..a7f519e557c 100644 --- a/mono/tests/pinvoke_ppcf.cs +++ b/mono/tests/pinvoke_ppcf.cs @@ -10,7 +10,7 @@ // // Bill Seurer (seurer@linux.vnet.ibm.com) // -// (C) {Copyright holder} +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; diff --git a/mono/tests/pinvoke_ppci.cs b/mono/tests/pinvoke_ppci.cs index e7c1d395c79..34021e0b053 100644 --- a/mono/tests/pinvoke_ppci.cs +++ b/mono/tests/pinvoke_ppci.cs @@ -10,7 +10,7 @@ // // Bill Seurer (seurer@linux.vnet.ibm.com) // -// (C) {Copyright holder} +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; diff --git a/mono/tests/pinvoke_ppcs.cs b/mono/tests/pinvoke_ppcs.cs index a57a9098500..08ad1d6eccd 100644 --- a/mono/tests/pinvoke_ppcs.cs +++ b/mono/tests/pinvoke_ppcs.cs @@ -10,7 +10,7 @@ // // Bill Seurer (seurer@linux.vnet.ibm.com) // -// (C) {Copyright holder} +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; diff --git a/mono/tests/test-runner.cs b/mono/tests/test-runner.cs index 358be81312c..ae52220e335 100644 --- a/mono/tests/test-runner.cs +++ b/mono/tests/test-runner.cs @@ -6,24 +6,7 @@ // // Copyright (C) 2008 Novell, Inc (http://www.novell.com) // -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; using System.IO; diff --git a/mono/tests/verifier/AssemblyRunner.cs b/mono/tests/verifier/AssemblyRunner.cs index e66f751d24e..b4627e0d048 100644 --- a/mono/tests/verifier/AssemblyRunner.cs +++ b/mono/tests/verifier/AssemblyRunner.cs @@ -6,24 +6,7 @@ // // Copyright (C) 2007 Novell, Inc (http://www.novell.com) // -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// Licensed under the MIT license. See LICENSE file in the project root for full license information.// // using System; using System.IO; diff --git a/mono/tests/verifier/BatchCompiler.cs b/mono/tests/verifier/BatchCompiler.cs index 2233f10ce72..cb18ef67a89 100644 --- a/mono/tests/verifier/BatchCompiler.cs +++ b/mono/tests/verifier/BatchCompiler.cs @@ -6,25 +6,7 @@ // // Copyright (C) 2008 Novell, Inc (http://www.novell.com) // -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// +// Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.IO; using System.Reflection; diff --git a/mono/tests/verifier/COPYING.LIB b/mono/tests/verifier/COPYING.LIB deleted file mode 100755 index a14a1303801..00000000000 --- a/mono/tests/verifier/COPYING.LIB +++ /dev/null @@ -1,484 +0,0 @@ -These CLI bytecode verifier tests are licensed under the -terms of the GNU Library General Public License, version 2. - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/mono/unit-tests/test-conc-hashtable.c b/mono/unit-tests/test-conc-hashtable.c index c5303a1a6cd..32d859c50d5 100644 --- a/mono/unit-tests/test-conc-hashtable.c +++ b/mono/unit-tests/test-conc-hashtable.c @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/unit-tests/test-memfuncs.c b/mono/unit-tests/test-memfuncs.c index 2fb1498f609..07c33a90eff 100644 --- a/mono/unit-tests/test-memfuncs.c +++ b/mono/unit-tests/test-memfuncs.c @@ -3,18 +3,7 @@ * * Copyright (C) 2013 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/unit-tests/test-mono-handle.c b/mono/unit-tests/test-mono-handle.c index fd916a65906..3438039a4b0 100644 --- a/mono/unit-tests/test-mono-handle.c +++ b/mono/unit-tests/test-mono-handle.c @@ -5,6 +5,7 @@ * Aleksey Kliger * * Copyright 2015 Xamarin, Inc. (www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/unit-tests/test-sgen-qsort.c b/mono/unit-tests/test-sgen-qsort.c index 951b1b7321b..7cc6b627445 100644 --- a/mono/unit-tests/test-sgen-qsort.c +++ b/mono/unit-tests/test-sgen-qsort.c @@ -3,18 +3,7 @@ * * Copyright (C) 2013 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/utils/atomic.c b/mono/utils/atomic.c index 447af4e8995..b6d1e5f2055 100644 --- a/mono/utils/atomic.c +++ b/mono/utils/atomic.c @@ -505,8 +505,54 @@ InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) #elif defined (HAVE_64BIT_CMPXCHG_FALLBACK) -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/utils/atomic.c" +#if defined (TARGET_IOS) || defined (TARGET_WATCHOS) + +#ifndef __clang__ +#error "Not supported." +#endif + +gint64 +InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) +{ + return __sync_val_compare_and_swap (dest, comp, exch); +} + +#elif defined (TARGET_ANDROID) + +/* Some Android systems can't find the 64-bit CAS intrinsic at runtime, + * so we have to roll our own... + */ + +gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) __attribute__ ((naked)); + +gint64 +InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) +{ + __asm__ ( + "push {r4, r5, r6, r7}\n" + "ldrd r4, [sp, #16]\n" + "dmb sy\n" + "1:\n" + "ldrexd r6, [r0]\n" + "cmp r7, r5\n" + "cmpeq r6, r4\n" + "bne 2f\n" + "strexd r1, r2, [r0]\n" + "cmp r1, #0\n" + "bne 1b\n" + "2:\n" + "dmb sy\n" + "mov r0, r6\n" + "mov r1, r7\n" + "pop {r4, r5, r6, r7}\n" + "bx lr\n" + ); +} + +#else + +#error "Need a 64-bit CAS fallback!" + #endif #else diff --git a/mono/utils/atomic.h b/mono/utils/atomic.h index 306800cfe1d..78ab036a22b 100755 --- a/mono/utils/atomic.h +++ b/mono/utils/atomic.h @@ -6,6 +6,7 @@ * * (C) 2002 Ximian, Inc. * Copyright 2012 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef _WAPI_ATOMIC_H_ @@ -14,8 +15,15 @@ #include "config.h" #include -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/utils/atomic.h" +/* +The current Nexus 7 arm-v7a fails with: +F/MonoDroid( 1568): shared runtime initialization error: Cannot load library: reloc_library[1285]: 37 cannot locate '__sync_val_compare_and_swap_8' + +Apple targets have historically being problematic, xcode 4.6 would miscompile the intrinsic. +*/ + +#if defined (__arm__) && defined (HAVE_ARMV7) +#define HAVE_64BIT_CMPXCHG_FALLBACK /* See atomic.c in this directory. */ #endif /* On Windows, we always use the functions provided by the Windows API. */ diff --git a/mono/utils/dlmalloc.h b/mono/utils/dlmalloc.h index 074f947f291..44a8f6b7c7b 100644 --- a/mono/utils/dlmalloc.h +++ b/mono/utils/dlmalloc.h @@ -52,9 +52,21 @@ extern "C" { #define dlindependent_comalloc independent_comalloc #endif /* USE_DL_PREFIX */ -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/utils/dlmalloc.h" -#endif +#define dlcalloc mono_dlcalloc +#define dlfree mono_dlfree +#define dlmalloc mono_dlmalloc +#define dlmemalign mono_dlmemalign +#define dlrealloc mono_dlrealloc +#define dlvalloc mono_dlvalloc +#define dlpvalloc mono_dlpvalloc +#define dlmallinfo mono_dlmallinfo +#define dlmallopt mono_dlmallopt +#define dlmalloc_trim mono_dlmalloc_trim +#define dlmalloc_stats mono_dlmalloc_stats +#define dlmalloc_usable_size mono_dlmalloc_usable_size +#define dlmalloc_footprint mono_dlmalloc_footprint +#define dlindependent_calloc mono_dlindependent_calloc +#define dlindependent_comalloc mono_dlindependent_comalloc /* malloc(size_t n) diff --git a/mono/utils/gc_wrapper.h b/mono/utils/gc_wrapper.h index a90d27c064f..908bcabc512 100644 --- a/mono/utils/gc_wrapper.h +++ b/mono/utils/gc_wrapper.h @@ -1,6 +1,7 @@ /* * Copyright 2004-2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_OS_GC_WRAPPER_H__ #define __MONO_OS_GC_WRAPPER_H__ diff --git a/mono/utils/hazard-pointer.c b/mono/utils/hazard-pointer.c index df1e4cdc8e9..f5e9f73ed35 100644 --- a/mono/utils/hazard-pointer.c +++ b/mono/utils/hazard-pointer.c @@ -2,6 +2,7 @@ * hazard-pointer.c: Hazard pointer related code. * * (C) Copyright 2011 Novell, Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/hazard-pointer.h b/mono/utils/hazard-pointer.h index fa70e71bb40..ae3a1a1d887 100644 --- a/mono/utils/hazard-pointer.h +++ b/mono/utils/hazard-pointer.h @@ -2,6 +2,7 @@ * hazard-pointer.h: Hazard pointer related code. * * (C) Copyright 2011 Novell, Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_HAZARD_POINTER_H__ #define __MONO_HAZARD_POINTER_H__ diff --git a/mono/utils/json.c b/mono/utils/json.c index 2ca9ec24745..331f9038081 100644 --- a/mono/utils/json.c +++ b/mono/utils/json.c @@ -5,6 +5,7 @@ * Joao Matos (joao.matos@xamarin.com) * * Copyright 2015 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/json.h b/mono/utils/json.h index cee9c8905dc..79b26165e77 100644 --- a/mono/utils/json.h +++ b/mono/utils/json.h @@ -5,6 +5,7 @@ * Joao Matos (joao.matos@xamarin.com) * * Copyright 2015 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_UTILS_JSON_H__ diff --git a/mono/utils/lock-free-alloc.c b/mono/utils/lock-free-alloc.c index 66cb6ea3f80..b32f5926178 100644 --- a/mono/utils/lock-free-alloc.c +++ b/mono/utils/lock-free-alloc.c @@ -3,24 +3,7 @@ * * (C) Copyright 2011 Novell, Inc * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/utils/lock-free-array-queue.c b/mono/utils/lock-free-array-queue.c index 98a3f31745a..b0d0a9a1dfe 100644 --- a/mono/utils/lock-free-array-queue.c +++ b/mono/utils/lock-free-array-queue.c @@ -3,6 +3,7 @@ * require hazard pointers. * * (C) Copyright 2011 Xamarin Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/utils/lock-free-array-queue.h b/mono/utils/lock-free-array-queue.h index 620025153de..fc924a7639a 100644 --- a/mono/utils/lock-free-array-queue.h +++ b/mono/utils/lock-free-array-queue.h @@ -3,6 +3,7 @@ * require hazard pointers. * * (C) Copyright 2011 Xamarin Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_LOCK_FREE_ARRAY_QUEUE_H__ #define __MONO_LOCK_FREE_ARRAY_QUEUE_H__ diff --git a/mono/utils/memfuncs.c b/mono/utils/memfuncs.c index f657b5532ee..455ffe77ea4 100644 --- a/mono/utils/memfuncs.c +++ b/mono/utils/memfuncs.c @@ -3,18 +3,7 @@ * * Copyright (C) 2013-2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ /* diff --git a/mono/utils/memfuncs.h b/mono/utils/memfuncs.h index 51a3618e706..24cc0544474 100644 --- a/mono/utils/memfuncs.h +++ b/mono/utils/memfuncs.h @@ -3,18 +3,8 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_UTILS_MEMFUNCS_H__ diff --git a/mono/utils/mono-complex.h b/mono/utils/mono-complex.h index 798fddb263b..af13bf62b98 100644 --- a/mono/utils/mono-complex.h +++ b/mono/utils/mono-complex.h @@ -5,6 +5,7 @@ * Joao Matos (joao.matos@xamarin.com) * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) +* Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-context.c b/mono/utils/mono-context.c index 81aff561cca..632513d874f 100644 --- a/mono/utils/mono-context.c +++ b/mono/utils/mono-context.c @@ -3,6 +3,7 @@ * * * Copyright (c) 2011 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-context.h b/mono/utils/mono-context.h index 2661e657636..c1159ca723a 100644 --- a/mono/utils/mono-context.h +++ b/mono/utils/mono-context.h @@ -3,6 +3,7 @@ * * * Copyright (c) 2011 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ diff --git a/mono/utils/mono-counters.c b/mono/utils/mono-counters.c index 17170a40ed2..e0260f8ac84 100644 --- a/mono/utils/mono-counters.c +++ b/mono/utils/mono-counters.c @@ -1,6 +1,7 @@ /* * Copyright 2006-2010 Novell * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-dl-darwin.c b/mono/utils/mono-dl-darwin.c index ff7028555c1..225706c547a 100644 --- a/mono/utils/mono-dl-darwin.c +++ b/mono/utils/mono-dl-darwin.c @@ -6,6 +6,7 @@ * * Copyright 2001-2004 Ximian, Inc. * Copyright 2004-2009 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-dl-posix.c b/mono/utils/mono-dl-posix.c index 09eed6222e2..b48a1831d75 100644 --- a/mono/utils/mono-dl-posix.c +++ b/mono/utils/mono-dl-posix.c @@ -6,6 +6,7 @@ * * Copyright 2001-2004 Ximian, Inc. * Copyright 2004-2009 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-dl-windows.c b/mono/utils/mono-dl-windows.c index 19ff818f733..9e3efa796f7 100644 --- a/mono/utils/mono-dl-windows.c +++ b/mono/utils/mono-dl-windows.c @@ -6,6 +6,7 @@ * * Copyright 2001-2004 Ximian, Inc. * Copyright 2004-2009 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-dl.c b/mono/utils/mono-dl.c index aa57e04a50e..62493555a30 100644 --- a/mono/utils/mono-dl.c +++ b/mono/utils/mono-dl.c @@ -6,6 +6,7 @@ * * Copyright 2001-2004 Ximian, Inc. * Copyright 2004-2009 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" #include "mono/utils/mono-dl.h" diff --git a/mono/utils/mono-embed.c b/mono/utils/mono-embed.c index 3bb1ac6bff6..de78a84aa43 100644 --- a/mono/utils/mono-embed.c +++ b/mono/utils/mono-embed.c @@ -10,6 +10,7 @@ * Copyright 2001-2004 Ximian, Inc. * Copyright 2004-2010 Novell, Inc. * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" #include "mono/utils/mono-dl.h" diff --git a/mono/utils/mono-error.c b/mono/utils/mono-error.c index 06040202164..94c0c4fd35a 100644 --- a/mono/utils/mono-error.c +++ b/mono/utils/mono-error.c @@ -4,6 +4,7 @@ * Authors: * Rodrigo Kumpera (rkumpera@novell.com) * Copyright 2009 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-filemap.c b/mono/utils/mono-filemap.c index c559ad3185d..cd93eaff39f 100644 --- a/mono/utils/mono-filemap.c +++ b/mono/utils/mono-filemap.c @@ -5,6 +5,7 @@ * Paolo Molaro (lupus@ximian.com) * * Copyright 2008-2008 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/utils/mono-hwcap-arm.c b/mono/utils/mono-hwcap-arm.c index 2df530d824e..6cf8065d06a 100644 --- a/mono/utils/mono-hwcap-arm.c +++ b/mono/utils/mono-hwcap-arm.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-arm.h" diff --git a/mono/utils/mono-hwcap-arm64.c b/mono/utils/mono-hwcap-arm64.c index 5149cc06943..5491cff96cf 100644 --- a/mono/utils/mono-hwcap-arm64.c +++ b/mono/utils/mono-hwcap-arm64.c @@ -2,6 +2,7 @@ * mono-hwcap-arm64.c: ARM hardware feature detection * * Copyright 2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-arm64.h" diff --git a/mono/utils/mono-hwcap-ia64.c b/mono/utils/mono-hwcap-ia64.c index 226ab0d6a57..b5979862208 100644 --- a/mono/utils/mono-hwcap-ia64.c +++ b/mono/utils/mono-hwcap-ia64.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-ia64.h" diff --git a/mono/utils/mono-hwcap-mips.c b/mono/utils/mono-hwcap-mips.c index a768257ff8f..6d809a79ac5 100644 --- a/mono/utils/mono-hwcap-mips.c +++ b/mono/utils/mono-hwcap-mips.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-mips.h" diff --git a/mono/utils/mono-hwcap-ppc.c b/mono/utils/mono-hwcap-ppc.c index c88b95f6ec8..174cc620a20 100644 --- a/mono/utils/mono-hwcap-ppc.c +++ b/mono/utils/mono-hwcap-ppc.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-ppc.h" diff --git a/mono/utils/mono-hwcap-s390x.c b/mono/utils/mono-hwcap-s390x.c index d5c9d254c3c..19a7fba1101 100644 --- a/mono/utils/mono-hwcap-s390x.c +++ b/mono/utils/mono-hwcap-s390x.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-s390x.h" diff --git a/mono/utils/mono-hwcap-sparc.c b/mono/utils/mono-hwcap-sparc.c index d0456db5494..ba849873632 100644 --- a/mono/utils/mono-hwcap-sparc.c +++ b/mono/utils/mono-hwcap-sparc.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-sparc.h" diff --git a/mono/utils/mono-hwcap-x86.c b/mono/utils/mono-hwcap-x86.c index 57fff00039e..4a96aa3a088 100644 --- a/mono/utils/mono-hwcap-x86.c +++ b/mono/utils/mono-hwcap-x86.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "mono/utils/mono-hwcap-x86.h" diff --git a/mono/utils/mono-hwcap.c b/mono/utils/mono-hwcap.c index 38c032696bb..a3d2b6078bf 100644 --- a/mono/utils/mono-hwcap.c +++ b/mono/utils/mono-hwcap.c @@ -16,6 +16,7 @@ * Copyright 2006 Broadcom * Copyright 2007-2008 Andreas Faerber * Copyright 2011-2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-lazy-init.h b/mono/utils/mono-lazy-init.h index 99631f08ef6..194eadc15c9 100644 --- a/mono/utils/mono-lazy-init.h +++ b/mono/utils/mono-lazy-init.h @@ -4,6 +4,7 @@ * Authors: Ludovic Henry * * Copyright 2015 Xamarin, Inc. (www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_LAZY_INIT_H__ diff --git a/mono/utils/mono-machine.h b/mono/utils/mono-machine.h index 083f41aee33..fce4e6c2ba6 100644 --- a/mono/utils/mono-machine.h +++ b/mono/utils/mono-machine.h @@ -5,6 +5,7 @@ * Rodrigo Kumpera (kumpera@gmail.com) * * Copyright (c) 2011 Novell, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_MONO_MACHINE_H__ diff --git a/mono/utils/mono-mmap-internals.h b/mono/utils/mono-mmap-internals.h index ed6f015a647..faca70b8ca9 100644 --- a/mono/utils/mono-mmap-internals.h +++ b/mono/utils/mono-mmap-internals.h @@ -3,18 +3,7 @@ * * Copyright (C) 2014 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_UTILS_MMAP_INTERNAL_H__ diff --git a/mono/utils/mono-mmap.c b/mono/utils/mono-mmap.c index f3b4d17c77b..7fa483ce593 100644 --- a/mono/utils/mono-mmap.c +++ b/mono/utils/mono-mmap.c @@ -5,6 +5,7 @@ * Mono Team (mono-list@lists.ximian.com) * * Copyright 2001-2008 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/utils/mono-os-mutex.h b/mono/utils/mono-os-mutex.h index 536640532ef..8f7f70307c7 100644 --- a/mono/utils/mono-os-mutex.h +++ b/mono/utils/mono-os-mutex.h @@ -5,6 +5,8 @@ * Authors: Jeffrey Stedfast * * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_OS_MUTEX_H__ diff --git a/mono/utils/mono-proclib.c b/mono/utils/mono-proclib.c index dc7ba95c732..c53af96454a 100644 --- a/mono/utils/mono-proclib.c +++ b/mono/utils/mono-proclib.c @@ -1,6 +1,7 @@ /* * Copyright 2008-2011 Novell Inc * Copyright 2011 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "config.h" diff --git a/mono/utils/mono-rand.c b/mono/utils/mono-rand.c index d1e4bb2c496..1e8297750bf 100644 --- a/mono/utils/mono-rand.c +++ b/mono/utils/mono-rand.c @@ -10,6 +10,7 @@ * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2001 Xamarin, Inc (http://www.novell.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ diff --git a/mono/utils/mono-signal-handler.h b/mono/utils/mono-signal-handler.h index 94335964cd0..9e0b072a1a5 100644 --- a/mono/utils/mono-signal-handler.h +++ b/mono/utils/mono-signal-handler.h @@ -2,6 +2,7 @@ * mono-signal-handler.h: Handle signal handler differences across platforms * * Copyright (C) 2013 Xamarin Inc + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_SIGNAL_HANDLER_H__ diff --git a/mono/utils/mono-stack-unwinding.h b/mono/utils/mono-stack-unwinding.h index 456cb31bb3e..123f40ba2ad 100644 --- a/mono/utils/mono-stack-unwinding.h +++ b/mono/utils/mono-stack-unwinding.h @@ -1,6 +1,7 @@ /* * Copyright 2008-2010 Novell, Inc. * Copyright 2011 Xamarin Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_MONO_STACK_UNWINDING_H__ #define __MONO_MONO_STACK_UNWINDING_H__ diff --git a/mono/utils/mono-threads-android.c b/mono/utils/mono-threads-android.c index a72ee81a560..fa82387f26f 100644 --- a/mono/utils/mono-threads-android.c +++ b/mono/utils/mono-threads-android.c @@ -2,8 +2,55 @@ #if defined(PLATFORM_ANDROID) -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/utils/mono-threads-android.c" -#endif +#include +#include +#include +#include "glib.h" + +static void +slow_get_thread_bounds (guint8 *current, guint8 **staddr, size_t *stsize) +{ + char buff [1024]; + FILE *f = fopen ("/proc/self/maps", "r"); + if (!f) + g_error ("Could not determine thread bounds, failed to open /proc/self/maps"); + + while (fgets (buff, sizeof (buff), f)) { + intmax_t low, high; + char *ptr = buff; + char *end = NULL; + //each line starts with the range we want: f7648000-f7709000 + low = strtoimax (ptr, &end, 16); + if (end) { + ptr = end + 1; //skip the dash to make sure we don't get a negative number + end = NULL; + high = strtoimax (ptr, &end, 16); + } + if (end && low <= (intmax_t)(size_t)current && high > (intmax_t)(size_t)current) { + *staddr = (guint8 *)(size_t)low; + *stsize = (size_t)(high - low); + fclose (f); + return; + } + } + g_error ("Could not determine thread bounds, failed to find current stack pointer in /proc/self/maps"); +} + +void +mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize) +{ + pthread_attr_t attr; + guint8 *current = (guint8*)&attr; + + *staddr = NULL; + *stsize = (size_t)-1; + + pthread_getattr_np (pthread_self (), &attr); + pthread_attr_getstack (&attr, (void**)staddr, stsize); + pthread_attr_destroy (&attr); + + if (*staddr && ((current <= *staddr) || (current > *staddr + *stsize))) + slow_get_thread_bounds (current, staddr, stsize); +} #endif diff --git a/mono/utils/mono-threads-coop.c b/mono/utils/mono-threads-coop.c index 20740b3dcd1..4283537b0f9 100644 --- a/mono/utils/mono-threads-coop.c +++ b/mono/utils/mono-threads-coop.c @@ -5,6 +5,7 @@ * Rodrigo Kumpera (kumpera@gmail.com) * * Copyright 2015 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index 5d08308885a..21fae2f6078 100644 --- a/mono/utils/mono-threads.c +++ b/mono/utils/mono-threads.c @@ -6,6 +6,7 @@ * * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-time.c b/mono/utils/mono-time.c index 3c940e73ddf..5f0168ebb74 100644 --- a/mono/utils/mono-time.c +++ b/mono/utils/mono-time.c @@ -2,6 +2,7 @@ * Time utility functions. * Author: Paolo Molaro () * Copyright (C) 2008 Novell, Inc. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/mono-tls.h b/mono/utils/mono-tls.h index 0b6cd5a1a1c..565b3fe593b 100644 --- a/mono/utils/mono-tls.h +++ b/mono/utils/mono-tls.h @@ -6,6 +6,7 @@ * * Copyright 2011 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin, Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_TLS_H__ diff --git a/mono/utils/parse.c b/mono/utils/parse.c index 0c44c3f6bfa..0bf17f6727b 100644 --- a/mono/utils/parse.c +++ b/mono/utils/parse.c @@ -3,18 +3,7 @@ * * Copyright (C) 2015 Xamarin Inc * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include diff --git a/mono/utils/parse.h b/mono/utils/parse.h index a899908baad..e2b4a83f39a 100644 --- a/mono/utils/parse.h +++ b/mono/utils/parse.h @@ -1,20 +1,7 @@ /* * parse.h: Parsing for GC options. * - * Copyright (C) 2015 Xamarin Inc - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License 2.0 as published by the Free Software Foundation; - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License 2.0 along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #ifndef __MONO_UTILS_PARSE_H__