diff --git a/hotspot/.hgignore b/hotspot/.hgignore
new file mode 100644
index 00000000000..8c4cff4cd1f
--- /dev/null
+++ b/hotspot/.hgignore
@@ -0,0 +1,170 @@
+^build/solaris/solaris_sparc_compiler1/
+^build/solaris/solaris_sparc_compiler2/
+^build/solaris/solaris_sparc_core/
+^build/solaris/solaris_sparc_kernel/
+^build/solaris/solaris_sparc_docs/
+^build/solaris/jdk-solaris-sparc/
+^build/solaris/export-solaris-sparc/
+^build/solaris/solaris_sparcv9_compiler1/
+^build/solaris/solaris_sparcv9_compiler2/
+^build/solaris/solaris_sparcv9_core/
+^build/solaris/solaris_sparcv9_kernel/
+^build/solaris/solaris_sparcv9_docs/
+^build/solaris/jdk-solaris-sparcv9/
+^build/solaris/export-solaris-sparcv9/
+^build/solaris/solaris_sparc32_compiler1/
+^build/solaris/solaris_sparc32_compiler2/
+^build/solaris/solaris_sparc32_core/
+^build/solaris/solaris_sparc32_kernel/
+^build/solaris/solaris_sparc32_docs/
+^build/solaris/jdk-solaris-sparc32/
+^build/solaris/export-solaris-sparc32/
+^build/solaris/solaris_sparc64_compiler1/
+^build/solaris/solaris_sparc64_compiler2/
+^build/solaris/solaris_sparc64_core/
+^build/solaris/solaris_sparc64_kernel/
+^build/solaris/solaris_sparc64_docs/
+^build/solaris/jdk-solaris-sparc64/
+^build/solaris/export-solaris-sparc64/
+^build/solaris/solaris_i486_compiler1/
+^build/solaris/solaris_i486_compiler2/
+^build/solaris/solaris_i486_core/
+^build/solaris/solaris_i486_kernel/
+^build/solaris/solaris_i486_docs/
+^build/solaris/jdk-solaris-i486/
+^build/solaris/export-solaris-i486/
+^build/solaris/solaris_i386_compiler1/
+^build/solaris/solaris_i386_compiler2/
+^build/solaris/solaris_i386_core/
+^build/solaris/solaris_i386_kernel/
+^build/solaris/solaris_i386_docs/
+^build/solaris/jdk-solaris-i386/
+^build/solaris/export-solaris-i386/
+^build/solaris/solaris_amd64_compiler1/
+^build/solaris/solaris_amd64_compiler2/
+^build/solaris/solaris_amd64_core/
+^build/solaris/solaris_amd64_kernel/
+^build/solaris/solaris_amd64_docs/
+^build/solaris/jdk-solaris-amd64/
+^build/solaris/export-solaris-amd64/
+^build/solaris/solaris_x64_compiler1/
+^build/solaris/solaris_x64_compiler2/
+^build/solaris/solaris_x64_core/
+^build/solaris/solaris_x64_kernel/
+^build/solaris/solaris_x64_docs/
+^build/solaris/jdk-solaris-x64/
+^build/solaris/export-solaris-x64/
+^build/windows/windows_sparc_compiler1/
+^build/windows/windows_sparc_compiler2/
+^build/windows/windows_sparc_core/
+^build/windows/windows_sparc_kernel/
+^build/windows/windows_sparc_docs/
+^build/windows/jdk-windows-sparc/
+^build/windows/export-windows-sparc/
+^build/windows/windows_sparcv9_compiler1/
+^build/windows/windows_sparcv9_compiler2/
+^build/windows/windows_sparcv9_core/
+^build/windows/windows_sparcv9_kernel/
+^build/windows/windows_sparcv9_docs/
+^build/windows/jdk-windows-sparcv9/
+^build/windows/export-windows-sparcv9/
+^build/windows/windows_sparc32_compiler1/
+^build/windows/windows_sparc32_compiler2/
+^build/windows/windows_sparc32_core/
+^build/windows/windows_sparc32_kernel/
+^build/windows/windows_sparc32_docs/
+^build/windows/jdk-windows-sparc32/
+^build/windows/export-windows-sparc32/
+^build/windows/windows_sparc64_compiler1/
+^build/windows/windows_sparc64_compiler2/
+^build/windows/windows_sparc64_core/
+^build/windows/windows_sparc64_kernel/
+^build/windows/windows_sparc64_docs/
+^build/windows/jdk-windows-sparc64/
+^build/windows/export-windows-sparc64/
+^build/windows/windows_i486_compiler1/
+^build/windows/windows_i486_compiler2/
+^build/windows/windows_i486_core/
+^build/windows/windows_i486_kernel/
+^build/windows/windows_i486_docs/
+^build/windows/jdk-windows-i486/
+^build/windows/export-windows-i486/
+^build/windows/windows_i386_compiler1/
+^build/windows/windows_i386_compiler2/
+^build/windows/windows_i386_core/
+^build/windows/windows_i386_kernel/
+^build/windows/windows_i386_docs/
+^build/windows/jdk-windows-i386/
+^build/windows/export-windows-i386/
+^build/windows/windows_amd64_compiler1/
+^build/windows/windows_amd64_compiler2/
+^build/windows/windows_amd64_core/
+^build/windows/windows_amd64_kernel/
+^build/windows/windows_amd64_docs/
+^build/windows/jdk-windows-amd64/
+^build/windows/export-windows-amd64/
+^build/windows/windows_x64_compiler1/
+^build/windows/windows_x64_compiler2/
+^build/windows/windows_x64_core/
+^build/windows/windows_x64_kernel/
+^build/windows/windows_x64_docs/
+^build/windows/jdk-windows-x64/
+^build/windows/export-windows-x64/
+^build/linux/linux_sparc_compiler1/
+^build/linux/linux_sparc_compiler2/
+^build/linux/linux_sparc_core/
+^build/linux/linux_sparc_kernel/
+^build/linux/linux_sparc_docs/
+^build/linux/jdk-linux-sparc/
+^build/linux/export-linux-sparc/
+^build/linux/linux_sparcv9_compiler1/
+^build/linux/linux_sparcv9_compiler2/
+^build/linux/linux_sparcv9_core/
+^build/linux/linux_sparcv9_kernel/
+^build/linux/linux_sparcv9_docs/
+^build/linux/jdk-linux-sparcv9/
+^build/linux/export-linux-sparcv9/
+^build/linux/linux_sparc32_compiler1/
+^build/linux/linux_sparc32_compiler2/
+^build/linux/linux_sparc32_core/
+^build/linux/linux_sparc32_kernel/
+^build/linux/linux_sparc32_docs/
+^build/linux/jdk-linux-sparc32/
+^build/linux/export-linux-sparc32/
+^build/linux/linux_sparc64_compiler1/
+^build/linux/linux_sparc64_compiler2/
+^build/linux/linux_sparc64_core/
+^build/linux/linux_sparc64_kernel/
+^build/linux/linux_sparc64_docs/
+^build/linux/jdk-linux-sparc64/
+^build/linux/export-linux-sparc64/
+^build/linux/linux_i486_compiler1/
+^build/linux/linux_i486_compiler2/
+^build/linux/linux_i486_core/
+^build/linux/linux_i486_kernel/
+^build/linux/linux_i486_docs/
+^build/linux/jdk-linux-i486/
+^build/linux/export-linux-i486/
+^build/linux/linux_i386_compiler1/
+^build/linux/linux_i386_compiler2/
+^build/linux/linux_i386_core/
+^build/linux/linux_i386_kernel/
+^build/linux/linux_i386_docs/
+^build/linux/jdk-linux-i386/
+^build/linux/export-linux-i386/
+^build/linux/linux_amd64_compiler1/
+^build/linux/linux_amd64_compiler2/
+^build/linux/linux_amd64_core/
+^build/linux/linux_amd64_kernel/
+^build/linux/linux_amd64_docs/
+^build/linux/jdk-linux-amd64/
+^build/linux/export-linux-amd64/
+^build/linux/linux_x64_compiler1/
+^build/linux/linux_x64_compiler2/
+^build/linux/linux_x64_core/
+^build/linux/linux_x64_kernel/
+^build/linux/linux_x64_docs/
+^build/linux/jdk-linux-x64/
+^build/linux/export-linux-x64/
+^dist/
+^nbproject/private/
diff --git a/hotspot/ASSEMBLY_EXCEPTION b/hotspot/ASSEMBLY_EXCEPTION
new file mode 100644
index 00000000000..8b7ac1d0813
--- /dev/null
+++ b/hotspot/ASSEMBLY_EXCEPTION
@@ -0,0 +1,27 @@
+
+OPENJDK ASSEMBLY EXCEPTION
+
+The OpenJDK source code made available by Sun at openjdk.java.net and
+openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the
+GNU General Public License version 2
+only ("GPL2"), with the following clarification and special exception.
+
+ Linking this OpenJDK Code statically or dynamically with other code
+ is making a combined work based on this library. Thus, the terms
+ and conditions of GPL2 cover the whole combination.
+
+ As a special exception, Sun gives you permission to link this
+ OpenJDK Code with certain code licensed by Sun as indicated at
+ http://openjdk.java.net/legal/exception-modules-2007-05-08.html
+ ("Designated Exception Modules") to produce an executable,
+ regardless of the license terms of the Designated Exception Modules,
+ and to copy and distribute the resulting executable under GPL2,
+ provided that the Designated Exception Modules continue to be
+ governed by the licenses under which they were offered by Sun.
+
+As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to
+build an executable that includes those portions of necessary code that Sun
+could not provide under GPL2 (or that Sun has provided under GPL2 with the
+Classpath exception). If you modify or add to the OpenJDK code, that new
+GPL2 code may still be combined with Designated Exception Modules if the
+new code is made subject to this exception by its copyright holder.
diff --git a/hotspot/LICENSE b/hotspot/LICENSE
new file mode 100644
index 00000000000..eeab58c21c9
--- /dev/null
+++ b/hotspot/LICENSE
@@ -0,0 +1,347 @@
+The GNU General Public License (GPL)
+
+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.
+
+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.
+
+ One line to give the program's name and a brief idea of what it does.
+
+ 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.
+
+ signature of Ty Coon, 1 April 1989
+
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General Public
+License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL
+
+Certain source files distributed by Sun Microsystems, Inc. are subject to
+the following clarification and special exception to the GPL, but only where
+Sun has expressly included in the particular source file's header the words
+"Sun designates this particular file as subject to the "Classpath" exception
+as provided by Sun in the LICENSE file that accompanied this code."
+
+ Linking this library statically or dynamically with other modules is making
+ a combined work based on this library. Thus, the terms and conditions of
+ the GNU General Public License cover the whole combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,
+ and to copy and distribute the resulting executable under terms of your
+ choice, provided that you also meet, for each linked independent module,
+ the terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library. If
+ you modify this library, you may extend this exception to your version of
+ the library, but you are not obligated to do so. If you do not wish to do
+ so, delete this exception statement from your version.
diff --git a/hotspot/README b/hotspot/README
new file mode 100644
index 00000000000..19afb261fc3
--- /dev/null
+++ b/hotspot/README
@@ -0,0 +1,14 @@
+README:
+ This file should be located at the top of the hotspot Mercurial repository.
+
+ See http://openjdk.java.net/ for more information about the OpenJDK.
+
+ See ../README-builds.html for complete details on build machine requirements.
+
+Simple Build Instructions:
+
+ cd make && gnumake
+
+ The files that will be imported into the jdk build will be in the "build"
+ directory.
+
diff --git a/hotspot/THIRD_PARTY_README b/hotspot/THIRD_PARTY_README
new file mode 100644
index 00000000000..9f4d7e5087a
--- /dev/null
+++ b/hotspot/THIRD_PARTY_README
@@ -0,0 +1,1616 @@
+DO NOT TRANSLATE OR LOCALIZE.
+
+%% This notice is provided with respect to Thai dictionary for text breaking, which may be included with this software:
+
+--- begin of LICENSE file ---
+
+Copyright (C) 1982 The Royal Institute, Thai Royal Government.
+
+Copyright (C) 1998 National Electronics and Computer Technology Center,
+ National Science and Technology Development Agency,
+ Ministry of Science Technology and Environment,
+ Thai Royal Government.
+
+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.
+
+--- end of LICENSE file ---
+%% This notice is provided with respect to ASM, which may be included with this software:
+Copyright (c) 2000-2005 INRIA, France Telecom
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+%% This notice is provided with respect to zlib 1.1.3, which may be included with this software:
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of 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 following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes.
+
+%% This notice is provided with respect to W3C (DTD for XML Signatures), which may be included with this software:
+W3C® SOFTWARE NOTICE AND LICENSE
+Copyright © 1994-2002 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/
+This W3C work (including software, documents, or other related items) is being provided by the copyright holders under the following license. By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
+Permission to use, copy, modify, and distribute this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make:
+1.The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.
+2.Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: "Copyright © [$date-of-software] World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/"
+3.Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.
+____________________________________
+This formulation of W3C's notice and license became active on August 14 1998 so as to improve compatibility with GPL. This version ensures that W3C software licensing terms are no more restrictive than GPL and consequently W3C software may be distributed in GPL packages. See the older formulation for the policy prior to this date. Please see our Copyright FAQ for common questions about using materials from our site, including specific terms and conditions for packages like libwww, Amaya, and Jigsaw. Other questions about this notice can be directed to site-policy@w3.org.
+
+%% This notice is provided with respect to jscheme.jar, which may be included with this software:
+Software License Agreement
+Copyright © 1998-2002 by Peter Norvig.
+Permission is granted to anyone to use this software, in source or object code form, on any computer system, and to modify, compile, decompile, run, and redistribute it to anyone else, subject to the following restrictions:
+1.The author makes no warranty of any kind, either expressed or implied, about the suitability of this software for any purpose.
+2.The author accepts no liability of any kind for damages or other consequences of the use of this software, even if they arise from defects in the software.
+3.The origin of this software must not be misrepresented, either by explicit claim or by omission.
+4.Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Altered versions may be distributed in packages under other licenses (such as the GNU license).
+If you find this software useful, it would be nice if you let me (peter@norvig.com) know about it, and nicer still if you send me modifications that you are willing to share. However, you are not required to do so.
+
+
+%% This notice is provided with respect to PC/SC Lite for Suse Linux v. 1.1.1, which may be included with this software:
+
+Copyright (c) 1999-2004 David Corcoran
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+Changes to this license can be made only by the copyright author with
+explicit written consent.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+%% This notice is provided with respect to IAIK PKCS Wrapper, which may be included with this software:
+
+Copyright (c) 2002 Graz University of Technology. All rights reserved.
+Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met:
+
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment:
+
+ "This product includes software developed by IAIK of Graz University of Technology."
+
+ Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear.
+
+4. The names "Graz University of Technology" and "IAIK of Graz University of Technology" must not be used to endorse or promote products derived from this software without prior written permission.
+
+5. Products derived from this software may not be called "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior written permission of Graz University of Technology.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+%% This notice is provided with respect to Document Object Model (DOM) v. Level 3, which may be included with this software:
+
+W3Cýý SOFTWARE NOTICE AND LICENSE
+
+http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other related items) is being
+provided by the copyright holders under the following license. By obtaining, using and/or copying this work, you
+(the licensee) agree that you have read, understood, and will comply with the following terms and conditions.
+
+Permission to copy, modify, and distribute this software and its documentation, with or without modification, for
+any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies
+of the software and documentation or portions thereof, including modifications:
+ 1.The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.
+ 2.Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, the
+ W3C Software Short Notice should be included (hypertext is preferred, text is permitted) within the body
+ of any redistributed or derivative code.
+ 3.Notice of any changes or modifications to the files, including the date changes were made. (We
+ recommend you provide URIs to the location from which the code is derived.)
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKENO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
+WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THEUSE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS,COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL ORCONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the
+software without specific, written prior permission. Title to copyright in this software and any associated
+documentation will at all times remain with copyright holders.
+
+____________________________________
+
+This formulation of W3C's notice and license became active on December 31 2002. This version removes the
+copyright ownership notice such that this license can be used with materials other than those owned by the
+W3C, reflects that ERCIM is now a host of the W3C, includes references to this specific dated version of the
+license, and removes the ambiguous grant of "use". Otherwise, this version is the same as the previous
+version and is written so as to preserve the Free Software Foundation's assessment of GPL compatibility and
+OSI's certification under the Open Source Definition. Please see our Copyright FAQ for common questions
+about using materials from our site, including specific terms and conditions for packages like libwww, Amaya,
+and Jigsaw. Other questions about this notice can be directed to
+site-policy@w3.org.
+
+%% This notice is provided with respect to Xalan, Xerces, which may be included with this software:
+
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation. All rights * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. *
+ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. *
+ * 4. The names "Xerces" and "Apache Software Foundation" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * nor may "Apache" appear in their name, without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ==================================================================== *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, International
+ * Business Machines, Inc., http://www.ibm.com. For more
+ * information on the Apache Software Foundation, please see
+ *
+
+%% This notice is provided with respect to JavaScript, which may be included with this software:
+
+AMENDMENTS
+The Netscape Public License Version 1.1 ("NPL") consists of the Mozilla Public License Version 1.1 with the following Amendments, including Exhibit A-Netscape Public License. Files identified with "Exhibit A-Netscape Public License" are governed by the Netscape Public License Version 1.1.
+Additional Terms applicable to the Netscape Public License.
+I. Effect.
+These additional terms described in this Netscape Public License -- Amendments shall apply to the Mozilla Communicator client code and to all Covered Code under this License.
+II. ''Netscape's Branded Code'' means Covered Code that Netscape distributes and/or permits others to distribute under one or more trademark(s) which are controlled by Netscape but which are not licensed for use under this License.
+III. Netscape and logo.
+This License does not grant any rights to use the trademarks "Netscape'', the "Netscape N and horizon'' logo or the "Netscape lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", "Smart Browsing" even if such marks are included in the Original Code or Modifications.
+IV. Inability to Comply Due to Contractual Obligation.
+Prior to licensing the Original Code under this License, Netscape has licensed third party code for use in Netscape's Branded Code. To the extent that Netscape is limited contractually from making such third party code available under this License, Netscape may choose to reintegrate such code into Covered Code without being required to distribute such code in Source Code form, even if such code would otherwise be considered ''Modifications'' under this License.
+V. Use of Modifications and Covered Code by Initial Developer.
+V.1. In General.
+The obligations of Section 3 apply to Netscape, except to the extent specified in this Amendment, Section V.2 and V.3.
+V.2. Other Products.
+Netscape may include Covered Code in products other than the Netscape's Branded Code which are released by Netscape during the two (2) years following the release date of the Original Code, without such additional products becoming subject to the terms of this License, and may license such additional products on different terms from those contained in this License.
+V.3. Alternative Licensing.
+Netscape may license the Source Code of Netscape's Branded Code, including Modifications incorporated therein, without such Netscape Branded Code becoming subject to the terms of this License, and may license such Netscape Branded Code on different terms from those contained in this License.
+
+VI. Litigation.
+Notwithstanding the limitations of Section 11 above, the provisions regarding litigation in Section 11(a), (b) and (c) of the License shall apply to all disputes relating to this License.
+
+EXHIBIT A-Netscape Public License.
+
+''The contents of this file are subject to the Netscape 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/NPL/
+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 Mozilla Communicator client code, released March 31, 1998.
+The Initial Developer of the Original Code is Netscape Communications Corporation. Portions created by Netscape are Copyright (C) 1998-1999 Netscape Communications Corporation. 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 NPL, 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 NPL or the [___] License."
+
+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.]
+
+%% This notice is provided with respect to Mesa 3-D graphics library v. 5, which may be included with this software:
+
+Copyright (c) 2007 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are 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 Materials.
+
+THE MATERIALS ARE 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
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+%% This notice is provided with respect to Byte Code Engineering Library (BCEL), which may be included with this software:
+
+ Apache Software License
+
+ /*
+==================================================================== * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001 The Apache Software Foundation. Allrights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, withor without
+ * modification, are permitted provided that the followingconditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the abovecopyright
+ * notice, this list of conditions and the followingdisclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce theabove copyright
+ * notice, this list of conditions and the followingdisclaimer in
+ * the documentation and/or other materials providedwith the
+ * distribution.
+ *
+ * 3. The end-user documentation included with theredistribution,
+ * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation
+(http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in thesoftware itself,
+ * if and wherever such third-party acknowledgmentsnormally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation"and
+ * "Apache BCEL" must not be used to endorse or promoteproducts
+ * derived from this software without prior writtenpermission. For
+ * written permission, please contact apache@apache.org. *
+ * 5. Products derived from this software may not be called"Apache",
+ * "Apache BCEL", nor may "Apache" appear in their name,without
+ * prior written permission of the Apache SoftwareFoundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED ORIMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWAREFOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVERCAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING INANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+==================================================================== *
+ * This software consists of voluntary contributions madeby many
+ * individuals on behalf of the Apache Software
+Foundation. For more
+ * information on the Apache Software Foundation, pleasesee
+ * .
+ */
+
+%% This notice is provided with respect to Regexp, Regular Expression Package, which may be included with this software:
+
+The Apache Software License, Version 1.1
+Copyright (c) 2001 The Apache Software Foundation. All rights
+reserved.
+Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+
+3. The end-user documentation included with the redistribution,
+if any, must include the following acknowledgment:
+"This product includes software developed by the
+Apache Software Foundation (http://www.apache.org/)."
+Alternately, this acknowledgment may appear in the software itself,
+if and wherever such third-party acknowledgments normally appear.
+
+4. The names "Apache" and "Apache Software Foundation" and
+"Apache Turbine" must not be used to endorse or promote products
+derived from this software without prior written permission. For
+written permission, please contact apache@apache.org.
+
+5. Products derived from this software may not be called "Apache",
+"Apache Turbine", nor may "Apache" appear in their name, without
+prior written permission of the Apache Software Foundation.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+====================================================================
+This software consists of voluntary contributions made by many
+individuals on behalf of the Apache Software Foundation. For more
+information on the Apache Software Foundation, please see
+
+http://www.apache.org.
+
+%% This notice is provided with respect to CUP Parser Generator for Java, which may be included with this software:
+
+CUP Parser Generator Copyright Notice, License, and Disclaimer
+
+Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided thatthe above copyright notice appear in all copies and that both the copyrightnotice and this permission notice and warranty disclaimer appear in
+supporting documentation, and that the names of the authors or their employersnot be used in advertising or publicity pertaining to distribution of
+the software without specific, written prior permission.
+
+The authors and their employers disclaim all warranties with regard to thissoftware, including all implied warranties of merchantability and
+fitness. In no event shall the authors or their employers be liable for anyspecial, indirect or consequential damages or any damages whatsoever
+resulting from loss of use, data or profits, whether in an action of contract,negligence or other tortious action, arising out of or in connection withthe use or performance of this software.
+
+%% This notice is provided with respect to SAX v. 2.0.1, which may be included with this software:
+
+Copyright Status
+
+ SAX is free!
+
+ In fact, it's not possible to own a license to SAX, since it's been placed in the public
+ domain.
+
+ No Warranty
+
+ Because SAX is released to the public domain, there is no warranty for the design or for
+ the software implementation, to the extent permitted by applicable law. Except when
+ otherwise stated in writing the copyright holders and/or other parties provide SAX "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 SAX is with you. Should SAX prove defective, you
+ assume the cost of all necessary servicing, repair or correction.
+
+ 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 SAX, be liable to you for
+ damages, including any general, special, incidental or consequential damages arising out of
+ the use or inability to use SAX (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 SAX to
+ operate with any other programs), even if such holder or other party has been advised of
+ the possibility of such damages.
+
+ Copyright Disclaimers
+
+ This page includes statements to that effect by David Megginson, who would have been
+ able to claim copyright for the original work.
+ SAX 1.0
+
+ Version 1.0 of the Simple API for XML (SAX), created collectively by the membership of
+ the XML-DEV mailing list, is hereby released into the public domain.
+
+ No one owns SAX: you may use it freely in both commercial and non-commercial
+ applications, bundle it with your software distribution, include it on a CD-ROM, list the
+ source code in a book, mirror the documentation at your own web site, or use it in any
+ other way you see fit.
+
+ David Megginson, sax@megginson.com
+ 1998-05-11
+
+ SAX 2.0
+
+ I hereby abandon any property rights to SAX 2.0 (the Simple API for XML), and release
+ all of the SAX 2.0 source code, compiled code, and documentation contained in this
+ distribution into the Public Domain. SAX comes with NO WARRANTY or guarantee of
+ fitness for any purpose.
+
+ David Megginson, david@megginson.com
+ 2000-05-05
+
+%% This notice is provided with respect to Cryptix, which may be included with this software:
+
+Cryptix General License
+
+Copyright © 1995-2003 The Cryptix Foundation Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions aremet:
+
+ 1.Redistributions of source code must retain the copyright notice, this list of conditions and the following disclaimer. 2.Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE CRYPTIX FOUNDATION LIMITED AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS ORIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FORA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CRYPTIX FOUNDATION LIMITED OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOTLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OFTHE POSSIBILITY OF SUCH DAMAGE.
+
+%% This notice is provided with respect to X Window System, which may be included with this software:
+
+Copyright The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and itsdocumentation for any purpose is hereby granted without fee, provided that theabove copyright notice appear in all copies and that both that copyright noticeand this permission notice appear in supporting documentation.
+
+The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESSFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUPBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OFCONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THESOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group.
+
+Portions also covered by other licenses as noted in the above URL.
+
+%% This notice is provided with respect to Retroweaver, which may be included with this software:
+
+Copyright (c) February 2004, Toby Reyelts
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+Neither the name of Toby Reyelts nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+%% This notice is provided with respect to stripper, which may be included with this software:
+
+Stripper : debug information stripper
+ Copyright (c) 2003 Kohsuke Kawaguchi
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holders nor the names of its
+ contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+%% This notice is provided with respect to libpng official PNG reference library, which may be included with this software:
+
+This copy of the libpng notices is provided for your convenience. In case ofany discrepancy between this copy and the notices in the file png.h that isincluded in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately followingthis sentence.
+
+libpng version 1.2.6, December 3, 2004, is
+Copyright (c) 2004 Glenn Randers-Pehrson, and is
+distributed according to the same disclaimer and license as libpng-1.2.5with the following individual added to the list of Contributing Authors
+ Cosmin Truta
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, areCopyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6with the following individuals added to the list of Contributing Authors
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, areCopyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,with the following individuals added to the list of Contributing Authors:
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,with the following individuals added to the list of Contributing Authors:
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authorsand Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and offitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute thissource code, or portions hereof, for any purpose, without fee, subjectto the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, withoutfee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use thissource code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is acertification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+December 3, 2004
+
+%% This notice is provided with respect to Libungif - An uncompressed GIF library, which may be included with this software:
+
+The GIFLIB distribution is Copyright (c) 1997 Eric S. Raymond
+
+Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies 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 inall copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, 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 INTHE SOFTWARE.
+
+%% This notice is provided with respect to XML Resolver library, Xalan J2, and StAX API, which may be included with this software:
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+ "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+ "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+
+%% Some Portions licensed from IBM are available at:
+http://www.ibm.com/software/globalization/icu/
+
+%% This notice is provided with respect to ICU4J, ICU 1.8.1 and later, which may be included with this software:
+
+ICU License - ICU 1.8.1 and later COPYRIGHT AND PERMISSION NOTICE Cop
+yright (c)
+1995-2003 International Business Machines Corporation and others All rightsreserved. Permission is hereby granted, free of charge, to any person obtaininga copy of this software and associated documentation files (the "Software"), todeal in the Software without restriction, including without limitation therights to use, copy, modify, merge, publish, distribute, and/or sell copies ofthe Software, and to permit persons to whom the Software is furnished to do so,provided that the above copyright notice(s) and this permission notice appear inall copies of the Software and that both the above copyright notice(s) and thispermission notice appear in supporting documentation. THE SOFTWARE IS PROVIDED"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOTLIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSEAND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHTHOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY C
+ LAIM, OR ANYSPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTINGFROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCEOR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE ORPERFORMANCE OF THIS SOFTWARE. Except as contained in this notice, the name of acopyright holder shall not be used in advertising or otherwise to promote thesale, use or other dealings in this Software without prior written authorizationof the copyright holder.
+
+%% This notice is provided with respect to Jing, which may be included with this software:
+
+Jing Copying Conditions
+
+Copyright (c) 2001-2003 Thai Open Source Software Center Ltd
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,this list of conditions and the following disclaimer in the documentation and/orother materials provided with the distribution.
+ * Neither the name of the Thai Open Source Software Center Ltd nor the namesof its contributors may be used to endorse or promote products derived from thissoftware without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ANDANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AREDISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ONANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+%% This notice is provided with respect to RELAX NG Object Model/Parser, which may be included with this software:
+
+
+The MIT License
+
+Copyright (c)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy ofthis software and associated documentation files (the "Software"), to deal inthe Software without restriction, including without limitation the rights touse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies ofthe 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 allcopies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESSFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS ORCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHERIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+%% This notice is provided with respect to XFree86-VidMode Extension, which may be included with this software:
+
+Version 1.1 of XFree86 ProjectLicence.
+
+ Copyright (C) 1994-2004 The XFree86 Project, Inc. All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to deal inthe Software without restriction, including without limitation the rights touse, copy, modify, merge, publish, distribute, sublicence, and/or sell copies ofthe Software, and to permit persons to whom the Software is furnished to do so,subject to the following conditions:
+
+ 1. Redistributions of source code must retain the above copyright notice,this list of conditions, and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyrightnotice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution, and in thesame place and form as other copyright, license and disclaimer information. 3. The end-user documentation included with the redistribution, if any,must include the following acknowledgment: "This product includes softwaredeveloped by The XFree86 Project, Inc (http://www.xfree86.org/) and itscontributors", in the same place and form as other third-party acknowledgments.Alternately, this acknowledgment may appear in the software itself, in the sameform and location as other such third-party acknowledgments.
+ 4. Except as contained in this notice, the name of The XFree86 Project,Inc shall not be used in advertising or otherwise to promote the sale, use orother dealings in this Software without prior written authorization from TheXFree86 Project, Inc.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ANDFITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE XFREE86PROJECT, INC OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ORBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISINGIN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITYOF SUCH DAMAGE.
+
+%% This notice is provided with respect to XML Security, which may be included with this software:
+
+ The Apache Software License,
+ Version 1.1
+
+
+ PDF
+
+
+ Copyright (C) 2002 The Apache SoftwareFoundation.
+ All rights reserved. Redistribution anduse in
+ source and binary forms, with or withoutmodifica-
+ tion, are permitted provided that thefollowing
+ conditions are met: 1. Redistributions ofsource
+ code must retain the above copyrightnotice, this
+ list of conditions and the followingdisclaimer.
+ 2. Redistributions in binary form mustreproduce
+ the above copyright notice, this list of conditions and the following disclaimerin the
+ documentation and/or other materialsprovided with
+ the distribution. 3. The end-userdocumentation
+ included with the redistribution, if any,must
+ include the following acknowledgment:"This
+ product includes software developed bythe Apache
+ Software Foundation
+(http://www.apache.org/)."
+ Alternately, this acknowledgment mayappear in the
+ software itself, if and wherever suchthird-party
+ acknowledgments normally appear. 4. Thenames
+ "Apache Forrest" and "Apache SoftwareFoundation"
+ must not be used to endorse or promoteproducts
+ derived from this software without priorwritten
+ permission. For written permission,please contact
+ apache@apache.org. 5. Products derivedfrom this
+ software may not be called "Apache", normay
+ "Apache" appear in their name, withoutprior
+ written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED``AS IS''
+ AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESSFOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NOEVENT
+ SHALL THE APACHE SOFTWARE FOUNDATION ORITS
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT,INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL
+ DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICTLIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OROTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
+ SUCH DAMAGE. This software consists ofvoluntary
+ contributions made by many individuals onbehalf
+ of the Apache Software Foundation. Formore
+ information on the Apache SoftwareFoundation,
+ please see .
+
+%% This notice is provided with respect to Independent JPEG Group's software (libjpeg), which may be included with this software:
+
+In plain English:
+
+1. We don't promise that this software works. (But if you find any bugs,
+ please let us know!)
+2. You can use this software for whatever you want. You don't have to pay us.
+3. You may not pretend that you wrote this software. If you use it in a program, you must acknowledge somewhere in your documentation that you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied, with respect to this software, its quality, accuracy, merchantability, or fitness for a particular purpose. This software is provided "AS IS", and you, its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this software (or portions thereof) for any purpose, without fee, subject to these conditions:
+
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice unaltered; and any additions, deletions, or changes to the original files must be clearly indicated in accompanying documentation.
+
+(2) If only executable code is distributed, then the accompanying documentation must state that "this software is based in part on the work of the Independent JPEG Group".
+
+(3) Permission for use of this software is granted only if the user accepts full responsibility for any undesirable consequences; the authors accept NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code, not just to the unmodified library. If you use our work, you ought to acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name in advertising or publicity relating to this software or products derived from it. This software may be referred to only as "the Independent JPEG Group's software".
+
+We specifically permit and encourage the use of this software as the basis of commercial products, provided that all warranty or liability claims are assumed by the product vendor.
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. ansi2knr.c is NOT covered by the above copyright and conditions, but instead by the usual distribution terms of the Free Software Foundation; principally, that you must include source code if you redistribute it. (See the file ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part of any program generated from the IJG code, this does not limit you more than the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf. It is copyright by the Free Software Foundation but is freely distributable. The same holds for its supporting scripts (config.guess, config.sub, ltconfig, ltmain.sh). Another support script, install-sh, is copyright by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot legally be used without obtaining one or more licenses. For this reason, support for arithmetic coding has been removed from the free JPEG software. (Since arithmetic coding provides only a marginal gain over the unpatented Huffman mode, it is unlikely that very many implementations will support it.) So far as we are aware, there are no patent restrictions on the remaining code.
+
+The IJG distribution formerly included code to read and write GIF files. To avoid entanglement with the Unisys LZW patent, GIF reading support has been removed altogether, and the GIF writer has been simplified to produce "uncompressed GIFs". This technique does not use the LZW algorithm; the resulting GIF files are larger than usual, but are readable by all standard GIF decoders.
+
+We are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+%% This notice is provided with respect to X Resize and Rotate (Xrandr) Extension, which may be included with this software:
+2. XFree86 License
+
+XFree86 code without an explicit copyright is covered by the following
+copyright/license:
+
+Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
+
+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 XFREE86
+PROJECT 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.
+
+Except as contained in this notice, the name of the XFree86 Project shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+this Software without prior written authorization from the XFree86 Project.
+
+%% This notice is provided with respect to fontconfig, which may be included with this software:
+Id: COPYING,v 1.3 2003/04/04 20:17:40 keithp Exp $
+Copyright 2001,2003 Keith Packard
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Keith Packard not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. Keith Packard makes no
+representations about the suitability of this software for any purpose. It
+is provided "as is" without express or implied warranty.
+
+KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+%% This notice is provided with respect to XFree86, which may be included with this software:
+Copyright (C) 1994-2002 The XFree86 Project, Inc. All Rights Reserved.
+
+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 XFREE86 PROJECT 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.
+
+Except as contained in this notice, the name of the XFree86 Project shall not be
+used in advertising or otherwise
+to promote the sale, use or other dealings in this Software without prior
+written authorization from the XFree86
+Project.
+%% This notice is provided with respect to Fast Infoset, which may be included with this software:
+* Fast Infoset ver. 0.1 software ("Software")
+*
+* Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
+*
+* Software is licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+* License for the specific language governing permissions and limitations.
+*
+* Sun supports and benefits from the global community of open source
+* developers, and thanks the community for its important contributions and
+* open standards-based technology, which Sun has adopted into many of its
+* products.
+*
+* Please note that portions of Software may be provided with notices and
+* open source licenses from such communities and third parties that govern the
+* use of those portions, and any licenses granted hereunder do not alter any
+* rights and obligations you may have under such open source licenses,
+* however, the disclaimer of warranty and limitation of liability provisions
+* in this License will apply to all Software in this distribution.
+*
+* You acknowledge that the Software is not designed, licensed or intended
+* for use in the design, construction, operation or maintenance of any nuclear
+* facility.
+*
+* Apache License
+* Version 2.0, January 2004
+* http://www.apache.org/licenses/
+*
+*/
+/*
+* ====================================================================
+*
+* This code is subject to the freebxml License, Version 1.1
+*
+* Copyright (c) 2001 - 2005 freebxml.org. All rights reserved.
+*
+* $Header: /cvs/fi/FastInfoset/src/com/sun/xml/internal/fastinfoset/AbstractResourceBundle.java,v 1.2
+* ====================================================================
+*/
+%% This notice is provided with respect to Kerberos, which may be included with this software:
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+%% This notice is provided with respect to Unicode's CLDR data repository, which may be included with this software:
+
+ Unicode Copyright
+
+ For the general privacy policy governing access to this site, see the
+Unicode Privacy Policy. For trademark usage, see the the Unicode Consortium
+Trademarks and Logo Policy.
+ Notice to End User: Terms of Use
+ Carefully read the following legal agreement ("Agreement"). Use or copying
+of the software and/or codes provided with this agreement (The "Software")
+constitutes your acceptance of these terms
+
+ 1. Unicode Copyright.
+ 1. Copyright © 1991-2005 Unicode, Inc. All rights reserved.
+ 2. Certain documents and files on this website contain a legend
+indicating that "Modification is permitted." Any person is hereby authorized,
+without fee, to modify such documents and files to create derivative works
+conforming to the Unicode® Standard, subject to Terms and Conditions herein.
+ 3. Any person is hereby authorized, without fee, to view, use,
+reproduce, and distribute all documents and files solely for informational
+purposes in the creation of products supporting the Unicode Standard, subject to
+the Terms and Conditions herein.
+ 4. Further specifications of rights and restrictions pertaining to
+the use of the particular set of data files known as the "Unicode Character
+Database" can be found in Exhibit 1.
+ 5. Further specifications of rights and restrictions pertaining to
+the use of the particular set of files that constitute the online edition of The
+Unicode Standard, Version 4.0, may be found in V4.0 online edition.
+ 6. No license is granted to "mirror" the Unicode website where a
+fee is charged for access to the "mirror" site.
+ 7. Modification is not permitted with respect to this document. All
+copies of this document must be verbatim.
+ 2. Restricted Rights Legend. Any technical data or software which is
+licensed to the United States of America, its agencies and/or instrumentalities
+under this Agreement is commercial technical data or commercial computer
+software developed exclusively at private expense as defined in FAR 2.101, or
+DFARS 252.227-7014 (June 1995), as applicable. For technical data, use,
+duplication, or disclosure by the Government is subject to restrictions as set
+forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and
+this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202,
+as applicable, use, duplication or disclosure by the Government is subject to
+the restrictions set forth in this Agreement.
+ 3. Warranties and Disclaimers.
+ 1. This publication and/or website may include technical or
+typographical errors or other inaccuracies . Changes are periodically added to
+the information herein; these changes will be incorporated in new editions of
+the publication and/or website. Unicode may make improvements and/or changes in
+the product(s) and/or program(s) described in this publication and/or website at
+any time.
+ 2. If this file has been purchased on magnetic or optical media
+from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange
+of the defective media within ninety (90) days of original purchase.
+ 3. EXCEPT AS PROVIDED IN SECTION C.2, THIS PUBLICATION AND/OR
+SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS,
+IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE
+AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS
+PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED
+TO THIS PUBLICATION OR THE UNICODE WEBSITE.
+ 4. Waiver of Damages. In no event shall Unicode or its licensors be
+liable for any special, incidental, indirect or consequential damages of any
+kind, or any damages whatsoever, whether or not Unicode was advised of the
+possibility of the damage, including, without limitation, those resulting from
+the following: loss of use, data or profits, in connection with the use,
+modification or distribution of this information or its derivatives.
+ 5. Trademarks.
+ 1. Unicode and the Unicode logo are registered trademarks of
+Unicode, Inc.
+ 2. This site contains product names and corporate names of other
+companies. All product names and company names and logos mentioned herein are
+the trademarks or registered trademarks of their respective owners. Other
+products and corporate names mentioned herein which are trademarks of a third
+party are used only for explanation and for the owners' benefit and with no
+intent to infringe.
+ 3. Use of third party products or information referred to herein is
+at the user's risk.
+ 6. Miscellaneous.
+ 1. Jurisdiction and Venue. This server is operated from a location
+in the State of California, United States of America. Unicode makes no
+representation that the materials are appropriate for use in other locations. If
+you access this server from other locations, you are responsible for compliance
+with local laws. This Agreement, all use of this site and any claims and damages
+resulting from use of this site are governed solely by the laws of the State of
+California without regard to any principles which would apply the laws of a
+different jurisdiction. The user agrees that any disputes regarding this site
+shall be resolved solely in the courts located in Santa Clara County,
+California. The user agrees said courts have personal jurisdiction and agree to
+waive any right to transfer the dispute to any other forum.
+ 2. Modification by Unicode Unicode shall have the right to modify
+this Agreement at any time by posting it to this site. The user may not assign
+any part of this Agreement without Unicode's prior written consent.
+ 3. Taxes. The user agrees to pay any taxes arising from access to
+this website or use of the information herein, except for those based on
+Unicode's net income.
+ 4. Severability. If any provision of this Agreement is declared
+invalid or unenforceable, the remaining provisions of this Agreement shall
+remain in effect.
+ 5. Entire Agreement. This Agreement constitutes the entire
+agreement between the parties.
+
+EXHIBIT 1
+UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
+
+ Unicode Data Files include all data files under the directories
+http://www.unicode.org/Public/ and http://www.unicode.org/reports/. Unicode
+Software includes any source code under the directories
+http://www.unicode.org/Public/ and http://www.unicode.org/reports/.
+
+ NOTICE TO USER: Carefully read the following legal agreement. BY
+DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES
+("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND
+AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU
+DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES
+OR SOFTWARE.
+
+ COPYRIGHT AND PERMISSION NOTICE
+
+ Copyright Ă?Â,Ă,© 1991-2004 Unicode, Inc. All rights reserved. Distributed under
+the Terms of Use in http://www.unicode.org/copyright.html.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+of the Unicode data files and associated documentation (the "Data Files") or
+Unicode software and associated documentation (the "Software") to deal in the
+Data Files or Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, and/or sell copies of
+the Data Files or Software, and to permit persons to whom the Data Files or
+Software are furnished to do so, provided that (a) the above copyright notice(s)
+and this permission notice appear with all copies of the Data Files or Software,
+(b) both the above copyright notice(s) and this permission notice appear in
+associated documentation, and (c) there is clear notice in each modified Data
+File or in the Software as well as in the documentation associated with the Data
+File(s) or Software that the data or software has been modified.
+
+ THE DATA FILES AND SOFTWARE ARE 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 OF THIRD
+PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+ Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in these Data Files or Software without prior written authorization of the
+copyright holder.
+
+ Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be
+registered in some jurisdictions. All other trademarks and registered trademarks
+mentioned herein are the property of their respective owners.
+%% This notice is provided with respect to RSA PKCS#11 Header Files & Specification, which may be included with this software:
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ *
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government. It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. FundsXpress makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+%% This notice is provided with respect to certain files/code which may included in the implementation of AWT within the software:
+
+******************************************************
+BEGIN src/solaris/native/sun/awt/HPkeysym.h
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Hewlett Packard
+or Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD
+TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. Hewlett-Packard shall not be liable for errors
+contained herein or direct, indirect, special, incidental or
+consequential damages in connection with the furnishing,
+performance, or use of this material.
+
+END src/solaris/native/sun/awt/HPkeysym.h
+******************************************************
+******************************************************
+BEGIN src/solaris/native/sun/awt/Xrandr.h
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandr.h,v 1.9 2002/09/29 23:39:44 keithp Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, Inc.
+ * Copyright © 2002 Hewlett-Packard Company, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Compaq not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. HP makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL COMPAQ
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jim Gettys, HP Labs, HP.
+ */
+
+
+END src/solaris/native/sun/awt/Xrandr.h
+******************************************************
+BEGIN src/solaris/native/sun/awt/extutil.h
+/*
+ * $Xorg: extutil.h,v 1.3 2000/08/18 04:05:45 coskrey Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Jim Fulton, MIT The Open Group
+ *
+ * Xlib Extension-Writing Utilities
+ *
+ * This package contains utilities for writing the client API for various
+ * protocol extensions. THESE INTERFACES ARE NOT PART OF THE X STANDARD AND
+ * ARE SUBJECT TO CHANGE!
+ */
+/* $XFree86: xc/include/extensions/extutil.h,v 1.5 2001/01/17 17:53:20 dawes Exp $ */
+
+END src/solaris/native/sun/awt/extutil.h
+******************************************************
+BEGIN src/solaris/native/sun/awt/fontconfig.h
+/*
+ * $RCSId: xc/lib/fontconfig/fontconfig/fontconfig.h,v 1.30 2002/09/26 00:17:27
+keithp Exp $
+ *
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+
+END src/solaris/native/sun/awt/fontconfig.h
+******************************************************
+BEGIN src/solaris/native/sun/awt/list.c
+AND src/solaris/native/sun/awt/list.h
+AND src/solaris/native/sun/awt/multiVis.c
+AND src/solaris/native/sun/awt/multiVis.h
+AND src/solaris/native/sun/awt/wsutils.h
+
+Copyright (c) 1994 Hewlett-Packard Co.
+Copyright (c) 1996 X Consortium
+
+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 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 X CONSORTIUM 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.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+END src/solaris/native/sun/awt/list.c
+AND src/solaris/native/sun/awt/list.h
+AND src/solaris/native/sun/awt/multiVis.c
+AND src/solaris/native/sun/awt/multiVis.h
+AND src/solaris/native/sun/awt/wsutils.h
+
+*****************************************************************
+BEGIN src/solaris/native/sun/awt/randr.h
+
+ *
+ * Copyright © 2000, Compaq Computer Corporation,
+ * Copyright © 2002, Hewlett Packard, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Compaq or HP not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. HP makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL HP
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Jim Gettys, HP Labs, Hewlett-Packard, Inc.
+
+END src/solaris/native/sun/awt/randr.h
+*****************************************************
+
+BEGIN src/solaris/native/sun/java2d/opengl/J2D_GL/glx.h
+ * Mesa 3-D graphics library
+ * Version: 4.1
+ *
+ * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+
+END src/solaris/native/sun/java2d/opengl/J2D_GL/glx.h
diff --git a/hotspot/agent/doc/ReadMe-JavaScript.text b/hotspot/agent/doc/ReadMe-JavaScript.text
new file mode 100644
index 00000000000..432aaa45aa0
--- /dev/null
+++ b/hotspot/agent/doc/ReadMe-JavaScript.text
@@ -0,0 +1,38 @@
+The HotSpot Serviceability Agent (SA) is a debugger for hotspot core
+dumps and hung processes. There is a read-only JDI (Java Debugger
+Interface) implementation on top of SA. This is part of JDK product and
+the classes are in $JDK/tools/sa-jdi.jar.
+
+In addition, there are few serviceability tools in $JDK/bin, namely,
+jstack (java stack trace tool), jmap (heap tool), jinfo (Java config
+tool) and jsadebugd. The classes for these are also in sa-jdi.jar
+file. sa-jdi.jar file is built along with hotspot (libjvm.so) on Solaris
+and Linux platforms. On Windows platform, SA-JDI is not included and
+serviceability tools do not use SA.
+
+Apart from these, HotSpot SA consists of a number of tools that are
+*not* included in JDK product bits.
+
+The sources and makefile for all-of-SA (including non-productized stuff)
+are under $HOTSPOT_WS/agent directory. The makefile $HOTSPOT/agent/make
+directory and shell scripts (and batch files) are used to build and run
+SA non-product tools. There is also documentation of SA under
+$HOTSPOT/agent/doc directory.
+
+To build complete SA, you need to have Rhino Mozilla jar (js.jar)
+version 1.5R5 under $HOTSPOT/agent/src/share/lib directory. Rhino is
+JavaScript interpreter written in Java. Rhino is used to implement SA
+features such as
+
+* SA command line debugger's JavaScript interface
+ - refer to $HOTSPOT/agent/doc/clhsdb.html
+ - refer to $HOTSPOT/agent/doc/jsdb.html
+* SA simple object query language (SOQL)
+ - language to query Java heap.
+
+Rhino's "js.jar" is not included in hotspot source bundles. You need to
+download it from http://www.mozilla.org/rhino/download.html.
+
+Without js.jar, $HOTSPOT/agent/make/Makefile will fail to build. But,
+note that sa-jdi.jar containing the productized portions of SA will
+still be built when you build hotspot JVM.
diff --git a/hotspot/agent/doc/clhsdb.html b/hotspot/agent/doc/clhsdb.html
new file mode 100644
index 00000000000..785be2f2568
--- /dev/null
+++ b/hotspot/agent/doc/clhsdb.html
@@ -0,0 +1,118 @@
+
+
+
+Command line HSDB
+
+
+
+
+Command line HSDB
+
+When debugging remote core dumps it is easier to work with command line tools instead of
+GUI tools. Command line HSDB (CLHSDB) tool is alternative to SA GUI tool HSDB.
+
+
+
+There is also JavaScript based SA command line interface called jsdb.
+But, CLHSDB supports Unix shell-like (or dbx/gdb-like) command line interface with
+support for output redirection/appending (familiar >, >>), command history and so on.
+Each CLHSDB command can have zero or more arguments and optionally end with output redirection
+(or append) to a file. Commands may be stored in a file and run using source command.
+help command prints usage message for all supported commands (or a specific command)
+
+
+Shell/batch scripts to run command line HSDB
+
+
+- clhsdbproc.sh
+
- clhsdbproc64.sh
+
- clhsdbwindbg.bat
+
- clhsdbwindbg64.bat
+
+
+Annotated output of CLHSDB help command
+
+
+
+Available commands:
+ assert true | false turn on/off asserts in SA code
+ attach pid | exec core attach SA to a process or core
+ class name find a Java class from debuggee and print oop
+ classes print all loaded Java classes with klassOop
+ detach detach SA from current target
+ dis address [ length ] disassemble (sparc/x86) specified number of instructions from given address
+ dumpclass { address | name } [ directory ] dump .class file for given klassOop or class name
+ dumpheap [ file ] dump heap in hprof binary format
+ echo [ true | false ] turn on/off command echo mode
+ examine [ address/count ] | [ address,address] show contents of memory from given address
+ field [ type [ name fieldtype isStatic offset address ] ] print info about a field of HotSpot type
+ findpc address print info. about pointer location
+ flags [ flag ] show all -XX flag name value pairs. or just show given flag
+ help [ command ] print help message for all commands or just given command
+ history show command history. usual !command-number syntax works.
+ inspect expression inspect a given oop
+ jdis address show bytecode disassembly of a given methodOop
+ jhisto show Java heap histogram
+ jseval script evaluate a given string as JavaScript code
+ jsload file load and evaluate a JavaScript file
+ jstack [-v] show Java stack trace of all Java threads. -v is verbose mode
+ livenmethods show all live nmethods
+ mem address [ length ] show contents of memory -- also shows closest ELF/COFF symbol if found
+ pmap show Solaris pmap-like output
+ print expression print given klassOop, methodOop or arbitrary address
+ printas type expression print given address as given HotSpot type. eg. print JavaThread <address>
+ printstatics [ type ] print static fields of given HotSpot type (or all types if none specified)
+ pstack [-v] show mixed mode stack trace for all Java, non-Java threads. -v is verbose mode
+ quit quit CLHSDB tool
+ reattach detach and re-attach SA to current target
+ scanoops start end [ type ] scan a Oop from given start to end address
+ search [ heap | codecache | threads ] value search a value in heap or codecache or threads
+ source filename load and execute CLHSDB commands from given file
+ symbol name show address of a given ELF/COFF symbol
+ sysprops show all Java System properties
+ threads show all Java threads
+ tokenize ...
+ type [ type [ name super isOop isInteger isUnsigned size ] ] show info. on HotSpot type
+ universe print gc universe
+ verbose true | false turn on/off verbose mode
+ versioncheck [ true | false ] turn on/off debuggee VM version check
+ whatis address print info about any arbitrary address
+ where { -a | id } print Java stack trace of given Java thread or all Java threads (-a)
+
+
+
+JavaScript integration
+
+Few CLHSDB commands are already implemented in JavaScript. It is possible to extend CLHSDB command set
+by implementing more commands in a JavaScript file and by loading it by jsload command. jseval
+command may be used to evaluate arbitrary JavaScript expression from a string. Any JavaScript function
+may be exposed as a CLHSDB command by registering it using JavaScript registerCommand
+function. This function accepts command name, usage and name of the JavaScript implementation function
+as arguments.
+
+
+Simple CLHSDB command implemented in JavaScript
+
+File: test.js
+
+
+function helloImpl(name) {
+ println("hello, " + name);
+}
+
+// register the above JavaScript function as CLHSDB command
+registerCommand("hello", "hello name", "helloImpl");
+
+
+---------
+
+"test.js" can be loaded in CLHSDB prompt using jsload command using
+
+
+
+hsdb> jsload test.js
+
+
+
+
+
diff --git a/hotspot/agent/doc/hsdb.html b/hotspot/agent/doc/hsdb.html
new file mode 100644
index 00000000000..c835d6b43a1
--- /dev/null
+++ b/hotspot/agent/doc/hsdb.html
@@ -0,0 +1,44 @@
+
+
+
+SA HSDB GUI
+
+
+
+
+Once the HSDB debugger has been launched, the threads list is displayed
+if launched with debuggee options (pid or core) in command line. If
+HSDB was launched without debuggee, empty screen is shown.
+
+File menu sub-menu options to attach, detach debuggee and exit tool.
+Tools menu sub-menus include:
+
+ - browsing of the annotated stack memory ("Stack Memory" button). It
+ is currently annotated with the following information:
+
+ - method names of the Java frames and their extents (supporting
+ inlined compiled methods)
+
- locations and types of oops, found using the oop map information
+ from compiled methods (interpreter oop maps coming soon)
+
- if a Java frame was interrupted by a signal (e.g., because of a
+ crash), annotates the frame with the signal name and number
+
- interpreter codelet descriptions for interpreted frames
+
+ - finding which thread or threads caused a crash (currently
+ identified by the presence of a signal handler frame - solaris-only)
+
- browsing of oops using the Oop Inspector.
+
- browsing of the java.lang.Thread object's oop.
+
- Object Histogram and inspection of objects and liveness analysis therein.
+
- Class Browser - view Java classes, bytecode disassembly,
+ or create .class files for selected classes
+
- native disassembly (sparc, x86 only) and nmethod disassembly with annotations for safepoint details.
+
- view -XX flags, System properties, VM version of debuggee
+
+Windows sub-menu options include:
+
+ - Windows sub-menu: Console window to run "CLHSDB" commands in GUI
+
- Windows sub-menu: Debugger console of underlying native debugger (MS Windbg or dbx (if used))
+
+
+
+
diff --git a/hotspot/agent/doc/index.html b/hotspot/agent/doc/index.html
new file mode 100644
index 00000000000..987e5f9c659
--- /dev/null
+++ b/hotspot/agent/doc/index.html
@@ -0,0 +1,241 @@
+
+
+
+Using HotSpot Serviceability Agent (SA)
+
+
+
+Using HotSpot Serviceability Agent (SA)
+
+HSDB GUI
+
+The top-level GUI program using the HotSpot Serviceability Agent APIs is
+called HSDB, the "HotSpot Debugger". To run it, type "hsdbproc.sh"
+or "hsdbwindbg.bat" or 64-bit variants (on Unix, Windows platforms
+respectively). More info. on HSDB GUI are in hsdb.html.
+
+
+SA Modes
+
+There are three modes for the SA debugger:
+
+- attaching to a local process,
+
- opening a core file, and
+
- attaching to a remote "debug server".
+
+
+The remote case requires two programs to be running on the remote machine:
+the rmiregistry (see the script "start-rmiregistry.sh" in this directory;
+run this in the background) and the debug server (see the script
+"start-debug-server-proc.sh"), in that order. start-rmiregistry.sh takes no
+arguments; start-debug-server-proc.sh (or -windbg.bat) takes as argument
+the process ID or the executable and core file names to allow remote debugging
+of.
+
+
+Command line HSDB
+
+There are also command line HSDB variants ("clhsdbproc.sh" or "clhsdbwindbg.bat"
+or 64-bit variants). There is also a JavaScript based command line interface
+called "jsdbproc.sh" [or "jsdbwindbg.bat" or 64-bit variants]. More details on
+command line interfaces can be found in
+
+
+
+Other command line tools
+
+The following table lists all SA command line tools. <xxx>windbg.bat
+files are for Windows. .sh files are for Solaris. <xxx>64.sh are for
+64 bit debugees.
+
+
+
+
+
+Tool
+ |
+
+Description
+ |
+
+
+
+
+dumpflagsproc.sh,
+dumpflagsproc64.sh,
+dumpflagswindbg.bat
+dumpflagswindbg64.bat
+ |
+
+dumps name and value of all -XX JVM command line arguments passed
+to debuggee.
+ |
+
+
+
+
+
+dumpsyspropsproc.sh,
+dumpsyspropsproc64.sh,
+dumpsyspropswindbg.bat
+dumpsyspropswindbg64.bat
+ |
+
+This prints name and value of Java level System properties.
+ |
+
+
+
+
+
+heapdumpproc.sh,
+heapdumpproc64.sh,
+heapdumpwindbg.bat
+heapdumpwindbg64.bat
+ |
+
+Dumps heap in a file in hprof binary format.
+ |
+
+
+
+
+
+heapsumproc.sh,
+heapsumproc64.sh,
+heapsumwindbg.bat
+heapsumwindbg64.bat
+ |
+
+Prints summary information on Java heap.
+ |
+
+
+
+
+
+jcoreproc.sh,
+jcoreproc64.sh,
+jcorewindbg.bat
+jcorewindbg64.bat
+ |
+
+This can retrieve .class files from the debuggee.
+set the environment variable JCORE_PACKAGES to comman separated list of
+packages whose classes have to be retrieved from the core file.
+ |
+
+
+
+
+
+jstackproc.sh,
+jstackproc64.sh,
+jstackwindbg.bat
+jstackwindbg64.bat
+ |
+
+used to get java stack trace for all java threads.
+ |
+
+
+
+
+jhistoproc.sh,
+jhistoproc64.sh,
+jhistowindbg.bat
+jhistowindbg64.bat
+ |
+
+used to get object histogram of java heap.
+ |
+
+
+
+
+permstatproc.sh,
+permstatproc64.sh,
+permstatwindbg.bat
+permstatwindbg64.bat
+ |
+
+To gather statistics on perm. generation.
+ |
+
+
+
+
+
+
+pstackproc.sh,
+pstackproc64.sh,
+pstackwindbg.bat
+pstackwindbg64.bat
+ |
+
+This is cross platform mixed mode pstack utility. This works on any (non-java as well) process, core dump. For java process and core dumps, this prints both java and C/C++ frames.
+ |
+
+
+
+
+pmapproc.sh,
+pmapproc64.sh,
+pmapwindbg.bat
+pmapwindbg64.bat
+ |
+
+This is cross platform Solaris pmap-like utility.
+ |
+
+
+
+
+soqlproc.sh,
+soqlproc64.sh,
+soqlwindbg.bat
+soqlwindbg64.bat
+ |
+
+This is command line SOQL - Simple Object Query Language tool.
+SOQL is SQL-like query language to query Java heap.
+ |
+
+
+start-debug-server-proc.sh,
+start-debug-server-proc64.sh,
+start-debug-server-windbg.bat,
+start-debug-server-windbg64.bat,
+start-rmiregistry.bat,
+start-rmiregistry64.bat,
+start-rmiregistry.sh
+start-rmiregistry64.sh
+ |
+
+These scripts are used to run SA remotely.
+ |
+
+
+
+Debugging transported core dumps
+
+When a core dump is moved from the machine where it was produced to a
+difference machine, it may not always be possible for SA to debug the same.
+More info. on debugging on transported core dumps is in
+transported_core.html.
+
+
+SA Bugs
+
+Not all of the possible states of target VMs have been tested (or
+supportable) with SA. For example, the SA will probably not work at all
+if it freezes the target VM during certain phases of GC. When filing bugs
+a pointer to a core file (see gcore(1)) which the SA can not handle well
+is best.
+
+
+
+
diff --git a/hotspot/agent/doc/jsdb.html b/hotspot/agent/doc/jsdb.html
new file mode 100644
index 00000000000..e691bb9cb3c
--- /dev/null
+++ b/hotspot/agent/doc/jsdb.html
@@ -0,0 +1,1369 @@
+
+
+
+JavaScript interface to Hotspot Serviceability Agent
+
+
+
+JavaScript interface to Hotspot Serviceability Agent
+
+
+Serviceability Agent (SA) provides Java API and tools to diagnose HotSpot Virtual Machine and
+Java apps running on it. SA is a snapshot debugger -- can be used to observe state of a frozen java process or java core dump.
+
+
+Existing SA APIs
+
+There are two application programmer interfaces (APIs) for SA:
+
+- 1. Private java API
+
+-
+This tries to mimic hotspot VM's internal C++ classes and methods. Because VM data structures
+are a moving target, this API can never be 'stable'! Besides, to use SA's private API knowledge of
+HotSpot code base is essential.
+
+- 2. SA-JDI -- Java Debugger Interface read-only subset API
+
+-
+This is read-only subset of JDI (Java Debugger Interface)
+This is a standardized interface to get java level state of a java process or java core dump. While this
+interface is useful, this misses parts of java level state from target process or core such as
+
+- heap walking interface -- only objects traceable to static variables (of classes) and local
+variables of stack frames can be accessed.
+
- re-constructing .class from debuggee are missing.
+
- re-constructing object mirrors for Java objects of the debuggee.
+
+
+
+
+
+SA Scripting interface
+
+
+Traditionally, platform debuggers such as dbx, gdb and Solaris mdb (Module Debugger), provide a scripting
+language interface. Scripting language interface provides easy-to-use, dynamically typed
+interface to access data structures from debuggee. dbx and mdb even allow user to write
+C/C++ modules to extend the scripting language commands.
+
+
+
+SA provides SOQL - Simple Object Query Language -- a SQL-like query language to access
+Java heap as an object database. SA's main GUI (HSDB) also exposes scripting interface of underlying debugger such as dbx, windbg.
+But to use this interface, user has to learn scripting interface of multiple debugger back-ends such as dbx, windbg.
+And these scripting interfaces are 'raw' in the sense that no java state is exposed -- only C/C++ state of VM is exposed.
+Higher level SA services are not available through scripting interface.
+
+
+
+jsdb -- JavaScript Debugger attempts to provide JavaScript interface to SA.
+jsdb provides
+
+
+- high-level hotspot (and SA) independent scripting interface
+
- low-level SA-aware scripting interface.
+
+
+
+High level interface (Java State)
+
+jsdb is a command line JavaScript shell based on
+Mozilla's Rhino JavaScript Engine.
+This command line utility attaches to Java process or core file or remote debug server and waits for user input.
+This shell supports the following global functions and objects in addition to the standard JavaScript functions and
+objects:
+
+jdsb globals
+
+
+
+Function/Variable |
+Description |
+
+
+
+address(jobject)
+ |
+
+function that returns the address of the Java object as a string
+ |
+
+
+classof(jobject)
+ |
+
+function that returns the JavaScript object that represents class object of the Java object
+ |
+
+
+dumpClass(jclass,[dir])
+ |
+
+function that writes .class for the given Java Class. Optionally (second arg) accepts the directory where the
+.class has to be written.
+ |
+
+
+help()
+ |
+
+function that prints help message for global functions and objects
+ |
+
+
+
+identityHash(jobject)
+ |
+
+function that returns the identity hashCode of the Java object
+ |
+
+
+
+mirror(jobject)
+ |
+
+function that returns a local mirror of the Java object.
+ |
+
+
+
+load([file1, file2,...])
+ |
+
+function that loads zero or more JavaScript file(s). With no arguments, reads for
+JavaScript code.
+ |
+
+
+
+object(string)
+ |
+
+function that converts a string address into Java object
+ |
+
+
+
+owner(jobject)
+ |
+
+function that returns the owner thread of this monitor or null
+ |
+
+
+
+sizeof(jobject)
+ |
+
+function that returns the size of Java object in bytes
+ |
+
+
+
+staticof(jclass, field)
+ |
+
+function that returns the value of given field of the given Java class
+ |
+
+
+
+print(expr1, expr2,...)
+ |
+
+function that prints zero or more JavaScript expressions after converting those as strings
+ |
+
+
+
+println(expr1, expr2..)
+ |
+
+function that same as print, but prints a newline at the end
+ |
+
+
+
+read([prompt])
+ |
+
+function that reads a single line from standard input
+ |
+
+
+
+quit()
+ |
+
+function that quits the interactive load call as well as the shell
+ |
+
+
+
+jvm
+ |
+
+variable -- a JavaScript object that represents the target jvm that is being debugged
+ |
+
+
+
+jvm object
+
+
+jvm object supports the following read-only properties.
+
+
+
+
+
+Property name
+ |
+
+Description
+ |
+
+
+
+threads
+ |
+
+array of Java threads from the debuggee
+ |
+
+
+
+heap
+ |
+
+object representing the heap of the debuggee
+ |
+
+
+
+type
+ |
+
+string value that is either "Server" or "Client" or "Core" -- the flavour of debuggee VM
+ |
+
+
+
+bootClassPath
+ |
+
+string value of bootclasspath of the debuggee
+ |
+
+
+
+cpu
+ |
+
+string value of cpu on which the debuggee runs/ran
+ |
+
+
+
+sysProps
+ |
+
+name-value pairs (JavaScript associative array) of Java System properties of the debuggee
+ |
+
+
+
+addressSize
+ |
+
+int value -- 32 for 32 bit debuggee, 64 for 64 bit debuggee
+ |
+
+
+
+os
+ |
+
+string value of OS on which the debuggee runs/ran
+ |
+
+
+
+buildInfo
+ |
+
+internal build info string from debuggee
+ |
+
+
+
+flags
+ |
+
+name-value pairs (JavaScript associative array) of JVM command line flags of the debuggee
+ |
+
+
+
+classPath
+ |
+
+string value of classpath of the debuggee
+ |
+
+
+
+userDir
+ |
+
+string value of user.dir System property of the debuggee
+ |
+
+
+
+heap object
+
+
+heap object represents Java heap of the debuggee VM
+
+
+
+
+Function or property name
+ |
+
+Description
+ |
+
+
+
+capacity
+ |
+
+byte size of capacity of the heap
+ |
+
+
+
+used
+ |
+
+byte size of used portion (of live objects) of the heap
+ |
+
+
+
+forEachObject(func, [class], [include subtypes -- true|false])
+ |
+
+This function accepts a callback function 'func' and optionally class name and boolean arguments.
+This function calls the callback for each Java object in the debuggee's heap. The optional class
+argument may be used to receive objects of given class only. The third arguments specifies whether
+to include objects of subtype of given class [or interface] or not. The default value of class is "java.lang.Object"
+and and that of the third argument is true. i.e., by default all objects are included.
+ |
+
+
+
+forEachClass(func, [initiating loader -- true|false])
+ |
+
+This function accepts a callback function 'func'. This function iterates through the classes of the debuggee and calls the
+callback for each class. The second parameter tells whether to pass initiating loader to the iterator callback or not.
+ |
+
+
+
+Accessing Java objects and arrays in script
+
+
+From a given Java object, we can access all fields of the Java object by usual '.' operator. i.e., if you got a Java object
+called 'o' of type java.lang.Thread from debuggee, you can access 'stackSize' field by o.stackSize syntax. Similarly, length of Java array
+objects can be accessed by length property. And array indexing follows usual syntax. i.e., n'th element of array 'a' is
+accessed by a[n].
+
+
+jvm.threads array
+
+
+This is a JavaScript array of Java threads of the debuggee. As usual, 'length' property tells the number of threads and individual
+threads may be accessed by index operator -- i.e, jvm.threads[0] returns the first thread.
+
+
+thread object
+
+
+
+In addition to the fields of java.lang.Thread (or subclass) fields, thread objects have two additional properties.
+
+
+- frames -- array of stack frame objects
+
- monitors -- array of monitor objects owned by the thread
+
+
+
+
+stack frame object
+
+
+
+
+Property name
+ |
+
+Description
+ |
+
+
+thisObject
+ |
+
+Object representing 'this' of the current frame [will be null for static methods]
+ |
+
+
+
+locals
+ |
+
+name-value pairs of local variables [JavaScript associative array]
+ |
+
+
+
+line
+ |
+
+Java source line number at which the frame is executing
+ |
+
+
+
+bci
+ |
+
+byte code index of the bytecode that the frame is executing
+ |
+
+
+
+thread
+ |
+
+thread to which this frame belongs
+ |
+
+
+
+method
+ |
+
+Java method that the frame is executing
+ |
+
+
+
+method object
+
+
+method object represents a Java method of debuggee
+
+
+
+
+
+Property name
+ |
+
+Description
+ |
+
+
+
+isStatic
+ |
+
+boolean - true for static methods and false for non-static methods
+ |
+
+
+
+
+isSynchronized
+ |
+
+boolean - true for synchronized methods and false for non-synchronized methods
+ |
+
+
+
+
+isNative
+ |
+
+boolean - true for native methods and false for non-native methods
+ |
+
+
+
+
+isProtected
+ |
+
+boolean - true for protected methods and false for non-protected methods
+ |
+
+
+
+
+isPrivate
+ |
+
+boolean - true for private methods and false for non-private methods
+ |
+
+
+
+
+isSynthetic
+ |
+
+boolean - true for Javac generated synthetic methods and false for non-synthetic methods
+ |
+
+
+
+
+isPackagePrivate
+ |
+
+boolean - true for package-private methods and false for non-package-private methods
+ |
+
+
+
+
+isPublic
+ |
+
+boolean - true for public methods and false for non-public methods
+ |
+
+
+
+
+holder
+ |
+
+an object that represents Class that contains this method
+ |
+
+
+
+
+signature
+ |
+
+string -- signature of this method
+ |
+
+
+
+
+isObsolete
+ |
+
+boolean - true for obsolete (hotswapped) methods and false for non-obsolete methods
+ |
+
+
+
+
+isStrict
+ |
+
+boolean - true for strictfp methods and false for non-strictfp methods
+ |
+
+
+
+
+isFinal
+ |
+
+boolean - true for final methods and false for non-final methods
+ |
+
+
+
+
+name
+ |
+
+string - name of this method
+ |
+
+
+
+class object
+
+
+A class object represents loaded Java class in debuggee VM. This represents java.lang.Class instance in the debuggee.
+This is type of return value of classof global function. Also, method.holder property and field.holder are
+of this type.
+
+
+
+
+
+Property name
+ |
+
+Description
+ |
+
+
+
+
+name
+ |
+
+name of this class
+ |
+
+
+
+
+superClass
+ |
+
+class object representing super class of this class
+ |
+
+
+
+
+isArrayClass
+ |
+
+boolean -- is the current class an array class?
+ |
+
+
+
+
+isStatic
+ |
+
+boolean -- is the current class static or not
+ |
+
+
+
+
+isInterface
+ |
+
+boolean -- is the current class an interface
+ |
+
+
+
+
+isAbstract
+ |
+
+boolean -- is the current class abstract or not
+ |
+
+
+
+
+isProtected
+ |
+
+boolean -- is the current class protected or not
+ |
+
+
+
+
+isPrivate
+ |
+
+boolean -- is the current class private or not
+ |
+
+
+
+
+isPackagePrivate
+ |
+
+boolean -- is the current class package private or not
+ |
+
+
+
+
+isSynthetic
+ |
+
+boolean -- is the current class synthetic or not
+ |
+
+
+
+
+classLoader
+ |
+
+object that represents ClassLoader object that loaded the current class
+ |
+
+
+
+
+
+fields
+ |
+
+array of static and instance fields of the current class
+ |
+
+
+
+
+protectionDomain
+ |
+
+protection domain to which current class belongs
+ |
+
+
+
+
+isPublic
+ |
+
+boolean -- is the current class public or not
+ |
+
+
+
+
+signers
+ |
+
+array of signers for current class
+ |
+
+
+
+
+sourceFile
+ |
+
+string -- name of the source file for current class
+ |
+
+
+
+
+interfaces
+ |
+
+array -- interfaces implemented by current class
+ |
+
+
+
+
+isStrict
+ |
+
+boolean -- is the current class strictfp or not
+ |
+
+
+
+
+methods
+ |
+
+array of methods (static and instance) of the current class
+ |
+
+
+
+
+
+isFinal
+ |
+
+boolean -- is the current class final or not
+ |
+
+
+
+
+statics
+ |
+
+name-value pairs (JavaScript associate array) of static fields of the current class
+ |
+
+
+
+field object
+
+field represents a static or instance field of some class in debuggee
+
+
+
+
+
+Property name
+ |
+
+Description
+ |
+
+
+
+
+isStatic
+ |
+
+boolean -- is this field a static field?
+ |
+
+
+
+
+holder
+ |
+
+class that owns this field
+ |
+
+
+
+
+signature
+ |
+
+string signature of this field
+ |
+
+
+
+
+isProtected
+ |
+
+boolean - is this field a protected field or not?
+ |
+
+
+
+
+isPrivate
+ |
+
+boolean - is this field a private field or not?
+ |
+
+
+
+
+isSynthetic
+ |
+
+boolean - is this javac generated synthetic field or not?
+ |
+
+
+
+
+isPackagePrivate
+ |
+
+boolean - is this field a package private field or not?
+ |
+
+
+
+
+isTransient
+ |
+
+boolean - is this field a transient field or not?
+ |
+
+
+
+
+isFinal
+ |
+
+boolean - is this field final or not?
+ |
+
+
+
+
+name
+ |
+
+string - name of this field
+ |
+
+
+
+
+isPublic
+ |
+
+boolean - is this field public or not?
+ |
+
+
+
+Initialization Script
+
+jsdb engine looks for initialization script file named jsdb.js in user's home directory. If found, it loads just after attaching to debuggee but before printing prompt for user's input. User can assume that s/he can access debuggee VM
+state during initialization script.
+
+
+Sample scripts
+
+Semantics and knowledge of application classes (for eg. AppServer's classes) would be needed to create app specific
+scripts. The following script samples are app-independent and provide a flavour of kind of scripts that can be written.
+
+Script to print system properties of JVM
+
+
+
+jvm.sysProps.toString()
+
+
+
+Script to print JVM command line flags
+
+
+jvm.flags.toString()
+
+
+
+
+Script to print class-wise histogram of objects
+
+
+
+
+// associate array to hold histogram
+var histo;
+function func(obj) {
+ var classname = classof(obj).name;
+ if (histo[classname] == undefined) {
+ // first time we are visiting this class type
+ histo[classname] = 1;
+ } else {
+ histo[classname]++;
+ }
+}
+
+// iterate through java heap calling 'func' for each object
+jvm.heap.forEachObject(func);
+
+// print the histogram
+for (i in histo) {
+ println('number of instances of ', i, ' = ', histo[i]);
+}
+
+
+
+
+Script to print stack trace of all Java threads
+
+
+
+
+function printStackTrace(t) {
+ println(t.name);
+ println('');
+ for (i in t.frames) {
+ println(t.frames[i]);
+ }
+ println('');
+}
+
+// walk through the list of threads and call printStackTrace
+// for each thread
+for (o in jvm.threads) {
+ printStackTrace(jvm.threads[o]);
+}
+
+
+
+
+
+
+Script to re-construct .class files for all non-bootstrap classes
+
+
+
+
+function dump(cl) {
+ if (!cl.isArrayClass && cl.classLoader != null) {
+ // not an array class and a non-bootstrap class
+ // create .class files in e:\tmp dir
+ dumpClass(cl, "e:\\tmp);
+ } else {
+ println("skipping bootstrap class ", cl.name);
+ }
+}
+
+// walk thru heap and call callback for each java.lang.Class instance
+jvm.heap.forEachObject(dump, "java.lang.Class");
+
+
+
+Script to print paths of all java.io.File's currently accessed
+
+
+
+
+function printFile(f) {
+ // construct a mirror java.io.File here and
+ // print absolute path here
+ println(mirror(f).getAbsolutePath());
+}
+
+jvm.heap.forEachObject(printFile, "java.io.File");
+
+
+
+
+Script to print static fields of java.lang.Thread class
+
+
+
+var threadClass = classof("java.lang.Thread");
+for (i in threadClass.statics) {
+ println(i, '=', threadClass.statics[i]);
+}
+
+
+
+
+Low level interface (VM State)
+
+
+Low level jsdb interface works by JavaScript-to-Java (previously known as "LiveConnect")
+interface provided by Rhino JavaScript engine.
+
+
+sapkg object
+
+This object provides short names for SA package names. For eg. instead of writing
+Packages.sun.jvm.hotspot.memory, we can write sapkg.memory.
+
+
+sa object
+
+This object contains all SA singleton objects such as VM, Universe, SymbolTable,
+SystemDictionary, ObjectHeap, CollectedHeap, Debugger, CDebugger (if available),
+Interpreter, TypeDataBase and Threads. For eg. to access SymbolTable of Java debuggee,
+we can use sa.symbolTable. User can execute the following code to get fields of this object.
+
+
+
+for (i in sa) {
+ println(i);
+}
+
+
+
+Heap Iterators
+
+- forEachOop(callback)
+- calls a callback function for each Oop in Java heap
+- forEachOopOfKlass(callback, klass, [includeSubtypes])
+- calls a callback function for each Oop of a give Klass type
+Optinally, third argument can specify whether to include subtype Oops
+or not.
+
+
+
+System Dictionary Access
+
+- forEachKlass(callback)
+- calls a callback function for each Klass in Java heap
+- forEachKlassAndLoader(callback)
+-
+calls callback with Klass and initiating loader (Oop) for System dictionary
+entry.
+
+- forEachPrimArrayKlass(callback)
+-
+calls callback with Klass and initiating loader (Oop) for each
+primitive array Klass in the system.
+
+- findInstanceKlass(name)
+-
+finds the first instance klass with given name from System dictionary
+
+
+
+Thread, Frame Iterators
+
+- forEachJavaThread(callback)
+- calls callback for each Java Thread
+- forEachFrame(javaThread, callback)
+- calls callback for each Frame of a given JavaThread
+- forEachVFrame(javaThread, callback)
+- calls callback for each JavaVFrame of a given JavaThread
+- forEachThread(callback)
+- calls callback for each (native) ThreadProxy (obtained by CDebugger.getThreadList)
+
+- forEachCFrame(threadProxy, callback)
+-
+calls callback for each CFrame of a given ThreadProxy object
+
+
+
+Code blobs, Interpreter codelets
+
+- forEachCodeBlob(callback)
+-
+calls callback with each code blob in code cache
+
+- findCodeBlob(address)
+-
+finds the code blob, if any, that contains the given address.
+Returns null, on failure.
+
+- findNMethod(address)
+-
+finds the NMethod that contains given address.
+
+- pcDescAt(addr)
+-
+returns PCDesc at given address or null.
+
+- forEachInterpCodelet(callbacl)
+-
+calls callback with each Interpreter codelet
+
+
+
+VM structs, constants
+
+- forEachType(callback)
+-
+calls callback for each Type in VM's type database
+
+- forEachVMIntConst(callback)
+-
+calls callback for each named integer constant. passes name
+as argument.
+
+- forEachVMLongConst(callback)
+-
+calls callback for each named long constant. passes name
+as argument.
+
+- findVMType(name)
+-
+finds a VM type by name. returns null if no known Type of given name
+exists in type database.
+
+- findVMIntConst(name)
+-
+finds an integer constant in type data base by name.
+
+- findVMLongConst(name)
+-
+finds an long constant in type data base by name.
+
+- vmTypeof(addr)
+-
+returns VM type of object at 'addr' if any. Else, returns null.
+
+- isOfVMType(addr, type)
+-
+returns whether object at 'addr' is of VM type 'type' or not.
+
+- printVMType(type, addr)
+-
+prints 'addr' as VM object of type 'type'
+
+- printXXX(addr)
+-
+For each VM type, these functions are defined. For eg. there is printUniverse,
+printSystemDictionary etc. are available. Without 'addr' being passed static fields are printed. With 'addr' param being passed, instance fields are printed.
+
+
+
+Low level debugger facilities
+
+- num2addr(number)
+-
+converts a (long) number to SA Address instance
+
+- str2addr(string)
+-
+converts a given hex string to SA Address instance
+
+- any2addr(any)
+-
+Takes a number or a string or an Address and returns
+an Address instance. For other types, returns 'undefined'
+
+- addr2str(addr)
+-
+converts a given Address instance to a hex string
+
+- addr2num(addr)
+-
+converts a given Address instance to a (long) number
+
+- sym2addr(library, symbol)
+-
+returns Address of a given symbol in a given library (shared object or DLL)
+Example: sym2addr('jvm.dll', 'JNI_CreateJavaVM')
+
- addr2sym(addr)
+-
+Returns nearest symbol to a given address (if any). If no such symbol is found,
+returns the given address as a string.
+
+- readBytesAt(addr, num)
+-
+returns 'num' bytes at 'addr' as a Java byte[]
+
+- readWordsAt(addr, num)
+-
+returns 'num' words at 'addr' as a Java long[]
+
+- readCStrAt(addr)
+-
+returns 'C' String at given address
+
+- readCStrLen(addr)
+-
+returns the length of the 'C' String at given address
+
+- readRegs(threadProxy)
+-
+returns register set (of Thread Context) of a given thread specified
+by threadProxy. return value is an associate array having name-value pairs
+of registers.
+
+- regs(threadProxy)
+-
+prints register set of a given thread.
+
+- mem(addr, [num])
+-
+prints 'num' words (address size) at 'addr'. Prints nearest symbol for address, if found.
+
+- dis(addr, [num])
+- prints native code disassembly of 'num' bytes at given address 'addr'.
+Default value of 'num' is 4. This automatically detects whether the given address
+inside a nmethod. If so, it prints safepoint info, entry points , method signature etc.
+of the nmethod.
+
+- jdis(method [or addr])
+-
+prints Java bytecode disassembly for given method Oop or address of a method Oop.
+
+- nmethoddis(nmethod)
+-
+prints disassembly of given nmethod object. Note that you don't have to call this directly
+instead use 'dis'.
+
+- where
+-
+prints Java stack trace for all Java threads
+
+
+
+Miscellaneous
+
+- addr2oop(addr)
+-
+converts a given address to a Oop object
+
+- oop2addr(oop)
+-
+returns address of a given Oop object
+
+- isOfVMType(addr, type)
+-
+returns whether the given 'addr' points to a (C++) VM object of specified
+type. type may be specified by SA Type object or string name of the type.
+
+- newVMObject(addr)
+-
+returns instance of SA object for a given address (similar to SA VirtualConstructor
+interface).
+
+- vmobj2addr(vmobject)
+-
+returns Address represented by a given SA VMObject
+
+- addr2vmobj(addr)
+- same as newVMObject(addr)
+- whatis(addr)
+-
+returns string description of given address (using SA FindPointer and guess type API).
+
- isOop(addr)
+-
+returns whether a given address is a valid Oop address or not
+
+
+
+Moving b/w jsdb low level and high level interfaces
+
+
+Java objects of debuggee are represented by different script wrappers in high level
+interface. In the low-level interface these are instances of SA Oop class or its'
+subclass. To move b/w low-level and high-level interfaces the following functions may
+be used
+
+
+- oop2obj(oop)
+-
+converts a given Oop object to a high-level wrapper object
+
+- obj2oop(obj)
+-
+converts a jsdb high level wrapper to underlying Oop instance
+
+
+
+JavaScript tips
+
+
+
+
+
diff --git a/hotspot/agent/doc/transported_core.html b/hotspot/agent/doc/transported_core.html
new file mode 100644
index 00000000000..e1cdf0f2407
--- /dev/null
+++ b/hotspot/agent/doc/transported_core.html
@@ -0,0 +1,110 @@
+
+
+
+Debugging transported core dumps
+
+
+
+Debugging transported core dumps
+
+
+When a core dump is moved to a machine different from the one where it was
+produced ("transported core dump"), debuggers (dbx, gdb, windbg or SA) do not
+always successfully open the dump. This is due to kernel, library (shared
+objects or DLLs) mismatch between core dump machine and debugger machine.
+
+
+
+In most platforms, core dumps do not contain text (a.k.a) Code pages.
+There pages are to be read from executable and shared objects (or DLLs).
+Therefore it is important to have matching executable and shared object
+files in debugger machine.
+
+
+Solaris transported core dumps
+
+
+Debuggers on Solaris (and Linux) use two addtional shared objects
+rtld_db.so and libthread_db.so. rtld_db.so is used to
+read information on shared objects from the core dump. libthread_db.so
+is used to get information on threads from the core dump. rtld_db.so
+evolves along with rtld.so (the runtime linker library) and libthread_db.so
+evolves along with libthread.so (user land multithreading library).
+Hence, debugger machine should have right version of rtld_db.so and
+libthread_db.so to open the core dump successfully. More details on
+these debugger libraries can be found in
+
+Solaris Linkers and Libraries Guide - 817-1984
+
+
+Solaris SA against transported core dumps
+
+
+With transported core dumps, you may get "rtld_db failures" or
+"libthread_db failures" or SA may just throw some other error
+(hotspot symbol is missing) when opening the core dump.
+Enviroment variable LIBSAPROC_DEBUG may be set to any value
+to debug such scenarios. With this env. var set, SA prints many
+messages in standard error which can be useful for further debugging.
+SA on Solaris uses libproc.so library. This library also
+prints debug messages with env. var LIBPROC_DEBUG. But,
+setting LIBSAPROC_DEBUG results in setting LIBPROC_DEBUG as well.
+
+
+The best possible way to debug a transported core dump is to match the
+debugger machine to that of core dump machine. i.e., have same Kernel
+and libthread patch level between the machines. mdb (Solaris modular
+debugger) may be used to find the Kernel patch level of core dump
+machine and debugger machine may be brought to the same level.
+
+
+If the matching machine is "far off" in your network, then
+
+
+
+
+But, it may not be feasible to find matching machine to debug.
+If so, you can copy all application shared objects (and libthread_db.so, if needed) from the core dump
+machine into your debugger machine's directory, say, /export/applibs. Now, set SA_ALTROOT
+environment variable to point to /export/applibs directory. Note that /export/applibs should either
+contain matching 'full path' of libraries. i.e., /usr/lib/libthread_db.so from core
+machine should be under /export/applibs/use/lib directory and /use/java/jre/lib/sparc/client/libjvm.so
+from core machine should be under /export/applibs/use/java/jre/lib/sparc/client so on or /export/applibs
+should just contain libthread_db.so, libjvm.so etc. directly.
+
+
+
+Support for transported core dumps is not built into the standard version of libproc.so. You need to
+set LD_LIBRARY_PATH env var to point to the path of a specially built version of libproc.so.
+Note that this version of libproc.so has a special symbol to support transported core dump debugging.
+In future, we may get this feature built into standard libproc.so -- if that happens, this step (of
+setting LD_LIBRARY_PATH) can be skipped.
+
+
+Ignoring libthread_db.so failures
+
+If you are okay with missing thread related information, you can set
+SA_IGNORE_THREADDB environment variable to any value. With this
+set, SA ignores libthread_db failure, but you won't be able to get any
+thread related information. But, you would be able to use SA and get
+other information.
+
+
+Linux SA against transported core dumps
+
+On Linux, SA parses core and shared library ELF files. SA does not use
+libthread_db.so or rtld_db.so for core dump debugging (although
+libthread_db.so is used for live process debugging). But, you
+may still face problems with transported core dumps, because matching shared
+objects may not be in the path(s) specified in core dump file. To
+workaround this, you can define environment variable SA_ALTROOT
+to be the directory where shared libraries are kept. The semantics of
+this env. variable is same as that for Solaris (please refer above).
+
+
+
+
+
diff --git a/hotspot/agent/make/ClosureFinder.java b/hotspot/agent/make/ClosureFinder.java
new file mode 100644
index 00000000000..171ba5ff901
--- /dev/null
+++ b/hotspot/agent/make/ClosureFinder.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+import java.io.*;
+import java.util.*;
+
+
+/**
+ This class finds transitive closure of dependencies from a given
+root set of classes. If your project has lots of .class files and you
+want to ship only those .class files which are used (transitively)
+from a root set of classes, then you can use this utility.
+How does it work?
+
+ We walk through all constant pool entries of a given class and
+find all modified UTF-8 entries. Anything that looks like a class name is
+considered as a class and we search for that class in the given
+classpath. If we find a .class of that name, then we add that class to
+list.
+
+ We could have used CONSTANT_ClassInfo type constants only. But
+that will miss classes used through Class.forName or xyz.class
+construct. But, if you refer to a class name in some other string we
+would include it as dependency :(. But this is quite unlikely
+anyway. To look for exact Class.forName argument(s) would involve
+bytecode analysis. Also, we handle only simple reflection. If you
+accept name of a class from externally (for eg properties file or
+command line args for example, this utility will not be able to find
+that dependency. In such cases, include those classes in the root set.
+
+*/
+
+public class ClosureFinder {
+ private Collection roots; // root class names Collection
+ private Map visitedClasses; // set of all dependencies as a Map
+ private String classPath; // classpath to look for .class files
+ private String[] pathComponents; // classpath components
+ private static final boolean isWindows = File.separatorChar != '/';
+
+ public ClosureFinder(Collection roots, String classPath) {
+ this.roots = roots;
+ this.classPath = classPath;
+ parseClassPath();
+ }
+
+ // parse classPath into pathComponents array
+ private void parseClassPath() {
+ List paths = new ArrayList();
+ StringTokenizer st = new StringTokenizer(classPath, File.pathSeparator);
+ while (st.hasMoreTokens())
+ paths.add(st.nextToken());
+
+ Object[] arr = paths.toArray();
+ pathComponents = new String[arr.length];
+ System.arraycopy(arr, 0, pathComponents, 0, arr.length);
+ }
+
+ // if output is aleady not computed, compute it now
+ // result is a map from class file name to base path where the .class was found
+ public Map find() {
+ if (visitedClasses == null) {
+ visitedClasses = new HashMap();
+ computeClosure();
+ }
+ return visitedClasses;
+ }
+
+ // compute closure for all given root classes
+ private void computeClosure() {
+ for (Iterator rootsItr = roots.iterator(); rootsItr.hasNext();) {
+ String name = (String) rootsItr.next();
+ name = name.substring(0, name.indexOf(".class"));
+ computeClosure(name);
+ }
+ }
+
+
+ // looks up for .class in pathComponents and returns
+ // base path if found, else returns null
+ private String lookupClassFile(String classNameAsPath) {
+ for (int i = 0; i < pathComponents.length; i++) {
+ File f = new File(pathComponents[i] + File.separator +
+ classNameAsPath + ".class");
+ if (f.exists()) {
+ if (isWindows) {
+ String name = f.getName();
+ // Windows reports special devices AUX,NUL,CON as files
+ // under any directory. It does not care about file extention :-(
+ if (name.compareToIgnoreCase("AUX.class") == 0 ||
+ name.compareToIgnoreCase("NUL.class") == 0 ||
+ name.compareToIgnoreCase("CON.class") == 0) {
+ return null;
+ }
+ }
+ return pathComponents[i];
+ }
+ }
+ return null;
+ }
+
+
+ // from JVM spec. 2'nd edition section 4.4
+ private static final int CONSTANT_Class = 7;
+ private static final int CONSTANT_FieldRef = 9;
+ private static final int CONSTANT_MethodRef = 10;
+ private static final int CONSTANT_InterfaceMethodRef = 11;
+ private static final int CONSTANT_String = 8;
+ private static final int CONSTANT_Integer = 3;
+ private static final int CONSTANT_Float = 4;
+ private static final int CONSTANT_Long = 5;
+ private static final int CONSTANT_Double = 6;
+ private static final int CONSTANT_NameAndType = 12;
+ private static final int CONSTANT_Utf8 = 1;
+
+ // whether a given string may be a class name?
+ private boolean mayBeClassName(String internalClassName) {
+ int len = internalClassName.length();
+ for (int s = 0; s < len; s++) {
+ char c = internalClassName.charAt(s);
+ if (!Character.isJavaIdentifierPart(c) && c != '/')
+ return false;
+ }
+ return true;
+ }
+
+ // compute closure for a given class
+ private void computeClosure(String className) {
+ if (visitedClasses.get(className) != null) return;
+ String basePath = lookupClassFile(className);
+ if (basePath != null) {
+ visitedClasses.put(className, basePath);
+ try {
+ File classFile = new File(basePath + File.separator + className + ".class");
+ FileInputStream fis = new FileInputStream(classFile);
+ DataInputStream dis = new DataInputStream(fis);
+ // look for .class signature
+ if (dis.readInt() != 0xcafebabe) {
+ System.err.println(classFile.getAbsolutePath() + " is not a valid .class file");
+ return;
+ }
+
+ // ignore major and minor version numbers
+ dis.readShort();
+ dis.readShort();
+
+ // read number of constant pool constants
+ int numConsts = (int) dis.readShort();
+ String[] strings = new String[numConsts];
+
+ // zero'th entry is unused
+ for (int cpIndex = 1; cpIndex < numConsts; cpIndex++) {
+ int constType = (int) dis.readByte();
+ switch (constType) {
+ case CONSTANT_Class:
+ case CONSTANT_String:
+ dis.readShort(); // string name index;
+ break;
+
+ case CONSTANT_FieldRef:
+ case CONSTANT_MethodRef:
+ case CONSTANT_InterfaceMethodRef:
+ case CONSTANT_NameAndType:
+ case CONSTANT_Integer:
+ case CONSTANT_Float:
+ // all these are 4 byte constants
+ dis.readInt();
+ break;
+
+ case CONSTANT_Long:
+ case CONSTANT_Double:
+ // 8 byte constants
+ dis.readLong();
+ // occupies 2 cp entries
+ cpIndex++;
+ break;
+
+
+ case CONSTANT_Utf8: {
+ strings[cpIndex] = dis.readUTF();
+ break;
+ }
+
+ default:
+ System.err.println("invalid constant pool entry");
+ return;
+ }
+ }
+
+ // now walk thru the string constants and look for class names
+ for (int s = 0; s < numConsts; s++) {
+ if (strings[s] != null && mayBeClassName(strings[s]))
+ computeClosure(strings[s].replace('/', File.separatorChar));
+ }
+
+ } catch (IOException exp) {
+ // ignore for now
+ }
+
+ }
+ }
+
+ // a sample main that accepts roots classes in a file and classpath as args
+ public static void main(String[] args) {
+ if (args.length != 2) {
+ System.err.println("Usage: ClosureFinder ");
+ System.exit(1);
+ }
+
+ List roots = new ArrayList();
+ try {
+ FileInputStream fis = new FileInputStream(args[0]);
+ DataInputStream dis = new DataInputStream(fis);
+ String line = null;
+ while ((line = dis.readLine()) != null) {
+ if (isWindows) {
+ line = line.replace('/', File.separatorChar);
+ }
+ roots.add(line);
+ }
+ } catch (IOException exp) {
+ System.err.println(exp.getMessage());
+ System.exit(2);
+ }
+
+ ClosureFinder cf = new ClosureFinder(roots, args[1]);
+ Map out = cf.find();
+ Iterator res = out.keySet().iterator();
+ for(; res.hasNext(); ) {
+ String className = (String) res.next();
+ System.out.println(className + ".class");
+ }
+ }
+}
diff --git a/hotspot/agent/make/Makefile b/hotspot/agent/make/Makefile
new file mode 100644
index 00000000000..0cde8d5754b
--- /dev/null
+++ b/hotspot/agent/make/Makefile
@@ -0,0 +1,312 @@
+#
+# Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+# This guards against adding broken .java files to the directory
+# hierarchy, but may be a pain to keep in sync
+
+# Generated using the build-pkglist script
+ifeq "x$(GAMMADIR)" "x"
+include ../../make/defs.make
+else
+include $(GAMMADIR)/make/defs.make
+endif
+
+PKGLIST = \
+sun.jvm.hotspot \
+sun.jvm.hotspot.asm \
+sun.jvm.hotspot.asm.amd64 \
+sun.jvm.hotspot.asm.ia64 \
+sun.jvm.hotspot.asm.sparc \
+sun.jvm.hotspot.asm.x86 \
+sun.jvm.hotspot.bugspot \
+sun.jvm.hotspot.bugspot.tree \
+sun.jvm.hotspot.c1 \
+sun.jvm.hotspot.code \
+sun.jvm.hotspot.compiler \
+sun.jvm.hotspot.debugger \
+sun.jvm.hotspot.debugger.amd64 \
+sun.jvm.hotspot.debugger.cdbg \
+sun.jvm.hotspot.debugger.cdbg.basic \
+sun.jvm.hotspot.debugger.cdbg.basic.amd64 \
+sun.jvm.hotspot.debugger.cdbg.basic.x86 \
+sun.jvm.hotspot.debugger.dbx \
+sun.jvm.hotspot.debugger.dbx.sparc \
+sun.jvm.hotspot.debugger.dbx.x86 \
+sun.jvm.hotspot.debugger.dummy \
+sun.jvm.hotspot.debugger.ia64 \
+sun.jvm.hotspot.debugger.linux \
+sun.jvm.hotspot.debugger.linux.amd64 \
+sun.jvm.hotspot.debugger.linux.ia64 \
+sun.jvm.hotspot.debugger.linux.x86 \
+sun.jvm.hotspot.debugger.posix \
+sun.jvm.hotspot.debugger.posix.elf \
+sun.jvm.hotspot.debugger.proc \
+sun.jvm.hotspot.debugger.proc.amd64 \
+sun.jvm.hotspot.debugger.proc.sparc \
+sun.jvm.hotspot.debugger.proc.x86 \
+sun.jvm.hotspot.debugger.remote \
+sun.jvm.hotspot.debugger.remote.amd64 \
+sun.jvm.hotspot.debugger.remote.sparc \
+sun.jvm.hotspot.debugger.remote.x86 \
+sun.jvm.hotspot.debugger.sparc \
+sun.jvm.hotspot.debugger.win32 \
+sun.jvm.hotspot.debugger.win32.coff \
+sun.jvm.hotspot.debugger.windbg \
+sun.jvm.hotspot.debugger.windbg.amd64 \
+sun.jvm.hotspot.debugger.windbg.ia64 \
+sun.jvm.hotspot.debugger.windbg.x86 \
+sun.jvm.hotspot.debugger.x86 \
+sun.jvm.hotspot.gc_implementation \
+sun.jvm.hotspot.gc_implementation.parallelScavenge \
+sun.jvm.hotspot.gc_implementation.shared \
+sun.jvm.hotspot.gc_interface \
+sun.jvm.hotspot.interpreter \
+sun.jvm.hotspot.jdi \
+sun.jvm.hotspot.livejvm \
+sun.jvm.hotspot.memory \
+sun.jvm.hotspot.oops \
+sun.jvm.hotspot.runtime \
+sun.jvm.hotspot.runtime.amd64 \
+sun.jvm.hotspot.runtime.ia64 \
+sun.jvm.hotspot.runtime.linux \
+sun.jvm.hotspot.runtime.linux_amd64 \
+sun.jvm.hotspot.runtime.linux_ia64 \
+sun.jvm.hotspot.runtime.linux_sparc \
+sun.jvm.hotspot.runtime.linux_x86 \
+sun.jvm.hotspot.runtime.posix \
+sun.jvm.hotspot.runtime.solaris_amd64 \
+sun.jvm.hotspot.runtime.solaris_sparc \
+sun.jvm.hotspot.runtime.solaris_x86 \
+sun.jvm.hotspot.runtime.sparc \
+sun.jvm.hotspot.runtime.win32_amd64 \
+sun.jvm.hotspot.runtime.win32_ia64 \
+sun.jvm.hotspot.runtime.win32_x86 \
+sun.jvm.hotspot.runtime.x86 \
+sun.jvm.hotspot.tools \
+sun.jvm.hotspot.tools.jcore \
+sun.jvm.hotspot.tools.soql \
+sun.jvm.hotspot.types \
+sun.jvm.hotspot.types.basic \
+sun.jvm.hotspot.ui \
+sun.jvm.hotspot.ui.action \
+sun.jvm.hotspot.ui.classbrowser \
+sun.jvm.hotspot.ui.resources \
+sun.jvm.hotspot.ui.table \
+sun.jvm.hotspot.ui.tree \
+sun.jvm.hotspot.ui.treetable \
+sun.jvm.hotspot.utilities \
+sun.jvm.hotspot.utilities.memo \
+sun.jvm.hotspot.utilities.soql
+#END PKGLIST
+
+# Generated using the build-filelist script
+FILELIST = \
+sun/jvm/hotspot/*.java \
+sun/jvm/hotspot/asm/*.java \
+sun/jvm/hotspot/asm/amd64/*.java \
+sun/jvm/hotspot/asm/ia64/*.java \
+sun/jvm/hotspot/asm/sparc/*.java \
+sun/jvm/hotspot/asm/x86/*.java \
+sun/jvm/hotspot/bugspot/*.java \
+sun/jvm/hotspot/bugspot/tree/*.java \
+sun/jvm/hotspot/c1/*.java \
+sun/jvm/hotspot/code/*.java \
+sun/jvm/hotspot/compiler/*.java \
+sun/jvm/hotspot/debugger/*.java \
+sun/jvm/hotspot/debugger/amd64/*.java \
+sun/jvm/hotspot/debugger/cdbg/*.java \
+sun/jvm/hotspot/debugger/cdbg/basic/*.java \
+sun/jvm/hotspot/debugger/cdbg/basic/amd64/*.java \
+sun/jvm/hotspot/debugger/cdbg/basic/x86/*.java \
+sun/jvm/hotspot/debugger/dbx/*.java \
+sun/jvm/hotspot/debugger/dbx/sparc/*.java \
+sun/jvm/hotspot/debugger/dbx/x86/*.java \
+sun/jvm/hotspot/debugger/dummy/*.java \
+sun/jvm/hotspot/debugger/ia64/*.java \
+sun/jvm/hotspot/debugger/linux/*.java \
+sun/jvm/hotspot/debugger/linux/x86/*.java \
+sun/jvm/hotspot/debugger/posix/*.java \
+sun/jvm/hotspot/debugger/posix/elf/*.java \
+sun/jvm/hotspot/debugger/proc/*.java \
+sun/jvm/hotspot/debugger/proc/amd64/*.java \
+sun/jvm/hotspot/debugger/proc/sparc/*.java \
+sun/jvm/hotspot/debugger/proc/x86/*.java \
+sun/jvm/hotspot/debugger/remote/*.java \
+sun/jvm/hotspot/debugger/remote/amd64/*.java \
+sun/jvm/hotspot/debugger/remote/sparc/*.java \
+sun/jvm/hotspot/debugger/remote/x86/*.java \
+sun/jvm/hotspot/debugger/sparc/*.java \
+sun/jvm/hotspot/debugger/win32/*.java \
+sun/jvm/hotspot/debugger/win32/coff/*.java \
+sun/jvm/hotspot/debugger/windbg/*.java \
+sun/jvm/hotspot/debugger/windbg/ia64/*.java \
+sun/jvm/hotspot/debugger/windbg/x86/*.java \
+sun/jvm/hotspot/debugger/x86/*.java \
+sun/jvm/hotspot/interpreter/*.java \
+sun/jvm/hotspot/jdi/*.java \
+sun/jvm/hotspot/livejvm/*.java \
+sun/jvm/hotspot/memory/*.java \
+sun/jvm/hotspot/oops/*.java \
+sun/jvm/hotspot/runtime/*.java \
+sun/jvm/hotspot/runtime/amd64/*.java \
+sun/jvm/hotspot/runtime/ia64/*.java \
+sun/jvm/hotspot/runtime/linux/*.java \
+sun/jvm/hotspot/runtime/linux_amd64/*.java \
+sun/jvm/hotspot/runtime/linux_ia64/*.java \
+sun/jvm/hotspot/runtime/linux_sparc/*.java \
+sun/jvm/hotspot/runtime/linux_x86/*.java \
+sun/jvm/hotspot/runtime/posix/*.java \
+sun/jvm/hotspot/runtime/solaris_amd64/*.java \
+sun/jvm/hotspot/runtime/solaris_sparc/*.java \
+sun/jvm/hotspot/runtime/solaris_x86/*.java \
+sun/jvm/hotspot/runtime/sparc/*.java \
+sun/jvm/hotspot/runtime/win32_amd64/*.java \
+sun/jvm/hotspot/runtime/win32_ia64/*.java \
+sun/jvm/hotspot/runtime/win32_x86/*.java \
+sun/jvm/hotspot/runtime/x86/*.java \
+sun/jvm/hotspot/tools/*.java \
+sun/jvm/hotspot/tools/jcore/*.java \
+sun/jvm/hotspot/tools/soql/*.java \
+sun/jvm/hotspot/types/*.java \
+sun/jvm/hotspot/types/basic/*.java \
+sun/jvm/hotspot/ui/*.java \
+sun/jvm/hotspot/ui/action/*.java \
+sun/jvm/hotspot/ui/classbrowser/*.java \
+sun/jvm/hotspot/ui/table/*.java \
+sun/jvm/hotspot/ui/tree/*.java \
+sun/jvm/hotspot/ui/treetable/*.java \
+sun/jvm/hotspot/utilities/*.java \
+sun/jvm/hotspot/utilities/memo/*.java \
+sun/jvm/hotspot/utilities/soql/*.java
+#END FILELIST
+
+ifneq "x$(ALT_BOOTDIR)" "x"
+ BOOTDIR := $(ALT_BOOTDIR)
+endif
+
+ifeq "x$(BOOTDIR)" "x"
+ JDK_HOME := $(shell dirname $(shell which java))/..
+else
+ JDK_HOME := $(BOOTDIR)
+endif
+
+isUnix := $(shell test -r c:/; echo $$?)
+
+ifeq "$(isUnix)" "1"
+ CPS := :
+else
+ CPS := ";"
+endif
+
+SRC_DIR = ../src/share/classes
+LIB_DIR = ../src/share/lib
+CLOSED_LIB_DIR = ../closed/src/share/lib
+BUILD_DIR = ../build
+OUTPUT_DIR = $(BUILD_DIR)/classes
+DOC_DIR = $(BUILD_DIR)/doc
+
+# gnumake 3.78.1 does not accept the *s,
+# so use the shell to expand them
+ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST))
+ALLFILES := $(shell /bin/ls $(ALLFILES))
+
+
+# tools.jar is needed by the JDI - SA binding
+CLASSPATH = $(LIB_DIR)/maf-1_0.jar$(CPS)$(JDK_HOME)/lib/tools.jar
+CLASSPATH := $(subst \,/,$(CLASSPATH))
+
+# FIXME: autogenerate call to rmic
+
+SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)"
+
+SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties
+
+# Tagging it on because there's no reason not to run it
+all: filelist
+ @mkdir -p $(OUTPUT_DIR)
+ @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
+ @javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
+ @rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
+ rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
+ cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
+
+allprof: filelist
+ @mkdir -p $(OUTPUT_DIR)
+ @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
+ @javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
+ @rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
+ rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
+ cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
+
+filelist: $(ALLFILES)
+ @if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \
+ echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA."; \
+ echo ""; \
+ exit 1; \
+ fi
+ @rm -f $@
+ @echo $(ALLFILES) > $@
+
+.PHONY: natives
+natives:
+ cd ../src/os/`java -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) all
+
+.PHONY: sa-jdi.jar
+sa-jdi.jar:
+ if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \
+ echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA.";\
+ exit 1; \
+ fi
+ rm -f $(BUILD_DIR)/sa-jdi.jar
+ rm -f $(OUTPUT_DIR)/jdi_class_files
+ javac -source 1.4 ClosureFinder.java -d $(OUTPUT_DIR)
+ cd $(OUTPUT_DIR) ; find sun/jvm/hotspot/jdi -name "*.class" > jdi_class_files
+ cd $(OUTPUT_DIR) ; jar cvf ../sa-jdi.jar `java ClosureFinder jdi_class_files .`
+ cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
+ cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(OUTPUT_DIR) sa.properties
+ rm -f $(OUTPUT_DIR)/ClosureFinder.class
+ rm -f $(OUTPUT_DIR)/jdi_class_files
+
+docs:
+ @javadoc -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST)
+
+sizes: $(ALLFILES)
+ wc -l $(ALLFILES)
+
+cscope: $(ALLFILES)
+ echo $(ALLFILES) > java.files
+ cscope -b -i java.files -f java.out
+
+.PHONY: sa.jar
+sa.jar:
+ rm -f $(BUILD_DIR)/sa.jar
+ mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources
+ rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/*
+ cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/
+ cd $(OUTPUT_DIR) ; jar cvf ../sa.jar *
+
+clean::
+ rm -rf filelist
+ cd ../src/os/`java -classpath $(OUTPUT_DIR) sun.jvm.hotspot.utilities.PlatformInfo`; $(MAKE) clean
+ rm -rf $(BUILD_DIR)/*
diff --git a/hotspot/agent/make/README.txt b/hotspot/agent/make/README.txt
new file mode 100644
index 00000000000..1ceb26b9339
--- /dev/null
+++ b/hotspot/agent/make/README.txt
@@ -0,0 +1,5 @@
+These are the Java-level sources for the Serviceability Agent (SA).
+
+To build, type "gnumake all".
+
+For usage documentation, please refer to ../doc/index.html.
diff --git a/hotspot/agent/make/bugspot.bat b/hotspot/agent/make/bugspot.bat
new file mode 100644
index 00000000000..da0880c4da8
--- /dev/null
+++ b/hotspot/agent/make/bugspot.bat
@@ -0,0 +1,25 @@
+REM
+REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main
diff --git a/hotspot/agent/make/build-filelist b/hotspot/agent/make/build-filelist
new file mode 100644
index 00000000000..34bd51422c8
--- /dev/null
+++ b/hotspot/agent/make/build-filelist
@@ -0,0 +1,10 @@
+#!/bin/sh -f
+
+SH=`which sh`
+MKS_HOME=`dirname $SH`
+
+CD=cd
+FIND=$MKS_HOME/find
+SORT=$MKS_HOME/sort
+
+$CD ../src/share/classes; $FIND sun \( -name SCCS -prune \) -o \( -name "*.java" \) -print | $SORT > ../../../make/filelist.txt
diff --git a/hotspot/agent/make/build-pkglist b/hotspot/agent/make/build-pkglist
new file mode 100644
index 00000000000..64d9a96cabb
--- /dev/null
+++ b/hotspot/agent/make/build-pkglist
@@ -0,0 +1,11 @@
+#!/bin/sh -f
+
+SH=`which sh`
+MKS_HOME=`dirname $SH`
+
+CD=cd
+FIND=$MKS_HOME/find
+SED=$MKS_HOME/sed
+SORT=$MKS_HOME/sort
+
+$CD ../src/share/classes; $FIND sun/jvm/hotspot \( -name SCCS -prune \) -o -type d -print | $SED -e 's/\//./g' | $SORT > ../../../make/pkglist.txt
diff --git a/hotspot/agent/make/build.xml b/hotspot/agent/make/build.xml
new file mode 100644
index 00000000000..ebd5d39b785
--- /dev/null
+++ b/hotspot/agent/make/build.xml
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hotspot/agent/make/clhsdbproc.sh b/hotspot/agent/make/clhsdbproc.sh
new file mode 100644
index 00000000000..033b7888ec9
--- /dev/null
+++ b/hotspot/agent/make/clhsdbproc.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+#
+# Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.CLHSDB $*
diff --git a/hotspot/agent/make/clhsdbproc64.sh b/hotspot/agent/make/clhsdbproc64.sh
new file mode 100644
index 00000000000..e452ab6acc8
--- /dev/null
+++ b/hotspot/agent/make/clhsdbproc64.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+#
+# Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.CLHSDB $*
diff --git a/hotspot/agent/make/clhsdbwindbg.bat b/hotspot/agent/make/clhsdbwindbg.bat
new file mode 100644
index 00000000000..0b9be545b27
--- /dev/null
+++ b/hotspot/agent/make/clhsdbwindbg.bat
@@ -0,0 +1,29 @@
+@echo off
+
+REM
+REM Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.CLHSDB %1 %2
diff --git a/hotspot/agent/make/clhsdbwindbg64.bat b/hotspot/agent/make/clhsdbwindbg64.bat
new file mode 100644
index 00000000000..07885f70bcc
--- /dev/null
+++ b/hotspot/agent/make/clhsdbwindbg64.bat
@@ -0,0 +1,29 @@
+@echo off
+
+REM
+REM Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.CLHSDB %1 %2
diff --git a/hotspot/agent/make/dumpflagsproc.sh b/hotspot/agent/make/dumpflagsproc.sh
new file mode 100644
index 00000000000..f79e9038ffc
--- /dev/null
+++ b/hotspot/agent/make/dumpflagsproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.FlagDumper $*
diff --git a/hotspot/agent/make/dumpflagsproc64.sh b/hotspot/agent/make/dumpflagsproc64.sh
new file mode 100644
index 00000000000..80f56164b26
--- /dev/null
+++ b/hotspot/agent/make/dumpflagsproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.FlagDumper $*
diff --git a/hotspot/agent/make/dumpflagswindbg.bat b/hotspot/agent/make/dumpflagswindbg.bat
new file mode 100644
index 00000000000..1fc80034e54
--- /dev/null
+++ b/hotspot/agent/make/dumpflagswindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.FlagDumper %1 %2
diff --git a/hotspot/agent/make/dumpflagswindbg64.bat b/hotspot/agent/make/dumpflagswindbg64.bat
new file mode 100644
index 00000000000..c5d0907006f
--- /dev/null
+++ b/hotspot/agent/make/dumpflagswindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.FlagDumper %1 %2
diff --git a/hotspot/agent/make/dumpsyspropsproc.sh b/hotspot/agent/make/dumpsyspropsproc.sh
new file mode 100644
index 00000000000..af2c1e31913
--- /dev/null
+++ b/hotspot/agent/make/dumpsyspropsproc.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.SysPropsDumper $*
+
diff --git a/hotspot/agent/make/dumpsyspropsproc64.sh b/hotspot/agent/make/dumpsyspropsproc64.sh
new file mode 100644
index 00000000000..fa9dd036f94
--- /dev/null
+++ b/hotspot/agent/make/dumpsyspropsproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.SysPropsDumper $*
diff --git a/hotspot/agent/make/dumpsyspropswindbg.bat b/hotspot/agent/make/dumpsyspropswindbg.bat
new file mode 100644
index 00000000000..43622cfd798
--- /dev/null
+++ b/hotspot/agent/make/dumpsyspropswindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.SysPropsDumper %1 %2
diff --git a/hotspot/agent/make/dumpsyspropswindbg64.bat b/hotspot/agent/make/dumpsyspropswindbg64.bat
new file mode 100644
index 00000000000..535d2c6f05b
--- /dev/null
+++ b/hotspot/agent/make/dumpsyspropswindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.SysPropsDumper %1 %2
diff --git a/hotspot/agent/make/finalizerinfoproc.sh b/hotspot/agent/make/finalizerinfoproc.sh
new file mode 100644
index 00000000000..1296a209735
--- /dev/null
+++ b/hotspot/agent/make/finalizerinfoproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.FinalizerInfo $*
diff --git a/hotspot/agent/make/finalizerinfoproc64.sh b/hotspot/agent/make/finalizerinfoproc64.sh
new file mode 100644
index 00000000000..afd850d85d2
--- /dev/null
+++ b/hotspot/agent/make/finalizerinfoproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.FinalizerInfo $*
diff --git a/hotspot/agent/make/finalizerinfowindbg.bat b/hotspot/agent/make/finalizerinfowindbg.bat
new file mode 100644
index 00000000000..0fa549fd546
--- /dev/null
+++ b/hotspot/agent/make/finalizerinfowindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.FinalizerInfo %1 %2
diff --git a/hotspot/agent/make/finalizerinfowindbg64.bat b/hotspot/agent/make/finalizerinfowindbg64.bat
new file mode 100644
index 00000000000..e8c52a17f50
--- /dev/null
+++ b/hotspot/agent/make/finalizerinfowindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.FinalizerInfo %1 %2
diff --git a/hotspot/agent/make/grantAll.policy b/hotspot/agent/make/grantAll.policy
new file mode 100644
index 00000000000..8ab626ec18a
--- /dev/null
+++ b/hotspot/agent/make/grantAll.policy
@@ -0,0 +1,30 @@
+//
+// Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+//
+// This code is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License version 2 only, as
+// published by the Free Software Foundation.
+//
+// This code 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
+// version 2 for more details (a copy is included in the LICENSE file that
+// accompanied this code).
+//
+// You should have received a copy of the GNU General Public License version
+// 2 along with this work; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+// CA 95054 USA or visit www.sun.com if you need additional information or
+// have any questions.
+//
+//
+
+// Do NOT use this policy file in a production system!
+
+grant {
+ // Allow everything for now
+ permission java.security.AllPermission;
+};
diff --git a/hotspot/agent/make/heapdumpproc.sh b/hotspot/agent/make/heapdumpproc.sh
new file mode 100644
index 00000000000..c58a206da60
--- /dev/null
+++ b/hotspot/agent/make/heapdumpproc.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+#
+# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.HeapDumper $*
diff --git a/hotspot/agent/make/heapdumpproc64.sh b/hotspot/agent/make/heapdumpproc64.sh
new file mode 100644
index 00000000000..f1d2135f6c9
--- /dev/null
+++ b/hotspot/agent/make/heapdumpproc64.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+#
+# Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.HeapDumper $*
+
diff --git a/hotspot/agent/make/heapdumpwindbg.bat b/hotspot/agent/make/heapdumpwindbg.bat
new file mode 100644
index 00000000000..9711559ea49
--- /dev/null
+++ b/hotspot/agent/make/heapdumpwindbg.bat
@@ -0,0 +1,29 @@
+@echo off
+
+REM
+REM Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.HeapDumper %1 %2 %3 %4
diff --git a/hotspot/agent/make/heapdumpwindbg64.bat b/hotspot/agent/make/heapdumpwindbg64.bat
new file mode 100644
index 00000000000..7375d5fb051
--- /dev/null
+++ b/hotspot/agent/make/heapdumpwindbg64.bat
@@ -0,0 +1,29 @@
+@echo off
+
+REM
+REM Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.HeapDumper %1 %2 %3 %4
diff --git a/hotspot/agent/make/heapsumproc.sh b/hotspot/agent/make/heapsumproc.sh
new file mode 100644
index 00000000000..5fd95823069
--- /dev/null
+++ b/hotspot/agent/make/heapsumproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.HeapSummary $*
diff --git a/hotspot/agent/make/heapsumproc64.sh b/hotspot/agent/make/heapsumproc64.sh
new file mode 100644
index 00000000000..7c0d0293a84
--- /dev/null
+++ b/hotspot/agent/make/heapsumproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.HeapSummary $*
diff --git a/hotspot/agent/make/heapsumwindbg.bat b/hotspot/agent/make/heapsumwindbg.bat
new file mode 100644
index 00000000000..4221de1064f
--- /dev/null
+++ b/hotspot/agent/make/heapsumwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.HeapSummary %1 %2
diff --git a/hotspot/agent/make/heapsumwindbg64.bat b/hotspot/agent/make/heapsumwindbg64.bat
new file mode 100644
index 00000000000..245e8edcb28
--- /dev/null
+++ b/hotspot/agent/make/heapsumwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.HeapSummary %1 %2
diff --git a/hotspot/agent/make/hsdb.bat b/hotspot/agent/make/hsdb.bat
new file mode 100644
index 00000000000..6b12916d998
--- /dev/null
+++ b/hotspot/agent/make/hsdb.bat
@@ -0,0 +1,25 @@
+REM
+REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2
diff --git a/hotspot/agent/make/hsdb.sh b/hotspot/agent/make/hsdb.sh
new file mode 100644
index 00000000000..3e5cc2df040
--- /dev/null
+++ b/hotspot/agent/make/hsdb.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+STARTDIR=`dirname $0`
+
+if [ "x$SA_JAVA" = "x" ]; then
+ SA_JAVA=java
+fi
+
+$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $*
diff --git a/hotspot/agent/make/hsdbproc.sh b/hotspot/agent/make/hsdbproc.sh
new file mode 100644
index 00000000000..d84dfa56202
--- /dev/null
+++ b/hotspot/agent/make/hsdbproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.HSDB $*
diff --git a/hotspot/agent/make/hsdbproc64.sh b/hotspot/agent/make/hsdbproc64.sh
new file mode 100644
index 00000000000..4710d38ad47
--- /dev/null
+++ b/hotspot/agent/make/hsdbproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.HSDB $*
diff --git a/hotspot/agent/make/hsdbwindbg.bat b/hotspot/agent/make/hsdbwindbg.bat
new file mode 100644
index 00000000000..9cc82ec6cf5
--- /dev/null
+++ b/hotspot/agent/make/hsdbwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.HSDB %1 %2
diff --git a/hotspot/agent/make/hsdbwindbg64.bat b/hotspot/agent/make/hsdbwindbg64.bat
new file mode 100644
index 00000000000..3f1bb170188
--- /dev/null
+++ b/hotspot/agent/make/hsdbwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.HSDB %1 %2
diff --git a/hotspot/agent/make/index.html b/hotspot/agent/make/index.html
new file mode 100644
index 00000000000..436daaa2b8c
--- /dev/null
+++ b/hotspot/agent/make/index.html
@@ -0,0 +1,262 @@
+
+
+
+
+
+Using The HotSpot Serviceability Agent
+
+
+
+
+
+Using The HotSpot Serviceability Agent
+
+
+
+
+Contents
+
+
+
+
+
+
+
+
+The HotSpot Serviceability Agent (SA) is a set of Java APIs which
+mirror the internal APIs of the HotSpot VM and which can be used to
+examine the state of a HotSpot VM.
+
+
+
+The system understands the layout of certain VM data structures and is
+able to traverse these structures in an examination-only fashion; that
+is, it does not rely on being able to run code in the target VM. For
+this reason it transparently works with either a running VM or a core
+file.
+
+
+
+The system can reconstruct information about Java frames on the stack
+and objects in the heap. Many of the important data structures in the
+VM like the CodeCache, Universe, StubQueue, Frames, and VFrames have
+been exposed and have relatively complete (or at least useful)
+implementations.
+
+
+
+A small graphical debugger called HSDB (the "HotSpot Debugger") has
+been written using these APIs. It provides stack memory dumps
+annotated with method invocations, compiled-code inlining (if
+present), interpreted vs. compiled code, interpreter codelets (if
+interpreted), and live oops from oop-map information. It also provides
+a tree-based oop inspector. More information will be added as
+necessary; please send
+email with suggestions on what would be useful.
+
+
+
+The SA currently only works on Solaris. It uses dbx to connect to the
+remote process or core file and communicates with a small piece of
+code (an "import module") loaded into the debugger.
+
+
+
+
+
+The Java-side source code, which is the bulk of the SA, is in
+src/share/vm/agent. The organization of the sun.jvm.hotspot package
+hierarchy mirrors the organization in the VM. This should allow
+engineers familiar with the HotSpot sources to quickly understand how
+the SA works and to make modifications if necessary. To build these
+sources, cd to src/share/vm/agent and type "make".
+
+
+
+
+The SA on Solaris works by communicating with a small piece of code
+(an "import module") loaded into dbx. The source code for this import
+module is in src/os/solaris/agent. To build this library, cd to
+src/os/solaris/agent and type "make 32bit" or "make 64bit". The
+distinction is necessary because the SPARC version of dbx ships with
+two versions of its executable, and depending on which architecture
+(v8 or v9) the debugger is running on selects the appropriate
+executable. The SA tries the v8 version first, but if you are running
+on a v9 machine you must provide both versions to the SA.
+
+
+
+
+The system is currently hardwired to look on jano for its dbx
+executable and import module. The relevant directory structure looks
+like this:
+
+
+ - .../hotspot/sa/
+
+ - solaris/
+
+ - sparc/
+
+ - bin/
+
+ - dbx: symlink to (v8) dbx 7.0 executable
+
+
+
+ - lib/
+
+ - libsvc_agent_dbx.so: 32-bit version of import module
+
+
+ - sparcv9/
+
+ - lib/
+
+ - libsvc_agent_dbx.so: 32-bit version of import module
+
+
+
+
+
+
+
+
+The code which builds up path names to these executables is contained
+in sun.jvm.hotspot.HotSpotAgent.java. There are hardcoded paths in
+this file to jano, but the rest of the system is isolated from this.
+
+
+
+(It would be nice to have a panel in the debugger allowing
+configuration of all of the known operating systems' options; right
+now Solaris is the only supported OS, making that easier.)
+
+
+
+
+
+An installation of HSDB has been placed on jano. To access it, add the
+following directory to your PATH:
+
+
+
+
+ /net/jano/export/disk05/hotspot/sa/bin/common
+
+
+
+
+To start the debugger, type "hsdb".
+
+
+
+Alternatively, you can start a local build of the debugger by building
+the sources in src/share/vm/agent, cd'ing to that directory, and
+typing "java sun.jvm.hotspot.HSDB".
+
+
+
+There are three modes for the debugger: attaching to a local process,
+opening a core file, and attaching to a remote "debug server". The
+remote case requires two programs to be running on the remote machine:
+the rmiregistry (see the script "start-rmiregistry" in this directory;
+run this in the background) and the debug server (see the script
+"start-debug-server"), in that order. start-rmiregistry takes no
+arguments; start-debug-server takes as argument the process ID or the
+executable and core file names to allow remote debugging of. Make sure
+you do NOT have a CLASSPATH environment variable set when you run
+these scripts. (The classes put into the rmiregistry are in sun.*, and
+there are permissions problems if they aren't placed on the boot
+classpath.)
+
+
+
+NOTE that the SA currently only works against VMs on Solaris/SPARC.
+Remote debugging of Solaris/SPARC VMs on arbitrary platforms is
+possible using the debug server; select "Connect to debug server..."
+in HSDB.
+
+
+
+Once the debugger has been launched, the threads list is displayed.
+The current set of functionality allows:
+
+
+
+- Browsing of the annotated stack memory ("Stack Memory" button). It
+ is currently annotated with the following information:
+
+ - Method names of the Java frames and their extents (supporting
+ inlined compiled methods)
+
- Locations and types of oops, found using the oop map information
+ from compiled methods (interpreter oop maps coming soon)
+
- If a Java frame was interrupted by a signal (e.g., because of a
+ crash), annotates the frame with the signal name and number
+
- Interpreter codelet descriptions for interpreted frames
+
+ - Finding which thread or threads caused a crash (currently
+ identified by the presence of a signal handler frame)
+
- Browsing of oops using the Oop Inspector.
+
- Browsing of the java.lang.Thread object's oop.
+
- Object histogram and inspection of objects therein.
+
+
+
+
+More functionality is planned. Please send email with suggestions on what
+would be useful, with any questions or comments, or if the debugger
+crashes.
+
+
+
+
+
+HSDB does not suspend the system at a safepoint, but at an arbitrary
+point. This means that many of the invariants in the VM's code are not
+followed.
+
+
+
+As it happens, most of the places where the code ported over from the
+VM has failed involve the topmost frame on the stack. Some
+modifications have been made to allow the system to recognize
+problematic situations.
+
+
+
+Certainly, not all of the failure modes of the debugger have been
+found. Please send email if
+HSDB throws an exception. The best debugging aid in these situations
+is a core file since it is a static view of the VM to which we can
+then adapt the debugger code, as opposed to having to try to suspend
+the VM over and over to reproduce the failure. gcore (1) is a useful
+tool. (NOTE: do not try gcore with any application using the DGA X
+server extension (example: Java2Demo); the kernel will panic. See bug
+4343237.)
+
+
+
+
diff --git a/hotspot/agent/make/jcoreproc.sh b/hotspot/agent/make/jcoreproc.sh
new file mode 100644
index 00000000000..c38243f39e4
--- /dev/null
+++ b/hotspot/agent/make/jcoreproc.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+# set the environment variable JCORE_PACKAGES to a comma separated list of
+# packages whose classes have to be retrieved from the core file.
+
+$SA_JAVA_CMD -Dsun.jvm.hotspot.tools.jcore.filter=sun.jvm.hotspot.tools.jcore.PackageNameFilter -Dsun.jvm.hotspot.tools.jcore.PackageNameFilter.pkgList=$JCORE_PACKAGES sun.jvm.hotspot.tools.jcore.ClassDump $*
diff --git a/hotspot/agent/make/jcoreproc64.sh b/hotspot/agent/make/jcoreproc64.sh
new file mode 100644
index 00000000000..64530cf1300
--- /dev/null
+++ b/hotspot/agent/make/jcoreproc64.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+# set the environment variable JCORE_PACKAGES to a comma separated list of
+# packages whose classes have to be retrieved from the core file.
+
+$SA_JAVA_CMD -Dsun.jvm.hotspot.tools.jcore.filter=sun.jvm.hotspot.tools.jcore.PackageNameFilter -Dsun.jvm.hotspot.tools.jcore.PackageNameFilter.pkgList=$JCORE_PACKAGES sun.jvm.hotspot.tools.jcore.ClassDump $*
diff --git a/hotspot/agent/make/jcorewindbg.bat b/hotspot/agent/make/jcorewindbg.bat
new file mode 100644
index 00000000000..e368d03f97e
--- /dev/null
+++ b/hotspot/agent/make/jcorewindbg.bat
@@ -0,0 +1,33 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+REM set the environment variable JCORE_PACKAGES to comman separated list of
+REM packages whose classes have to be retrieved from the core file.
+
+%SA_JAVA_CMD% -Dsun.jvm.hotspot.tools.jcore.filter=sun.jvm.hotspot.tools.jcore.PackageNameFilter -Dsun.jvm.hotspot.tools.jcore.PackageNameFilter.pkgList=%JCORE_PACKAGES% sun.jvm.hotspot.tools.jcore.ClassDump %1 %2
+
+
diff --git a/hotspot/agent/make/jcorewindbg64.bat b/hotspot/agent/make/jcorewindbg64.bat
new file mode 100644
index 00000000000..ecd162b4509
--- /dev/null
+++ b/hotspot/agent/make/jcorewindbg64.bat
@@ -0,0 +1,33 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+REM set the environment variable JCORE_PACKAGES to comman separated list of
+REM packages whose classes have to be retrieved from the core file.
+
+%SA_JAVA_CMD% -Dsun.jvm.hotspot.tools.jcore.filter=sun.jvm.hotspot.tools.jcore.PackageNameFilter -Dsun.jvm.hotspot.tools.jcore.PackageNameFilter.pkgList=%JCORE_PACKAGES% sun.jvm.hotspot.tools.jcore.ClassDump %1 %2
+
+
diff --git a/hotspot/agent/make/jdbcore.sh b/hotspot/agent/make/jdbcore.sh
new file mode 100644
index 00000000000..703767c891d
--- /dev/null
+++ b/hotspot/agent/make/jdbcore.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+usage()
+{
+ echo "usage: $0 "
+ exit 1
+}
+#
+if [ $# -lt 2 ]; then
+ usage
+else
+ EXEC_FILE="${1}"
+ CORE_FILE="${2}"
+ echo "$0 attaching to core=${CORE_FILE}"
+fi
+#
+
+. `dirname $0`/saenv.sh
+
+$JAVA_HOME/bin/jdb -J-Xbootclasspath/a:$SA_CLASSPATH:$JAVA_HOME/lib/tools.jar \
+ -J-Dsun.boot.library.path=$JAVA_HOME/jre/lib/$CPU:$SA_LIBPATH \
+ -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:core=${CORE_FILE},javaExecutable=${EXEC_FILE}
diff --git a/hotspot/agent/make/jdbcore64.sh b/hotspot/agent/make/jdbcore64.sh
new file mode 100644
index 00000000000..8bb3dd4364a
--- /dev/null
+++ b/hotspot/agent/make/jdbcore64.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+usage()
+{
+ echo "usage: $0 "
+ exit 1
+}
+#
+if [ $# -lt 2 ]; then
+ usage
+else
+ EXEC_FILE="${1}"
+ CORE_FILE="${2}"
+ echo "$0 attaching to core=${CORE_FILE}"
+fi
+#
+
+. `dirname $0`/saenv64.sh
+
+$JAVA_HOME/bin/jdb -J-d64 -J-Xbootclasspath/a:$SA_CLASSPATH:$JAVA_HOME/lib/tools.jar \
+ -J-Dsun.boot.library.path=$JAVA_HOME/jre/lib/$CPU:$SA_LIBPATH \
+ -connect sun.jvm.hotspot.jdi.SACoreAttachingConnector:core=${CORE_FILE},javaExecutable=${EXEC_FILE}
diff --git a/hotspot/agent/make/jdbproc.sh b/hotspot/agent/make/jdbproc.sh
new file mode 100644
index 00000000000..799ca440bfa
--- /dev/null
+++ b/hotspot/agent/make/jdbproc.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+usage()
+{
+ echo "usage: $0 "
+ exit 1
+}
+#
+if [ $# -lt 1 ]; then
+ usage
+else
+ PID="${1}"
+ echo "$0 attaching to PID=${PID}"
+fi
+#
+
+. `dirname $0`/saenv.sh
+
+$JAVA_HOME/bin/jdb -J-Xbootclasspath/a:$SA_CLASSPATH:$JAVA_HOME/lib/tools.jar \
+ -J-Dsun.boot.library.path=$JAVA_HOME/jre/lib/$CPU:$SA_LIBPATH \
+ -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=${PID}
diff --git a/hotspot/agent/make/jdbproc64.sh b/hotspot/agent/make/jdbproc64.sh
new file mode 100644
index 00000000000..608d8330a1f
--- /dev/null
+++ b/hotspot/agent/make/jdbproc64.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+usage()
+{
+ echo "usage: $0 "
+ exit 1
+}
+#
+if [ $# -lt 1 ]; then
+ usage
+else
+ PID="${1}"
+ echo "$0 attaching to PID=${PID}"
+fi
+
+. `dirname $0`/saenv64.sh
+
+$JAVA_HOME/bin/jdb -J-d64 -J-Xbootclasspath/a:$SA_CLASSPATH:$JAVA_HOME/lib/tools.jar \
+ -J-Dsun.boot.library.path=$JAVA_HOME/jre/lib/$CPU:$SA_LIBPATH \
+ -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=${PID}
+
diff --git a/hotspot/agent/make/jhistoproc.sh b/hotspot/agent/make/jhistoproc.sh
new file mode 100644
index 00000000000..d2e3b504abd
--- /dev/null
+++ b/hotspot/agent/make/jhistoproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.ObjectHistogram $*
diff --git a/hotspot/agent/make/jhistoproc64.sh b/hotspot/agent/make/jhistoproc64.sh
new file mode 100644
index 00000000000..8cda08be04b
--- /dev/null
+++ b/hotspot/agent/make/jhistoproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.ObjectHistogram $*
diff --git a/hotspot/agent/make/jhistowindbg.bat b/hotspot/agent/make/jhistowindbg.bat
new file mode 100644
index 00000000000..28f17580bae
--- /dev/null
+++ b/hotspot/agent/make/jhistowindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.ObjectHistogram %1 %2
diff --git a/hotspot/agent/make/jhistowindbg64.bat b/hotspot/agent/make/jhistowindbg64.bat
new file mode 100644
index 00000000000..b437f97aaff
--- /dev/null
+++ b/hotspot/agent/make/jhistowindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.ObjectHistogram %1 %2
diff --git a/hotspot/agent/make/jsdbproc.sh b/hotspot/agent/make/jsdbproc.sh
new file mode 100644
index 00000000000..2d59d6e40cd
--- /dev/null
+++ b/hotspot/agent/make/jsdbproc.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+#
+# Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.soql.JSDB $*
diff --git a/hotspot/agent/make/jsdbproc64.sh b/hotspot/agent/make/jsdbproc64.sh
new file mode 100644
index 00000000000..96ae452c8a9
--- /dev/null
+++ b/hotspot/agent/make/jsdbproc64.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+#
+# Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.JSDB $*
diff --git a/hotspot/agent/make/jsdbwindbg.bat b/hotspot/agent/make/jsdbwindbg.bat
new file mode 100644
index 00000000000..354425e1928
--- /dev/null
+++ b/hotspot/agent/make/jsdbwindbg.bat
@@ -0,0 +1,29 @@
+@echo off
+
+REM
+REM Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.soql.JSDB %1 %2
diff --git a/hotspot/agent/make/jsdbwindbg64.bat b/hotspot/agent/make/jsdbwindbg64.bat
new file mode 100644
index 00000000000..f6d761a82f4
--- /dev/null
+++ b/hotspot/agent/make/jsdbwindbg64.bat
@@ -0,0 +1,29 @@
+@echo off
+
+REM
+REM Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.soql.JSDB %1 %2
diff --git a/hotspot/agent/make/jstackproc.sh b/hotspot/agent/make/jstackproc.sh
new file mode 100644
index 00000000000..0e16dd9b009
--- /dev/null
+++ b/hotspot/agent/make/jstackproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.StackTrace $*
diff --git a/hotspot/agent/make/jstackproc64.sh b/hotspot/agent/make/jstackproc64.sh
new file mode 100644
index 00000000000..aea5ef1f6bd
--- /dev/null
+++ b/hotspot/agent/make/jstackproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.StackTrace $*
diff --git a/hotspot/agent/make/jstackwindbg.bat b/hotspot/agent/make/jstackwindbg.bat
new file mode 100644
index 00000000000..fdaed906901
--- /dev/null
+++ b/hotspot/agent/make/jstackwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.StackTrace %1 %2
diff --git a/hotspot/agent/make/jstackwindbg64.bat b/hotspot/agent/make/jstackwindbg64.bat
new file mode 100644
index 00000000000..35562e7e783
--- /dev/null
+++ b/hotspot/agent/make/jstackwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.StackTrace %1 %2
diff --git a/hotspot/agent/make/marks_notes.html b/hotspot/agent/make/marks_notes.html
new file mode 100644
index 00000000000..96b82356146
--- /dev/null
+++ b/hotspot/agent/make/marks_notes.html
@@ -0,0 +1,99 @@
+
+
+
+ Hotspot SA User Interface Notes
+
+
+
+ Hotspot SA User Interface Notes
+
+ Workspace and Building
+
+
+ All the source code for the Serviceability Agent is in
+ src/share/vm/agent
in the HotSport workspace
+ /net/jano.sfbay/export/disk05/hotspot/ws/1.4/sa_baseline
+
+ You can build the project by typing gnumake
in the
+ src/share/vm/agent
directory.
+
+ You can also use the default build target using the Ant build file (build.xml). You can download Ant from
+ http://jakarta.apache.org/ant. Documentation for Ant can be
+ found at http://jakarta.apache.org/ant/manual/index.html
+
+
+
Running the project
+
+
+ java -cp classes sun.jvm.hotspot.HSDB
+ java -cp classes sun.jvm.hotspot.bugspot.Main
+
+
+ Feedback
+
+ Refactoring of package hierarchy. All user interface components should be in
+ the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB and
+ sun.jvm.hotspot.ui.bugspot.Main for BugSpot.
+
+ The src\share\vm\agent area seems like a workspace so it should be organized like
+ one. In particular, I'd like to suggest the following directory layout:
+
+
+ - src: All sources that are curently under the sun directory.
+
- classes: compiled class files.
+
- lib: Resources like images, icons and jar files.
+
- docs: Documentation
+
- deploy: distribution bundles for Java Web Start.
+
+
+
+ Seems like there is a lot of redundant functionality. Between the HSDB and BugSpot. Perhaps
+ this can be consolidated with a javax.swing.Actions
architecture.
+
+
Tasklist
+
+
+ Stack memory pane:
+ It's one of the more useful JVM debugging tools in the SA. However, it
+ doesn't support any interaction with the text; the Memory Panel in BugSpot
+ was written afterward (with help from Shannon) and implements proper
+ selection, scrolling, and drag-and-drop, but no annotations. I'm not sure how
+ to integrate the annotations with the JTable that's being used for the memory
+ view; if you have suggestions here please let me know.
+
+ Integrations with the NetBeans architecture (plug in). See the
+ Netbeans Open APIs homepage
+
+
+
+ HSDB: Object Histogram. Column sizes should be sized according the the
+ contents. i.e, The size and count columns should be narrow enought to
+ handle the largest window. Since there is a lot of data, sorting
+ and searching should be implemented.
+
+
+
Log
+
+ Last modified: Tue Feb 05 19:15:12 Pacific Standard Time 2002
+
+ sun.jvm.hotspot.oops.ObjectHistogram should be the underlying data
+ structure for the TableModels. It shouldnt bother with sorting the data -
+ the table model should do that. It should implement these methods:
+
+
+ public int getSize()
+ public ObjectHistogramElement getElementAt(int row);
+
+
+ ObjectHistogramElement should return the String that represents
+ the third column
+
+
+
+ Mark Davidson
+
+
+Last modified: Tue Feb 05 20:05:13 Pacific Standard Time 2002
+
+
+
diff --git a/hotspot/agent/make/mkinstall b/hotspot/agent/make/mkinstall
new file mode 100644
index 00000000000..a9940005317
--- /dev/null
+++ b/hotspot/agent/make/mkinstall
@@ -0,0 +1,146 @@
+
+# make the directories
+
+SA_NAME=sa17
+SA_TEST=$SA_NAME/test
+
+mkdir $SA_NAME
+mkdir $SA_NAME/solaris
+mkdir $SA_NAME/solaris/amd64
+mkdir $SA_NAME/solaris/sparc
+mkdir $SA_NAME/solaris/sparcv9
+mkdir $SA_NAME/solaris/i386
+mkdir $SA_NAME/linux
+mkdir $SA_NAME/linux/i386
+mkdir $SA_NAME/linux/ia64
+mkdir $SA_NAME/linux/amd64
+mkdir $SA_NAME/win32
+mkdir $SA_NAME/win32/i386
+mkdir $SA_NAME/win32/ia64
+mkdir $SA_NAME/win32/amd64
+mkdir $SA_TEST
+
+# make sa.jar
+jar -cvf $SA_NAME/sa.jar -C ../build/classes .
+
+# copy the native libraries
+
+cp ../src/os/solaris/proc/amd64/libsaproc.so $SA_NAME/solaris/amd64
+cp ../src/os/solaris/proc/sparc/libsaproc.so $SA_NAME/solaris/sparc
+cp ../src/os/solaris/proc/sparcv9/libsaproc.so $SA_NAME/solaris/sparcv9
+cp ../src/os/solaris/proc/i386/libsaproc.so $SA_NAME/solaris/i386
+cp ../src/os/linux/i386/libsaproc.so $SA_NAME/linux/i386
+cp ../src/os/linux/ia64/libsaproc.so $SA_NAME/linux/ia64
+cp ../src/os/linux/amd64/libsaproc.so $SA_NAME/linux/amd64
+cp ../src/os/win32/windbg/i386/sawindbg.dll $SA_NAME/win32/i386
+cp ../src/os/win32/windbg/ia64/sawindbg.dll $SA_NAME/win32/ia64
+cp ../src/os/win32/windbg/amd64/sawindbg.dll $SA_NAME/win32/amd64
+
+# copy Unix (Solaris and Linux) shell scripts
+cp saenv.sh $SA_NAME ; chmod 755 $SA_NAME/saenv.sh
+cp saenv64.sh $SA_NAME ; chmod 755 $SA_NAME/saenv64.sh
+cp clhsdbproc.sh $SA_NAME ; chmod 755 $SA_NAME/clhsdbproc.sh
+cp clhsdbproc64.sh $SA_NAME ; chmod 755 $SA_NAME/clhsdbproc64.sh
+cp dumpflagsproc.sh $SA_NAME ; chmod 755 $SA_NAME/dumpflagsproc.sh
+cp dumpflagsproc64.sh $SA_NAME ; chmod 755 $SA_NAME/dumpflagsproc64.sh
+cp dumpsyspropsproc.sh $SA_NAME ; chmod 755 $SA_NAME/dumpsyspropsproc.sh
+cp dumpsyspropsproc64.sh $SA_NAME ; chmod 755 $SA_NAME/dumpsyspropsproc64.sh
+cp finalizerinfoproc.sh $SA_NAME ; chmod 755 $SA_NAME/finalizerinfoproc.sh
+cp finalizerinfoproc64.sh $SA_NAME ; chmod 755 $SA_NAME/finalizerinfoproc64.sh
+cp heapdumpproc.sh $SA_NAME ; chmod 755 $SA_NAME/heapdumpproc.sh
+cp heapdumpproc64.sh $SA_NAME ; chmod 755 $SA_NAME/heapdumpproc64.sh
+cp heapsumproc.sh $SA_NAME ; chmod 755 $SA_NAME/heapsumproc.sh
+cp heapsumproc64.sh $SA_NAME ; chmod 755 $SA_NAME/heapsumproc64.sh
+cp hsdbproc.sh $SA_NAME ; chmod 755 $SA_NAME/hsdbproc.sh
+cp hsdbproc64.sh $SA_NAME ; chmod 755 $SA_NAME/hsdbproc64.sh
+cp jcoreproc.sh $SA_NAME ; chmod 755 $SA_NAME/jcoreproc.sh
+cp jcoreproc64.sh $SA_NAME ; chmod 755 $SA_NAME/jcoreproc64.sh
+cp jdbcore.sh $SA_NAME ; chmod 755 $SA_NAME/jdbcore.sh
+cp jdbcore64.sh $SA_NAME ; chmod 755 $SA_NAME/jdbcore64.sh
+cp jdbproc.sh $SA_NAME ; chmod 755 $SA_NAME/jdbproc.sh
+cp jdbproc64.sh $SA_NAME ; chmod 755 $SA_NAME/jdbproc64.sh
+cp jhistoproc.sh $SA_NAME ; chmod 755 $SA_NAME/jhistoproc.sh
+cp jhistoproc64.sh $SA_NAME ; chmod 755 $SA_NAME/jhistoproc64.sh
+cp jsdbproc.sh $SA_NAME ; chmod 755 $SA_NAME/jsdbproc.sh
+cp jsdbproc64.sh $SA_NAME ; chmod 755 $SA_NAME/jsdbproc64.sh
+cp jstackproc.sh $SA_NAME ; chmod 755 $SA_NAME/jstackproc.sh
+cp jstackproc64.sh $SA_NAME ; chmod 755 $SA_NAME/jstackproc64.sh
+cp permstatproc.sh $SA_NAME ; chmod 755 $SA_NAME/permstatproc.sh
+cp permstatproc64.sh $SA_NAME ; chmod 755 $SA_NAME/permstatproc64.sh
+cp pmapproc.sh $SA_NAME ; chmod 755 $SA_NAME/pmapproc.sh
+cp pmapproc64.sh $SA_NAME ; chmod 755 $SA_NAME/pmapproc64.sh
+cp pstackproc.sh $SA_NAME ; chmod 755 $SA_NAME/pstackproc.sh
+cp pstackproc64.sh $SA_NAME ; chmod 755 $SA_NAME/pstackproc64.sh
+cp soqlproc.sh $SA_NAME ; chmod 755 $SA_NAME/soqlproc.sh
+cp soqlproc64.sh $SA_NAME ; chmod 755 $SA_NAME/soqlproc64.sh
+cp start-debug-server $SA_NAME ; chmod 755 $SA_NAME/start-debug-server
+cp start-debug-server-proc.sh $SA_NAME ; chmod 755 $SA_NAME/start-debug-server-proc.sh
+cp start-debug-server-proc64.sh $SA_NAME ; chmod 755 $SA_NAME/start-debug-server-proc64.sh
+cp start-rmiregistry.sh $SA_NAME ; chmod 755 $SA_NAME/start-rmiregistry.sh
+
+# copy Windows batch files
+cp saenv.bat $SA_NAME ; chmod 755 $SA_NAME/saenv.bat
+cp saenv64.bat $SA_NAME ; chmod 755 $SA_NAME/saenv64.bat
+cp clhsdbwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/clhsdbwindbg.bat
+cp clhsdbwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/clhsdbwindbg64.bat
+cp dumpflagswindbg.bat $SA_NAME ; chmod 755 $SA_NAME/dumpflagswindbg.bat
+cp dumpflagswindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/dumpflagswindbg64.bat
+cp dumpsyspropswindbg.bat $SA_NAME ; chmod 755 $SA_NAME/dumpsyspropswindbg.bat
+cp dumpsyspropswindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/dumpsyspropswindbg64.bat
+cp finalizerinfowindbg.bat $SA_NAME ; chmod 755 $SA_NAME/finalizerinfowindbg.bat
+cp finalizerinfowindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/finalizerinfowindbg64.bat
+cp heapdumpwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/heapdumpwindbg.bat
+cp heapdumpwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/heapdumpwindbg64.bat
+cp heapsumwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/heapsumwindbg.bat
+cp heapsumwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/heapsumwindbg64.bat
+cp hsdbwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/hsdbwindbg.bat
+cp hsdbwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/hsdbwindbg64.bat
+cp jcorewindbg.bat $SA_NAME ; chmod 755 $SA_NAME/jcorewindbg.bat
+cp jcorewindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/jcorewindbg64.bat
+cp jhistowindbg.bat $SA_NAME ; chmod 755 $SA_NAME/jhistowindbg.bat
+cp jhistowindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/jhistowindbg64.bat
+cp jsdbwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/jsdbwindbg.bat
+cp jsdbwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/jsdbwindbg64.bat
+cp jstackwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/jstackwindbg.bat
+cp jstackwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/jstackwindbg64.bat
+cp permstatwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/permstatwindbg.bat
+cp permstatwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/permstatwindbg64.bat
+cp pmapwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/pmapwindbg.bat
+cp pmapwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/pmapwindbg64.bat
+cp pstackwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/pstackwindbg.bat
+cp pstackwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/pstackwindbg64.bat
+cp soqlwindbg.bat $SA_NAME ; chmod 755 $SA_NAME/soqlwindbg.bat
+cp soqlwindbg64.bat $SA_NAME ; chmod 755 $SA_NAME/soqlwindbg64.bat
+cp start-debug-server-windbg.bat $SA_NAME ; chmod 755 $SA_NAME/start-debug-server-windbg.bat
+cp start-debug-server-windbg64.bat $SA_NAME ; chmod 755 $SA_NAME/start-debug-server-windbg64.bat
+cp start-rmiregistry.bat $SA_NAME ; chmod 755 $SA_NAME/start-rmiregistry.bat
+
+
+# make the libproc test
+cd ../test/libproc ; make; cd ../../make
+
+# copy libproc test suite
+
+cp ../test/libproc/README $SA_TEST/README-libproc
+cp ../test/libproc/libproctest.sh $SA_TEST ; chmod 755 $SA_TEST/libproctest.sh
+cp ../test/libproc/libproctest64.sh $SA_TEST ; chmod 755 $SA_TEST/libproctest64.sh
+cp ../test/libproc/*.class $SA_TEST
+
+# copy RMI security policy file
+cp grantAll.policy $SA_NAME
+
+# copy documentation
+mkdir $SA_NAME/doc
+cp ../doc/*.html $SA_NAME/doc
+chmod 644 $SA_NAME/doc/*.html
+
+# make lib dir and copy other jar files
+mkdir $SA_NAME/lib
+cp ../src/share/lib/*.jar $SA_NAME/lib
+
+# tar and gzip
+tar -cvf $SA_NAME.tar $SA_NAME
+gzip $SA_NAME.tar
+
+# cleanup
+\rm -rf $SA_NAME
diff --git a/hotspot/agent/make/permstatproc.sh b/hotspot/agent/make/permstatproc.sh
new file mode 100644
index 00000000000..2772d23c8ce
--- /dev/null
+++ b/hotspot/agent/make/permstatproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.PermStat $*
diff --git a/hotspot/agent/make/permstatproc64.sh b/hotspot/agent/make/permstatproc64.sh
new file mode 100644
index 00000000000..6abeb76d5cc
--- /dev/null
+++ b/hotspot/agent/make/permstatproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.PermStat $*
diff --git a/hotspot/agent/make/permstatwindbg.bat b/hotspot/agent/make/permstatwindbg.bat
new file mode 100644
index 00000000000..7c35ed384a9
--- /dev/null
+++ b/hotspot/agent/make/permstatwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.PermStat %1 %2
diff --git a/hotspot/agent/make/permstatwindbg64.bat b/hotspot/agent/make/permstatwindbg64.bat
new file mode 100644
index 00000000000..721c23e1865
--- /dev/null
+++ b/hotspot/agent/make/permstatwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.PermStat %1 %2
diff --git a/hotspot/agent/make/pmapproc.sh b/hotspot/agent/make/pmapproc.sh
new file mode 100644
index 00000000000..91c27c55b62
--- /dev/null
+++ b/hotspot/agent/make/pmapproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.PMap $*
diff --git a/hotspot/agent/make/pmapproc64.sh b/hotspot/agent/make/pmapproc64.sh
new file mode 100644
index 00000000000..bd33e5ce7a0
--- /dev/null
+++ b/hotspot/agent/make/pmapproc64.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.PMap $*
+
diff --git a/hotspot/agent/make/pmapwindbg.bat b/hotspot/agent/make/pmapwindbg.bat
new file mode 100644
index 00000000000..50e653c8b4d
--- /dev/null
+++ b/hotspot/agent/make/pmapwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.PMap %1 %2
diff --git a/hotspot/agent/make/pmapwindbg64.bat b/hotspot/agent/make/pmapwindbg64.bat
new file mode 100644
index 00000000000..414a75a62dd
--- /dev/null
+++ b/hotspot/agent/make/pmapwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.PMap %1 %2
diff --git a/hotspot/agent/make/pstackproc.sh b/hotspot/agent/make/pstackproc.sh
new file mode 100644
index 00000000000..1d22899020e
--- /dev/null
+++ b/hotspot/agent/make/pstackproc.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+type c++filt 1>/dev/null 2>/dev/null
+if [ $? -eq 0 ]; then
+ $SA_JAVA_CMD sun.jvm.hotspot.tools.PStack $* | c++filt
+else
+ $SA_JAVA_CMD sun.jvm.hotspot.tools.PStack $*
+fi
+
diff --git a/hotspot/agent/make/pstackproc64.sh b/hotspot/agent/make/pstackproc64.sh
new file mode 100644
index 00000000000..bb5ce693af8
--- /dev/null
+++ b/hotspot/agent/make/pstackproc64.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+type c++filt 1>/dev/null 2>/dev/null
+if [ $? -eq 0 ]; then
+ $SA_JAVA_CMD sun.jvm.hotspot.tools.PStack $* | c++filt
+else
+ $SA_JAVA_CMD sun.jvm.hotspot.tools.PStack $*
+fi
+
diff --git a/hotspot/agent/make/pstackwindbg.bat b/hotspot/agent/make/pstackwindbg.bat
new file mode 100644
index 00000000000..1a7f33b099a
--- /dev/null
+++ b/hotspot/agent/make/pstackwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.PStack %1 %2
diff --git a/hotspot/agent/make/pstackwindbg64.bat b/hotspot/agent/make/pstackwindbg64.bat
new file mode 100644
index 00000000000..b1fd4438a36
--- /dev/null
+++ b/hotspot/agent/make/pstackwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.PStack %1 %2
diff --git a/hotspot/agent/make/saenv.bat b/hotspot/agent/make/saenv.bat
new file mode 100644
index 00000000000..b5342027b98
--- /dev/null
+++ b/hotspot/agent/make/saenv.bat
@@ -0,0 +1,54 @@
+@echo off
+REM
+REM Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+REM This is common environment settings for all SA
+REM windows batch scripts
+
+REM set jre\bin and jre\bin\client (or server) in PATH
+REM WINDBG_HOME must point to the Windows Debugging Tools
+REM installation directory
+
+if "%SA_JAVA%" == "" goto no_sa_java
+
+goto sa_java_set
+
+:no_sa_java
+set SA_JAVA=java
+
+:sa_java_set
+
+set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar
+
+set SA_LIBPATH=..\src\os\win32\windbg\i386;.\win32\i386
+
+set OPTIONS=-Dsun.jvm.hotspot.debugger.useWindbgDebugger
+set OPTIONS=-Dsun.jvm.hotspot.debugger.windbg.imagePath="%PATH%" %OPTIONS%
+set OPTIONS=-Dsun.jvm.hotspot.debugger.windbg.sdkHome="%WINDBG_HOME%" %OPTIONS%
+
+if "%SA_DISABLE_VERS_CHK%" == "" goto vers_chk
+set OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck %OPTIONS%"
+
+:vers_chk
+set SA_JAVA_CMD=%SA_JAVA% -showversion -cp %SA_CLASSPATH% -Djava.library.path=%SA_LIBPATH% %OPTIONS%
diff --git a/hotspot/agent/make/saenv.sh b/hotspot/agent/make/saenv.sh
new file mode 100644
index 00000000000..e5e5c485dd4
--- /dev/null
+++ b/hotspot/agent/make/saenv.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+#
+# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+# This file sets common environment variables for all SA scripts
+
+OS=`uname`
+STARTDIR=`dirname $0`
+ARCH=`uname -m`
+
+if [ "x$SA_JAVA" = "x" ]; then
+ SA_JAVA=java
+fi
+
+if [ "$OS" = "Linux" ]; then
+ if [ "$ARCH" = "ia64" ] ; then
+ SA_LIBPATH=$STARTDIR/../src/os/linux/ia64:$STARTDIR/linux/ia64
+ OPTIONS="-Dsa.library.path=$SA_LIBPATH"
+ CPU=ia64
+ elif [ "$ARCH" = "x86_64" ] ; then
+ SA_LIBPATH=$STARTDIR/../src/os/linux/amd64:$STARTDIR/linux/amd64
+ OPTIONS="-Dsa.library.path=$SA_LIBPATH"
+ CPU=amd64
+ else
+ SA_LIBPATH=$STARTDIR/../src/os/linux/i386:$STARTDIR/linux/i386
+ OPTIONS="-Dsa.library.path=$SA_LIBPATH"
+ CPU=i386
+ fi
+else
+ SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/`uname -p`:$STARTDIR/solaris/`uname -p`
+ OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
+ CPU=sparc
+fi
+
+if [ "x$SA_DISABLE_VERS_CHK" != "x" ]; then
+ OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck ${OPTIONS}"
+fi
+
+
+SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar
+
+OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
+
+SA_JAVA_CMD="$SA_PREFIX_CMD $SA_JAVA -showversion ${OPTIONS} -cp $SA_CLASSPATH $SA_OPTIONS"
diff --git a/hotspot/agent/make/saenv64.bat b/hotspot/agent/make/saenv64.bat
new file mode 100644
index 00000000000..84e30c31bc2
--- /dev/null
+++ b/hotspot/agent/make/saenv64.bat
@@ -0,0 +1,60 @@
+@echo off
+REM
+REM Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+REM FIXME: How do I detect processor on Windows so that
+REM AMD-64/IA-64 could be detected? Should I assume
+REM MKS/Cygwin here?
+
+REM This is common environment settings for all SA
+REM windows batch scripts
+
+REM set jre\bin and jre\bin\client (or server) in PATH
+REM WINDBG_HOME must point to the Windows Debugging Tools
+REM installation directory.
+
+if "%SA_JAVA%" == "" goto no_sa_java
+
+goto sa_java_set
+
+:no_sa_java
+set SA_JAVA=java
+
+:sa_java_set
+
+set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar
+
+REM For now, only AMD-64, IA-64 stack walking is not working anyway
+set SA_LIBPATH=.\src\os\win32\windbg\amd64;.\win32\amd64
+
+set OPTIONS=-Dsun.jvm.hotspot.debugger.useWindbgDebugger
+set OPTIONS=-Dsun.jvm.hotspot.debugger.windbg.imagePath="%PATH%" %OPTIONS%
+set OPTIONS=-Dsun.jvm.hotspot.debugger.windbg.sdkHome="%WINDBG_HOME%" %OPTIONS%
+
+if "%SA_DISABLE_VERS_CHK%" == "" goto vers_chk
+set OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck %OPTIONS%"
+
+:vers_chk
+
+set SA_JAVA_CMD=%SA_JAVA% -showversion -cp %SA_CLASSPATH% -Djava.library.path=.%SA_LIBPATH% %OPTIONS%
diff --git a/hotspot/agent/make/saenv64.sh b/hotspot/agent/make/saenv64.sh
new file mode 100644
index 00000000000..ea22420496b
--- /dev/null
+++ b/hotspot/agent/make/saenv64.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+#
+# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+# This file sets common environment variables for all 64-bit Solaris [sparcv9,
+# amd64] SA scripts. Please note that for 64-bit Linux use saenv.sh.
+
+OS=`uname`
+STARTDIR=`dirname $0`
+
+CPU=`isainfo | grep sparcv9`
+
+if [ "x$CPU" != "x" ]; then
+ CPU=sparcv9
+else
+ CPU=`isainfo | grep amd64`
+ if [ "x$CPU" != "x" ]; then
+ CPU=amd64
+ else
+ echo "unknown CPU, only sparcv9, amd64 are supported!"
+ exit 1
+ fi
+fi
+
+SA_LIBPATH=$STARTDIR/../src/os/solaris/proc/$CPU:$STARTDIR/solaris/$CPU
+
+OPTIONS="-Dsa.library.path=$SA_LIBPATH -Dsun.jvm.hotspot.debugger.useProcDebugger"
+
+if [ "x$SA_JAVA" = "x" ]; then
+ SA_JAVA=java
+fi
+
+if [ "x$SA_DISABLE_VERS_CHK" != "x" ]; then
+ OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck ${OPTIONS}"
+fi
+
+SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar
+
+OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
+
+SA_JAVA_CMD="$SA_PREFIX_CMD $SA_JAVA -d64 -showversion ${OPTIONS} -cp $SA_CLASSPATH $SA_OPTIONS"
diff --git a/hotspot/agent/make/soqlproc.sh b/hotspot/agent/make/soqlproc.sh
new file mode 100644
index 00000000000..9dba98a13e9
--- /dev/null
+++ b/hotspot/agent/make/soqlproc.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.soql.SOQL $*
diff --git a/hotspot/agent/make/soqlproc64.sh b/hotspot/agent/make/soqlproc64.sh
new file mode 100644
index 00000000000..153354529c5
--- /dev/null
+++ b/hotspot/agent/make/soqlproc64.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+$SA_JAVA_CMD sun.jvm.hotspot.tools.soql.SOQL $*
diff --git a/hotspot/agent/make/soqlwindbg.bat b/hotspot/agent/make/soqlwindbg.bat
new file mode 100644
index 00000000000..4d1e373f0ae
--- /dev/null
+++ b/hotspot/agent/make/soqlwindbg.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.soql.SOQL %1 %2
diff --git a/hotspot/agent/make/soqlwindbg64.bat b/hotspot/agent/make/soqlwindbg64.bat
new file mode 100644
index 00000000000..4bbf72109f1
--- /dev/null
+++ b/hotspot/agent/make/soqlwindbg64.bat
@@ -0,0 +1,28 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+%SA_JAVA_CMD% sun.jvm.hotspot.tools.soql.SOQL %1 %2
diff --git a/hotspot/agent/make/start-debug-server b/hotspot/agent/make/start-debug-server
new file mode 100644
index 00000000000..dfaf5d91515
--- /dev/null
+++ b/hotspot/agent/make/start-debug-server
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+STARTDIR=`dirname $0`
+
+if [ "x$SA_JAVA" = "x" ]; then
+ SA_JAVA=java
+fi
+
+if [ -f $STARTDIR/sa.jar ] ; then
+ CP=$STARTDIR/sa.jar
+else
+ CP=$STARTDIR/../build/classes
+fi
+
+# License file for development version of dbx
+setenv LM_LICENSE_FILE 7588@extend.eng:/usr/dist/local/config/sparcworks/license.dat:7588@setlicense
+
+$SA_JAVA -Xbootclasspath/p:$CP -Djava.rmi.server.codebase=file:/$CP -Djava.security.policy=$STARTDIR\/grantAll.policy sun.jvm.hotspot.DebugServer $*
diff --git a/hotspot/agent/make/start-debug-server-proc.sh b/hotspot/agent/make/start-debug-server-proc.sh
new file mode 100644
index 00000000000..2f809818b9d
--- /dev/null
+++ b/hotspot/agent/make/start-debug-server-proc.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv.sh
+
+if [ -f $STARTDIR/sa.jar ] ; then
+ CP=$STARTDIR/sa.jar
+else
+ CP=$STARTDIR/../build/classes
+fi
+
+$SA_JAVA -classpath $CP ${OPTIONS} -Djava.rmi.server.codebase=file:/$CP -Djava.security.policy=$STARTDIR\/grantAll.policy sun.jvm.hotspot.DebugServer $*
diff --git a/hotspot/agent/make/start-debug-server-proc64.sh b/hotspot/agent/make/start-debug-server-proc64.sh
new file mode 100644
index 00000000000..10146777c30
--- /dev/null
+++ b/hotspot/agent/make/start-debug-server-proc64.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+. `dirname $0`/saenv64.sh
+
+if [ -f $STARTDIR/sa.jar ] ; then
+ CP=$STARTDIR/sa.jar
+else
+ CP=$STARTDIR/../build/classes
+fi
+
+$SA_JAVA -d64 -classpath $CP ${OPTIONS} -Djava.rmi.server.codebase=file:/$CP -Djava.security.policy=$STARTDIR\/grantAll.policy sun.jvm.hotspot.DebugServer $*
diff --git a/hotspot/agent/make/start-debug-server-windbg.bat b/hotspot/agent/make/start-debug-server-windbg.bat
new file mode 100644
index 00000000000..9cac3839327
--- /dev/null
+++ b/hotspot/agent/make/start-debug-server-windbg.bat
@@ -0,0 +1,39 @@
+@echo off
+REM
+REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv.bat
+
+REM check for .\sa.jar, if it does not exist
+REM assume that we are in build configuration.
+
+if not exist .\sa.jar goto IN_BUILD_CONF
+set SA_CLASSPATH=.\sa.jar
+goto EXEC_CMD
+
+:IN_BUILD_CONF
+set SA_CLASSPATH=..\build\classes
+
+:EXEC_CMD
+%SA_JAVA% -classpath %SA_CLASSPATH% -Djava.rmi.server.codebase=file:/%SA_CLASSPATH% -Djava.security.policy=grantAll.policy -Djava.library.path=%SA_LIBPATH% %OPTIONS% sun.jvm.hotspot.DebugServer %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/hotspot/agent/make/start-debug-server-windbg64.bat b/hotspot/agent/make/start-debug-server-windbg64.bat
new file mode 100644
index 00000000000..bb7a4f99248
--- /dev/null
+++ b/hotspot/agent/make/start-debug-server-windbg64.bat
@@ -0,0 +1,39 @@
+@echo off
+REM
+REM Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+call saenv64.bat
+
+REM check for .\sa.jar, if it does not exist
+REM assume that we are in build configuration.
+
+if not exist .\sa.jar goto IN_BUILD_CONF
+set SA_CLASSPATH=.\sa.jar
+goto EXEC_CMD
+
+:IN_BUILD_CONF
+set SA_CLASSPATH=..\build\classes
+
+:EXEC_CMD
+%SA_JAVA% -classpath %SA_CLASSPATH% -Djava.rmi.server.codebase=file:/%SA_CLASSPATH% -Djava.security.policy=grantAll.policy -Djava.library.path=%SA_LIBPATH% %OPTIONS% sun.jvm.hotspot.DebugServer %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/hotspot/agent/make/start-rmiregistry.bat b/hotspot/agent/make/start-rmiregistry.bat
new file mode 100644
index 00000000000..d7f2a41d745
--- /dev/null
+++ b/hotspot/agent/make/start-rmiregistry.bat
@@ -0,0 +1,37 @@
+@echo off
+REM
+REM Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+REM
+REM This code is free software; you can redistribute it and/or modify it
+REM under the terms of the GNU General Public License version 2 only, as
+REM published by the Free Software Foundation.
+REM
+REM This code is distributed in the hope that it will be useful, but WITHOUT
+REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+REM version 2 for more details (a copy is included in the LICENSE file that
+REM accompanied this code).
+REM
+REM You should have received a copy of the GNU General Public License version
+REM 2 along with this work; if not, write to the Free Software Foundation,
+REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+REM
+REM Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+REM CA 95054 USA or visit www.sun.com if you need additional information or
+REM have any questions.
+REM
+REM
+
+REM check for .\sa.jar, if it does not exist
+REM assume that we are in build configuration.
+
+if not exist .\sa.jar goto IN_BUILD_CONF
+set CLASSPATH=.\sa.jar
+goto EXEC_CMD
+
+:IN_BUILD_CONF
+set CLASSPATH=..\build\classes
+
+:EXEC_CMD
+start rmiregistry -J-Xbootclasspath/p:%CLASSPATH%
diff --git a/hotspot/agent/make/start-rmiregistry.sh b/hotspot/agent/make/start-rmiregistry.sh
new file mode 100644
index 00000000000..1a192603825
--- /dev/null
+++ b/hotspot/agent/make/start-rmiregistry.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+STARTDIR=`dirname $0`
+
+if [ -f $STARTDIR/sa.jar ] ; then
+ CP=$STARTDIR/sa.jar
+else
+ CP=$STARTDIR/../build/classes
+fi
+
+rmiregistry -J-Xbootclasspath/p:$CP
diff --git a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
new file mode 100644
index 00000000000..c4ca7def0b1
--- /dev/null
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include "libproc.h"
+
+#if defined(x86_64) && !defined(amd64)
+#define amd64 1
+#endif
+
+#ifdef i386
+#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
+#endif
+
+#ifdef amd64
+#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
+#endif
+
+#if defined(sparc) || defined(sparcv9)
+#include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
+#endif
+
+static jfieldID p_ps_prochandle_ID = 0;
+static jfieldID threadList_ID = 0;
+static jfieldID loadObjectList_ID = 0;
+
+static jmethodID createClosestSymbol_ID = 0;
+static jmethodID createLoadObject_ID = 0;
+static jmethodID getThreadForThreadId_ID = 0;
+static jmethodID listAdd_ID = 0;
+
+#define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
+#define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
+#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
+#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
+
+static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
+ (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
+}
+
+static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
+ jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
+ return (struct ps_prochandle*)(intptr_t)ptr;
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: init0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0
+ (JNIEnv *env, jclass cls) {
+ jclass listClass;
+
+ if (init_libproc(getenv("LIBSAPROC_DEBUG")) != true) {
+ THROW_NEW_DEBUGGER_EXCEPTION("can't initialize libproc");
+ }
+
+ // fields we use
+ p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J");
+ CHECK_EXCEPTION;
+ threadList_ID = (*env)->GetFieldID(env, cls, "threadList", "Ljava/util/List;");
+ CHECK_EXCEPTION;
+ loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;");
+ CHECK_EXCEPTION;
+
+ // methods we use
+ createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol",
+ "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
+ CHECK_EXCEPTION;
+ createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject",
+ "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
+ CHECK_EXCEPTION;
+ getThreadForThreadId_ID = (*env)->GetMethodID(env, cls, "getThreadForThreadId",
+ "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
+ CHECK_EXCEPTION;
+ // java.util.List method we call
+ listClass = (*env)->FindClass(env, "java/util/List");
+ CHECK_EXCEPTION;
+ listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z");
+ CHECK_EXCEPTION;
+}
+
+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getAddressSize
+ (JNIEnv *env, jclass cls)
+{
+#ifdef _LP64
+ return 8;
+#else
+ return 4;
+#endif
+
+}
+
+
+static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
+ int n = 0, i = 0;
+
+ // add threads
+ n = get_num_threads(ph);
+ for (i = 0; i < n; i++) {
+ jobject thread;
+ jobject threadList;
+ lwpid_t lwpid;
+
+ lwpid = get_lwp_id(ph, i);
+ thread = (*env)->CallObjectMethod(env, this_obj, getThreadForThreadId_ID,
+ (jlong)lwpid);
+ CHECK_EXCEPTION;
+ threadList = (*env)->GetObjectField(env, this_obj, threadList_ID);
+ CHECK_EXCEPTION;
+ (*env)->CallBooleanMethod(env, threadList, listAdd_ID, thread);
+ CHECK_EXCEPTION;
+ }
+
+ // add load objects
+ n = get_num_libs(ph);
+ for (i = 0; i < n; i++) {
+ uintptr_t base;
+ const char* name;
+ jobject loadObject;
+ jobject loadObjectList;
+
+ base = get_lib_base(ph, i);
+ name = get_lib_name(ph, i);
+ loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
+ (*env)->NewStringUTF(env, name), (jlong)0, (jlong)base);
+ CHECK_EXCEPTION;
+ loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID);
+ CHECK_EXCEPTION;
+ (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
+ CHECK_EXCEPTION;
+ }
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: attach0
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
+ (JNIEnv *env, jobject this_obj, jint jpid) {
+
+ struct ps_prochandle* ph;
+ if ( (ph = Pgrab(jpid)) == NULL) {
+ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+ }
+ (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
+ fillThreadsAndLoadObjects(env, this_obj, ph);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: attach0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
+ (JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) {
+ const char *execName_cstr;
+ const char *coreName_cstr;
+ jboolean isCopy;
+ struct ps_prochandle* ph;
+
+ execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy);
+ CHECK_EXCEPTION;
+ coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
+ CHECK_EXCEPTION;
+
+ if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
+ (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
+ (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
+ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file");
+ }
+ (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph);
+ (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
+ (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
+ fillThreadsAndLoadObjects(env, this_obj, ph);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: detach0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0
+ (JNIEnv *env, jobject this_obj) {
+ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+ if (ph != NULL) {
+ Prelease(ph);
+ }
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: lookupByName0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0
+ (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
+ const char *objectName_cstr, *symbolName_cstr;
+ jlong addr;
+ jboolean isCopy;
+ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+
+ objectName_cstr = NULL;
+ if (objectName != NULL) {
+ objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy);
+ CHECK_EXCEPTION_(0);
+ }
+ symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy);
+ CHECK_EXCEPTION_(0);
+
+ addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
+
+ if (objectName_cstr != NULL) {
+ (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr);
+ }
+ (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr);
+ return addr;
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: lookupByAddress0
+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
+ */
+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0
+ (JNIEnv *env, jobject this_obj, jlong addr) {
+ uintptr_t offset;
+ const char* sym = NULL;
+
+ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+ sym = symbol_for_pc(ph, (uintptr_t) addr, &offset);
+ if (sym == NULL) return 0;
+ return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID,
+ (*env)->NewStringUTF(env, sym), (jlong)offset);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
+ * Method: readBytesFromProcess0
+ * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0
+ (JNIEnv *env, jobject this_obj, jlong addr, jlong numBytes) {
+
+ jboolean isCopy;
+ jbyteArray array;
+ jbyte *bufPtr;
+ ps_err_e err;
+
+ array = (*env)->NewByteArray(env, numBytes);
+ CHECK_EXCEPTION_(0);
+ bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy);
+ CHECK_EXCEPTION_(0);
+
+ err = ps_pdread(get_proc_handle(env, this_obj), (psaddr_t) (uintptr_t)addr, bufPtr, numBytes);
+ (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0);
+ return (err == PS_OK)? array : 0;
+}
+
+JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
+ (JNIEnv *env, jobject this_obj, jint lwp_id) {
+
+ struct user_regs_struct gregs;
+ jboolean isCopy;
+ jlongArray array;
+ jlong *regs;
+ int i;
+
+ struct ps_prochandle* ph = get_proc_handle(env, this_obj);
+ if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
+ THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
+ }
+
+#undef NPRGREG
+#ifdef i386
+#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
+#endif
+#ifdef ia64
+#define NPRGREG IA64_REG_COUNT
+#endif
+#ifdef amd64
+#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
+#endif
+#if defined(sparc) || defined(sparcv9)
+#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
+#endif
+
+ array = (*env)->NewLongArray(env, NPRGREG);
+ CHECK_EXCEPTION_(0);
+ regs = (*env)->GetLongArrayElements(env, array, &isCopy);
+
+#undef REG_INDEX
+
+#ifdef i386
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg
+
+ regs[REG_INDEX(GS)] = (uintptr_t) gregs.xgs;
+ regs[REG_INDEX(FS)] = (uintptr_t) gregs.xfs;
+ regs[REG_INDEX(ES)] = (uintptr_t) gregs.xes;
+ regs[REG_INDEX(DS)] = (uintptr_t) gregs.xds;
+ regs[REG_INDEX(EDI)] = (uintptr_t) gregs.edi;
+ regs[REG_INDEX(ESI)] = (uintptr_t) gregs.esi;
+ regs[REG_INDEX(FP)] = (uintptr_t) gregs.ebp;
+ regs[REG_INDEX(SP)] = (uintptr_t) gregs.esp;
+ regs[REG_INDEX(EBX)] = (uintptr_t) gregs.ebx;
+ regs[REG_INDEX(EDX)] = (uintptr_t) gregs.edx;
+ regs[REG_INDEX(ECX)] = (uintptr_t) gregs.ecx;
+ regs[REG_INDEX(EAX)] = (uintptr_t) gregs.eax;
+ regs[REG_INDEX(PC)] = (uintptr_t) gregs.eip;
+ regs[REG_INDEX(CS)] = (uintptr_t) gregs.xcs;
+ regs[REG_INDEX(SS)] = (uintptr_t) gregs.xss;
+
+#endif /* i386 */
+
+#if ia64
+ regs = (*env)->GetLongArrayElements(env, array, &isCopy);
+ for (i = 0; i < NPRGREG; i++ ) {
+ regs[i] = 0xDEADDEAD;
+ }
+#endif /* ia64 */
+
+#ifdef amd64
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg
+
+ regs[REG_INDEX(R15)] = gregs.r15;
+ regs[REG_INDEX(R14)] = gregs.r14;
+ regs[REG_INDEX(R13)] = gregs.r13;
+ regs[REG_INDEX(R12)] = gregs.r12;
+ regs[REG_INDEX(RBP)] = gregs.rbp;
+ regs[REG_INDEX(RBX)] = gregs.rbx;
+ regs[REG_INDEX(R11)] = gregs.r11;
+ regs[REG_INDEX(R10)] = gregs.r10;
+ regs[REG_INDEX(R9)] = gregs.r9;
+ regs[REG_INDEX(R8)] = gregs.r8;
+ regs[REG_INDEX(RAX)] = gregs.rax;
+ regs[REG_INDEX(RCX)] = gregs.rcx;
+ regs[REG_INDEX(RDX)] = gregs.rdx;
+ regs[REG_INDEX(RSI)] = gregs.rsi;
+ regs[REG_INDEX(RDI)] = gregs.rdi;
+ regs[REG_INDEX(RIP)] = gregs.rip;
+ regs[REG_INDEX(CS)] = gregs.cs;
+ regs[REG_INDEX(RSP)] = gregs.rsp;
+ regs[REG_INDEX(SS)] = gregs.ss;
+ regs[REG_INDEX(FSBASE)] = gregs.fs_base;
+ regs[REG_INDEX(GSBASE)] = gregs.gs_base;
+ regs[REG_INDEX(DS)] = gregs.ds;
+ regs[REG_INDEX(ES)] = gregs.es;
+ regs[REG_INDEX(FS)] = gregs.fs;
+ regs[REG_INDEX(GS)] = gregs.gs;
+
+#endif /* amd64 */
+
+#if defined(sparc) || defined(sparcv9)
+
+#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg
+
+#ifdef _LP64
+ regs[REG_INDEX(R_PSR)] = gregs.tstate;
+ regs[REG_INDEX(R_PC)] = gregs.tpc;
+ regs[REG_INDEX(R_nPC)] = gregs.tnpc;
+ regs[REG_INDEX(R_Y)] = gregs.y;
+#else
+ regs[REG_INDEX(R_PSR)] = gregs.psr;
+ regs[REG_INDEX(R_PC)] = gregs.pc;
+ regs[REG_INDEX(R_nPC)] = gregs.npc;
+ regs[REG_INDEX(R_Y)] = gregs.y;
+#endif
+ regs[REG_INDEX(R_G0)] = 0 ;
+ regs[REG_INDEX(R_G1)] = gregs.u_regs[0];
+ regs[REG_INDEX(R_G2)] = gregs.u_regs[1];
+ regs[REG_INDEX(R_G3)] = gregs.u_regs[2];
+ regs[REG_INDEX(R_G4)] = gregs.u_regs[3];
+ regs[REG_INDEX(R_G5)] = gregs.u_regs[4];
+ regs[REG_INDEX(R_G6)] = gregs.u_regs[5];
+ regs[REG_INDEX(R_G7)] = gregs.u_regs[6];
+ regs[REG_INDEX(R_O0)] = gregs.u_regs[7];
+ regs[REG_INDEX(R_O1)] = gregs.u_regs[8];
+ regs[REG_INDEX(R_O2)] = gregs.u_regs[ 9];
+ regs[REG_INDEX(R_O3)] = gregs.u_regs[10];
+ regs[REG_INDEX(R_O4)] = gregs.u_regs[11];
+ regs[REG_INDEX(R_O5)] = gregs.u_regs[12];
+ regs[REG_INDEX(R_O6)] = gregs.u_regs[13];
+ regs[REG_INDEX(R_O7)] = gregs.u_regs[14];
+#endif /* sparc */
+
+
+ (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
+ return array;
+}
diff --git a/hotspot/agent/src/os/linux/Makefile b/hotspot/agent/src/os/linux/Makefile
new file mode 100644
index 00000000000..e243171bc2e
--- /dev/null
+++ b/hotspot/agent/src/os/linux/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+ARCH := $(shell if ([ `uname -m` = "ia64" ]) ; then echo ia64 ; elif ([ `uname -m` = "x86_64" ]) ; then echo amd64; elif ([ `uname -m` = "sparc64" ]) ; then echo sparc; else echo i386 ; fi )
+GCC = gcc
+
+JAVAH = ${JAVA_HOME}/bin/javah
+
+SOURCES = salibelf.c \
+ symtab.c \
+ libproc_impl.c \
+ ps_proc.c \
+ ps_core.c \
+ LinuxDebuggerLocal.c
+
+INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
+
+OBJS = $(SOURCES:.c=.o)
+
+LIBS = -lthread_db
+
+CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES)
+
+LIBSA = $(ARCH)/libsaproc.so
+
+all: $(LIBSA)
+
+LinuxDebuggerLocal.o: LinuxDebuggerLocal.c
+ $(JAVAH) -jni -classpath ../../../build/classes \
+ sun.jvm.hotspot.debugger.x86.X86ThreadContext \
+ sun.jvm.hotspot.debugger.sparc.SPARCThreadContext \
+ sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
+ $(GCC) $(CFLAGS) $<
+
+.c.obj:
+ $(GCC) $(CFLAGS)
+
+ifndef LDNOMAP
+ LFLAGS_LIBSA = -Xlinker --version-script=mapfile
+endif
+
+$(LIBSA): $(OBJS) mapfile
+ if [ ! -d $(ARCH) ] ; then mkdir $(ARCH) ; fi
+ $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
+
+test.o: test.c
+ $(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c
+
+test: test.o
+ $(GCC) -o test test.o -L$(ARCH) -lsaproc $(LIBS)
+
+clean:
+ rm -rf $(LIBSA)
+ rm -rf $(OBJS)
+ rmdir $(ARCH)
+
diff --git a/hotspot/agent/src/os/linux/elfmacros.h b/hotspot/agent/src/os/linux/elfmacros.h
new file mode 100644
index 00000000000..6f26819e916
--- /dev/null
+++ b/hotspot/agent/src/os/linux/elfmacros.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _ELFMACROS_H_
+#define _ELFMACROS_H_
+
+#if defined(_LP64)
+#define ELF_EHDR Elf64_Ehdr
+#define ELF_SHDR Elf64_Shdr
+#define ELF_PHDR Elf64_Phdr
+#define ELF_SYM Elf64_Sym
+#define ELF_NHDR Elf64_Nhdr
+#define ELF_DYN Elf64_Dyn
+#define ELF_ADDR Elf64_Addr
+
+#define ELF_ST_TYPE ELF64_ST_TYPE
+
+#else
+
+#define ELF_EHDR Elf32_Ehdr
+#define ELF_SHDR Elf32_Shdr
+#define ELF_PHDR Elf32_Phdr
+#define ELF_SYM Elf32_Sym
+#define ELF_NHDR Elf32_Nhdr
+#define ELF_DYN Elf32_Dyn
+#define ELF_ADDR Elf32_Addr
+
+#define ELF_ST_TYPE ELF32_ST_TYPE
+
+#endif
+
+
+#endif /* _ELFMACROS_H_ */
diff --git a/hotspot/agent/src/os/linux/libproc.h b/hotspot/agent/src/os/linux/libproc.h
new file mode 100644
index 00000000000..cd0dbc2ce4b
--- /dev/null
+++ b/hotspot/agent/src/os/linux/libproc.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _LIBPROC_H_
+#define _LIBPROC_H_
+
+#include
+#include
+#include "proc_service.h"
+
+#if defined(sparc) || defined(sparcv9)
+/*
+ If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
+ otherwise it should be from /usr/include/asm-sparc
+ These two files define pt_regs structure differently
+*/
+#ifdef _LP64
+#include "asm-sparc64/ptrace.h"
+#else
+#include "asm-sparc/ptrace.h"
+#endif
+
+#endif //sparc or sparcv9
+
+/************************************************************************************
+
+0. This is very minimal subset of Solaris libproc just enough for current application.
+Please note that the bulk of the functionality is from proc_service interface. This
+adds Pgrab__ and some missing stuff. We hide the difference b/w live process and core
+file by this interface.
+
+1. pthread_id unique in both NPTL & LinuxThreads. We store this in
+OSThread::_pthread_id in JVM code.
+
+2. All threads see the same pid when they call getpid() under NPTL.
+Threads receive different pid under LinuxThreads. We used to save the result of
+::getpid() call in OSThread::_thread_id. This way uniqueness of OSThread::_thread_id
+was lost under NPTL. Now, we store the result of ::gettid() call in
+OSThread::_thread_id. Because gettid returns actual pid of thread (lwp id), this is
+unique again. We therefore use OSThread::_thread_id as unique identifier.
+
+3. There is a unique LWP id under both thread libraries. libthread_db maps pthread_id
+to its underlying lwp_id under both the thread libraries. thread_info.lwp_id stores
+lwp_id of the thread. The lwp id is nothing but the actual pid of clone'd processes. But
+unfortunately libthread_db does not work very well for core dumps. So, we get pthread_id
+only for processes. For core dumps, we don't use libthread_db at all (like gdb).
+
+4. ptrace operates on this LWP id under both the thread libraries. When we say 'pid' for
+ptrace call, we refer to lwp_id of the thread.
+
+5. for core file, we parse ELF files and read data from them. For processes we use
+combination of ptrace and /proc calls.
+
+*************************************************************************************/
+
+#ifdef ia64
+struct user_regs_struct {
+/* copied from user.h which doesn't define this in a struct */
+
+#define IA64_REG_COUNT (EF_SIZE/8+32) /* integer and fp regs */
+unsigned long regs[IA64_REG_COUNT]; /* integer and fp regs */
+};
+#endif
+
+#if defined(sparc) || defined(sparcv9)
+#define user_regs_struct pt_regs
+#endif
+
+// This C bool type must be int for compatibility with Linux calls and
+// it would be a mistake to equivalence it to C++ bool on many platforms
+
+typedef int bool;
+#define true 1
+#define false 0
+
+struct ps_prochandle;
+
+// attach to a process
+struct ps_prochandle* Pgrab(pid_t pid);
+
+// attach to a core dump
+struct ps_prochandle* Pgrab_core(const char* execfile, const char* corefile);
+
+// release a process or core
+void Prelease(struct ps_prochandle* ph);
+
+// functions not directly available in Solaris libproc
+
+// initialize libproc (call this only once per app)
+// pass true to make library verbose
+bool init_libproc(bool verbose);
+
+// get number of threads
+int get_num_threads(struct ps_prochandle* ph);
+
+// get lwp_id of n'th thread
+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index);
+
+// get regs for a given lwp
+bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lid, struct user_regs_struct* regs);
+
+// get number of shared objects
+int get_num_libs(struct ps_prochandle* ph);
+
+// get name of n'th lib
+const char* get_lib_name(struct ps_prochandle* ph, int index);
+
+// get base of lib
+uintptr_t get_lib_base(struct ps_prochandle* ph, int index);
+
+// returns true if given library is found in lib list
+bool find_lib(struct ps_prochandle* ph, const char *lib_name);
+
+// symbol lookup
+uintptr_t lookup_symbol(struct ps_prochandle* ph, const char* object_name,
+ const char* sym_name);
+
+// address->nearest symbol lookup. return NULL for no symbol
+const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset);
+
+#endif //__LIBPROC_H_
diff --git a/hotspot/agent/src/os/linux/libproc_impl.c b/hotspot/agent/src/os/linux/libproc_impl.c
new file mode 100644
index 00000000000..be00178f22f
--- /dev/null
+++ b/hotspot/agent/src/os/linux/libproc_impl.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include "libproc_impl.h"
+
+static const char* alt_root = NULL;
+static int alt_root_len = -1;
+
+#define SA_ALTROOT "SA_ALTROOT"
+
+static void init_alt_root() {
+ if (alt_root_len == -1) {
+ alt_root = getenv(SA_ALTROOT);
+ if (alt_root) {
+ alt_root_len = strlen(alt_root);
+ } else {
+ alt_root_len = 0;
+ }
+ }
+}
+
+int pathmap_open(const char* name) {
+ int fd;
+ char alt_path[PATH_MAX + 1];
+
+ init_alt_root();
+ fd = open(name, O_RDONLY);
+ if (fd >= 0) {
+ return fd;
+ }
+
+ if (alt_root_len > 0) {
+ strcpy(alt_path, alt_root);
+ strcat(alt_path, name);
+ fd = open(alt_path, O_RDONLY);
+ if (fd >= 0) {
+ print_debug("path %s substituted for %s\n", alt_path, name);
+ return fd;
+ }
+
+ if (strrchr(name, '/')) {
+ strcpy(alt_path, alt_root);
+ strcat(alt_path, strrchr(name, '/'));
+ fd = open(alt_path, O_RDONLY);
+ if (fd >= 0) {
+ print_debug("path %s substituted for %s\n", alt_path, name);
+ return fd;
+ }
+ }
+ }
+
+ return -1;
+}
+
+static bool _libsaproc_debug;
+
+void print_debug(const char* format,...) {
+ if (_libsaproc_debug) {
+ va_list alist;
+
+ va_start(alist, format);
+ fputs("libsaproc DEBUG: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+ }
+}
+
+bool is_debug() {
+ return _libsaproc_debug;
+}
+
+// initialize libproc
+bool init_libproc(bool debug) {
+ // init debug mode
+ _libsaproc_debug = debug;
+
+ // initialize the thread_db library
+ if (td_init() != TD_OK) {
+ print_debug("libthread_db's td_init failed\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void destroy_lib_info(struct ps_prochandle* ph) {
+ lib_info* lib = ph->libs;
+ while (lib) {
+ lib_info *next = lib->next;
+ if (lib->symtab) {
+ destroy_symtab(lib->symtab);
+ }
+ free(lib);
+ lib = next;
+ }
+}
+
+static void destroy_thread_info(struct ps_prochandle* ph) {
+ thread_info* thr = ph->threads;
+ while (thr) {
+ thread_info *next = thr->next;
+ free(thr);
+ thr = next;
+ }
+}
+
+// ps_prochandle cleanup
+
+// ps_prochandle cleanup
+void Prelease(struct ps_prochandle* ph) {
+ // do the "derived class" clean-up first
+ ph->ops->release(ph);
+ destroy_lib_info(ph);
+ destroy_thread_info(ph);
+ free(ph);
+}
+
+lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
+ return add_lib_info_fd(ph, libname, -1, base);
+}
+
+lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
+ lib_info* newlib;
+
+ if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
+ print_debug("can't allocate memory for lib_info\n");
+ return NULL;
+ }
+
+ strncpy(newlib->name, libname, sizeof(newlib->name));
+ newlib->base = base;
+
+ if (fd == -1) {
+ if ( (newlib->fd = pathmap_open(newlib->name)) < 0) {
+ print_debug("can't open shared object %s\n", newlib->name);
+ free(newlib);
+ return NULL;
+ }
+ } else {
+ newlib->fd = fd;
+ }
+
+ // check whether we have got an ELF file. /proc//map
+ // gives out all file mappings and not just shared objects
+ if (is_elf_file(newlib->fd) == false) {
+ close(newlib->fd);
+ free(newlib);
+ return NULL;
+ }
+
+ newlib->symtab = build_symtab(newlib->fd);
+ if (newlib->symtab == NULL) {
+ print_debug("symbol table build failed for %s\n", newlib->name);
+ }
+
+ // even if symbol table building fails, we add the lib_info.
+ // This is because we may need to read from the ELF file for core file
+ // address read functionality. lookup_symbol checks for NULL symtab.
+ if (ph->libs) {
+ ph->lib_tail->next = newlib;
+ ph->lib_tail = newlib;
+ } else {
+ ph->libs = ph->lib_tail = newlib;
+ }
+ ph->num_libs++;
+
+ return newlib;
+}
+
+// lookup for a specific symbol
+uintptr_t lookup_symbol(struct ps_prochandle* ph, const char* object_name,
+ const char* sym_name) {
+ // ignore object_name. search in all libraries
+ // FIXME: what should we do with object_name?? The library names are obtained
+ // by parsing /proc//maps, which may not be the same as object_name.
+ // What we need is a utility to map object_name to real file name, something
+ // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For
+ // now, we just ignore object_name and do a global search for the symbol.
+
+ lib_info* lib = ph->libs;
+ while (lib) {
+ if (lib->symtab) {
+ uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL);
+ if (res) return res;
+ }
+ lib = lib->next;
+ }
+
+ print_debug("lookup failed for symbol '%s' in obj '%s'\n",
+ sym_name, object_name);
+ return (uintptr_t) NULL;
+}
+
+
+const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) {
+ const char* res = NULL;
+ lib_info* lib = ph->libs;
+ while (lib) {
+ if (lib->symtab && addr >= lib->base) {
+ res = nearest_symbol(lib->symtab, addr - lib->base, poffset);
+ if (res) return res;
+ }
+ lib = lib->next;
+ }
+ return NULL;
+}
+
+// add a thread to ps_prochandle
+thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
+ thread_info* newthr;
+ if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
+ print_debug("can't allocate memory for thread_info\n");
+ return NULL;
+ }
+
+ // initialize thread info
+ newthr->pthread_id = pthread_id;
+ newthr->lwp_id = lwp_id;
+
+ // add new thread to the list
+ newthr->next = ph->threads;
+ ph->threads = newthr;
+ ph->num_threads++;
+ return newthr;
+}
+
+
+// struct used for client data from thread_db callback
+struct thread_db_client_data {
+ struct ps_prochandle* ph;
+ thread_info_callback callback;
+};
+
+// callback function for libthread_db
+static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
+ struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
+ td_thrinfo_t ti;
+ td_err_e err;
+
+ memset(&ti, 0, sizeof(ti));
+ err = td_thr_get_info(th_p, &ti);
+ if (err != TD_OK) {
+ print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
+ return err;
+ }
+
+ print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
+
+ if (ptr->callback(ptr->ph, ti.ti_tid, ti.ti_lid) != true)
+ return TD_ERR;
+
+ return TD_OK;
+}
+
+// read thread_info using libthread_db
+bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
+ struct thread_db_client_data mydata;
+ td_thragent_t* thread_agent = NULL;
+ if (td_ta_new(ph, &thread_agent) != TD_OK) {
+ print_debug("can't create libthread_db agent\n");
+ return false;
+ }
+
+ mydata.ph = ph;
+ mydata.callback = cb;
+
+ // we use libthread_db iterator to iterate thru list of threads.
+ if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
+ TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
+ td_ta_delete(thread_agent);
+ return false;
+ }
+
+ // delete thread agent
+ td_ta_delete(thread_agent);
+ return true;
+}
+
+
+// get number of threads
+int get_num_threads(struct ps_prochandle* ph) {
+ return ph->num_threads;
+}
+
+// get lwp_id of n'th thread
+lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
+ int count = 0;
+ thread_info* thr = ph->threads;
+ while (thr) {
+ if (count == index) {
+ return thr->lwp_id;
+ }
+ count++;
+ thr = thr->next;
+ }
+ return -1;
+}
+
+// get regs for a given lwp
+bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct user_regs_struct* regs) {
+ return ph->ops->get_lwp_regs(ph, lwp_id, regs);
+}
+
+// get number of shared objects
+int get_num_libs(struct ps_prochandle* ph) {
+ return ph->num_libs;
+}
+
+// get name of n'th solib
+const char* get_lib_name(struct ps_prochandle* ph, int index) {
+ int count = 0;
+ lib_info* lib = ph->libs;
+ while (lib) {
+ if (count == index) {
+ return lib->name;
+ }
+ count++;
+ lib = lib->next;
+ }
+ return NULL;
+}
+
+// get base address of a lib
+uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
+ int count = 0;
+ lib_info* lib = ph->libs;
+ while (lib) {
+ if (count == index) {
+ return lib->base;
+ }
+ count++;
+ lib = lib->next;
+ }
+ return (uintptr_t)NULL;
+}
+
+bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
+ lib_info *p = ph->libs;
+ while (p) {
+ if (strcmp(p->name, lib_name) == 0) {
+ return true;
+ }
+ p = p->next;
+ }
+ return false;
+}
+
+//--------------------------------------------------------------------------
+// proc service functions
+
+// get process id
+pid_t ps_getpid(struct ps_prochandle *ph) {
+ return ph->pid;
+}
+
+// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
+// of the load object object_name in the target process identified by ph.
+// It returns the symbol's value as an address in the target process in
+// *sym_addr.
+
+ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
+ const char *sym_name, psaddr_t *sym_addr) {
+ *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name);
+ return (*sym_addr ? PS_OK : PS_NOSYM);
+}
+
+// read "size" bytes info "buf" from address "addr"
+ps_err_e ps_pdread(struct ps_prochandle *ph, psaddr_t addr,
+ void *buf, size_t size) {
+ return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR;
+}
+
+// write "size" bytes of data to debuggee at address "addr"
+ps_err_e ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr,
+ const void *buf, size_t size) {
+ return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR;
+}
+
+// ------------------------------------------------------------------------
+// Functions below this point are not yet implemented. They are here only
+// to make the linker happy.
+
+ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) {
+ print_debug("ps_lsetfpregs not implemented\n");
+ return PS_OK;
+}
+
+ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) {
+ print_debug("ps_lsetregs not implemented\n");
+ return PS_OK;
+}
+
+ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *fpregs) {
+ print_debug("ps_lgetfpregs not implemented\n");
+ return PS_OK;
+}
+
+ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) {
+ print_debug("ps_lgetfpregs not implemented\n");
+ return PS_OK;
+}
+
+// new libthread_db of NPTL seem to require this symbol
+ps_err_e ps_get_thread_area() {
+ print_debug("ps_get_thread_area not implemented\n");
+ return PS_OK;
+}
diff --git a/hotspot/agent/src/os/linux/libproc_impl.h b/hotspot/agent/src/os/linux/libproc_impl.h
new file mode 100644
index 00000000000..43fbb59c296
--- /dev/null
+++ b/hotspot/agent/src/os/linux/libproc_impl.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _LIBPROC_IMPL_H_
+#define _LIBPROC_IMPL_H_
+
+#include
+#include
+#include "libproc.h"
+#include "symtab.h"
+
+// data structures in this file mimic those of Solaris 8.0 - libproc's Pcontrol.h
+
+#define BUF_SIZE (PATH_MAX + NAME_MAX + 1)
+
+// list of shared objects
+typedef struct lib_info {
+ char name[BUF_SIZE];
+ uintptr_t base;
+ struct symtab* symtab;
+ int fd; // file descriptor for lib
+ struct lib_info* next;
+} lib_info;
+
+// list of threads
+typedef struct thread_info {
+ lwpid_t lwp_id;
+ pthread_t pthread_id; // not used cores, always -1
+ struct user_regs_struct regs; // not for process, core uses for caching regset
+ struct thread_info* next;
+} thread_info;
+
+// list of virtual memory maps
+typedef struct map_info {
+ int fd; // file descriptor
+ off_t offset; // file offset of this mapping
+ uintptr_t vaddr; // starting virtual address
+ size_t memsz; // size of the mapping
+ struct map_info* next;
+} map_info;
+
+// vtable for ps_prochandle
+typedef struct ps_prochandle_ops {
+ // "derived class" clean-up
+ void (*release)(struct ps_prochandle* ph);
+ // read from debuggee
+ bool (*p_pread)(struct ps_prochandle *ph,
+ uintptr_t addr, char *buf, size_t size);
+ // write into debuggee
+ bool (*p_pwrite)(struct ps_prochandle *ph,
+ uintptr_t addr, const char *buf , size_t size);
+ // get integer regset of a thread
+ bool (*get_lwp_regs)(struct ps_prochandle* ph, lwpid_t lwp_id, struct user_regs_struct* regs);
+} ps_prochandle_ops;
+
+// the ps_prochandle
+
+struct core_data {
+ int core_fd; // file descriptor of core file
+ int exec_fd; // file descriptor of exec file
+ int interp_fd; // file descriptor of interpreter (ld-linux.so.2)
+ // part of the class sharing workaround
+ int classes_jsa_fd; // file descriptor of class share archive
+ uintptr_t dynamic_addr; // address of dynamic section of a.out
+ uintptr_t ld_base_addr; // base address of ld.so
+ size_t num_maps; // number of maps.
+ map_info* maps; // maps in a linked list
+ // part of the class sharing workaround
+ map_info* class_share_maps;// class share maps in a linked list
+ map_info** map_array; // sorted (by vaddr) array of map_info pointers
+};
+
+struct ps_prochandle {
+ ps_prochandle_ops* ops; // vtable ptr
+ pid_t pid;
+ int num_libs;
+ lib_info* libs; // head of lib list
+ lib_info* lib_tail; // tail of lib list - to append at the end
+ int num_threads;
+ thread_info* threads; // head of thread list
+ struct core_data* core; // data only used for core dumps, NULL for process
+};
+
+int pathmap_open(const char* name);
+
+void print_debug(const char* format,...);
+bool is_debug();
+
+typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
+
+// reads thread info using libthread_db and calls above callback for each thread
+bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb);
+
+// adds a new shared object to lib list, returns NULL on failure
+lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base);
+
+// adds a new shared object to lib list, supply open lib file descriptor as well
+lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
+ uintptr_t base);
+
+// adds a new thread to threads list, returns NULL on failure
+thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
+
+// a test for ELF signature without using libelf
+bool is_elf_file(int fd);
+
+#endif //_LIBPROC_IMPL_H_
diff --git a/hotspot/agent/src/os/linux/mapfile b/hotspot/agent/src/os/linux/mapfile
new file mode 100644
index 00000000000..485e100bfc4
--- /dev/null
+++ b/hotspot/agent/src/os/linux/mapfile
@@ -0,0 +1,62 @@
+#
+
+#
+# Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+ global:
+
+ # native methods of LinuxDebuggerLocal class
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_init0;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getAddressSize;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_detach0;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByName0;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_lookupByAddress0;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_readBytesFromProcess0;
+ Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0;
+
+ # proc_service.h functions - to be used by libthread_db
+ ps_getpid;
+ ps_pglobal_lookup;
+ ps_pdread;
+ ps_pdwrite;
+ ps_lsetfpregs;
+ ps_lsetregs;
+ ps_lgetfpregs;
+ ps_lgetregs;
+ ps_get_thread_area;
+
+ # used by attach test program
+ init_libproc;
+ Pgrab;
+ Pgrab_core;
+ Prelease;
+
+ local:
+ *;
+};
diff --git a/hotspot/agent/src/os/linux/proc_service.h b/hotspot/agent/src/os/linux/proc_service.h
new file mode 100644
index 00000000000..9cf1315a126
--- /dev/null
+++ b/hotspot/agent/src/os/linux/proc_service.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _PROC_SERVICE_H_
+#define _PROC_SERVICE_H_
+
+#include
+#include
+
+// Linux does not have the proc service library, though it does provide the
+// thread_db library which can be used to manipulate threads without having
+// to know the details of LinuxThreads or NPTL
+
+// copied from Solaris "proc_service.h"
+typedef enum {
+ PS_OK, /* generic "call succeeded" */
+ PS_ERR, /* generic error */
+ PS_BADPID, /* bad process handle */
+ PS_BADLID, /* bad lwp identifier */
+ PS_BADADDR, /* bad address */
+ PS_NOSYM, /* p_lookup() could not find given symbol */
+ PS_NOFREGS /* FPU register set not available for given lwp */
+} ps_err_e;
+
+// ps_getpid() is only defined on Linux to return a thread's process ID
+pid_t ps_getpid(struct ps_prochandle *ph);
+
+// ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
+// of the load object object_name in the target process identified by ph.
+// It returns the symbol's value as an address in the target process in
+// *sym_addr.
+
+ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
+ const char *sym_name, psaddr_t *sym_addr);
+
+// read "size" bytes of data from debuggee at address "addr"
+ps_err_e ps_pdread(struct ps_prochandle *ph, psaddr_t addr,
+ void *buf, size_t size);
+
+// write "size" bytes of data to debuggee at address "addr"
+ps_err_e ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr,
+ const void *buf, size_t size);
+
+ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs);
+
+ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset);
+
+ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *fpregs);
+
+ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset);
+
+// new libthread_db of NPTL seem to require this symbol
+ps_err_e ps_get_thread_area();
+
+#endif /* _PROC_SERVICE_H_ */
diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c
new file mode 100644
index 00000000000..b8890f15fc9
--- /dev/null
+++ b/hotspot/agent/src/os/linux/ps_core.c
@@ -0,0 +1,1011 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "libproc_impl.h"
+#include "salibelf.h"
+
+// This file has the libproc implementation to read core files.
+// For live processes, refer to ps_proc.c. Portions of this is adapted
+// /modelled after Solaris libproc.so (in particular Pcore.c)
+
+//----------------------------------------------------------------------
+// ps_prochandle cleanup helper functions
+
+// close all file descriptors
+static void close_elf_files(struct ps_prochandle* ph) {
+ lib_info* lib = NULL;
+
+ // close core file descriptor
+ if (ph->core->core_fd >= 0)
+ close(ph->core->core_fd);
+
+ // close exec file descriptor
+ if (ph->core->exec_fd >= 0)
+ close(ph->core->exec_fd);
+
+ // close interp file descriptor
+ if (ph->core->interp_fd >= 0)
+ close(ph->core->interp_fd);
+
+ // close class share archive file
+ if (ph->core->classes_jsa_fd >= 0)
+ close(ph->core->classes_jsa_fd);
+
+ // close all library file descriptors
+ lib = ph->libs;
+ while (lib) {
+ int fd = lib->fd;
+ if (fd >= 0 && fd != ph->core->exec_fd) close(fd);
+ lib = lib->next;
+ }
+}
+
+// clean all map_info stuff
+static void destroy_map_info(struct ps_prochandle* ph) {
+ map_info* map = ph->core->maps;
+ while (map) {
+ map_info* next = map->next;
+ free(map);
+ map = next;
+ }
+
+ if (ph->core->map_array) {
+ free(ph->core->map_array);
+ }
+
+ // Part of the class sharing workaround
+ map = ph->core->class_share_maps;
+ while (map) {
+ map_info* next = map->next;
+ free(map);
+ map = next;
+ }
+}
+
+// ps_prochandle operations
+static void core_release(struct ps_prochandle* ph) {
+ if (ph->core) {
+ close_elf_files(ph);
+ destroy_map_info(ph);
+ free(ph->core);
+ }
+}
+
+static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
+ map_info* map;
+ if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
+ print_debug("can't allocate memory for map_info\n");
+ return NULL;
+ }
+
+ // initialize map
+ map->fd = fd;
+ map->offset = offset;
+ map->vaddr = vaddr;
+ map->memsz = memsz;
+ return map;
+}
+
+// add map info with given fd, offset, vaddr and memsz
+static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
+ uintptr_t vaddr, size_t memsz) {
+ map_info* map;
+ if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
+ return NULL;
+ }
+
+ // add this to map list
+ map->next = ph->core->maps;
+ ph->core->maps = map;
+ ph->core->num_maps++;
+
+ return map;
+}
+
+// Part of the class sharing workaround
+static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
+ uintptr_t vaddr, size_t memsz) {
+ map_info* map;
+ if ((map = allocate_init_map(ph->core->classes_jsa_fd,
+ offset, vaddr, memsz)) == NULL) {
+ return NULL;
+ }
+
+ map->next = ph->core->class_share_maps;
+ ph->core->class_share_maps = map;
+}
+
+// Return the map_info for the given virtual address. We keep a sorted
+// array of pointers in ph->map_array, so we can binary search.
+static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
+{
+ int mid, lo = 0, hi = ph->core->num_maps - 1;
+ map_info *mp;
+
+ while (hi - lo > 1) {
+ mid = (lo + hi) / 2;
+ if (addr >= ph->core->map_array[mid]->vaddr)
+ lo = mid;
+ else
+ hi = mid;
+ }
+
+ if (addr < ph->core->map_array[hi]->vaddr)
+ mp = ph->core->map_array[lo];
+ else
+ mp = ph->core->map_array[hi];
+
+ if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz)
+ return (mp);
+
+
+ // Part of the class sharing workaround
+ // Unfortunately, we have no way of detecting -Xshare state.
+ // Check out the share maps atlast, if we don't find anywhere.
+ // This is done this way so to avoid reading share pages
+ // ahead of other normal maps. For eg. with -Xshare:off we don't
+ // want to prefer class sharing data to data from core.
+ mp = ph->core->class_share_maps;
+ if (mp) {
+ print_debug("can't locate map_info at 0x%lx, trying class share maps\n",
+ addr);
+ }
+ while (mp) {
+ if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
+ print_debug("located map_info at 0x%lx from class share maps\n",
+ addr);
+ return (mp);
+ }
+ mp = mp->next;
+ }
+
+ print_debug("can't locate map_info at 0x%lx\n", addr);
+ return (NULL);
+}
+
+//---------------------------------------------------------------
+// Part of the class sharing workaround:
+//
+// With class sharing, pages are mapped from classes[_g].jsa file.
+// The read-only class sharing pages are mapped as MAP_SHARED,
+// PROT_READ pages. These pages are not dumped into core dump.
+// With this workaround, these pages are read from classes[_g].jsa.
+
+// FIXME: !HACK ALERT!
+// The format of sharing achive file header is needed to read shared heap
+// file mappings. For now, I am hard coding portion of FileMapHeader here.
+// Refer to filemap.hpp.
+
+// FileMapHeader describes the shared space data in the file to be
+// mapped. This structure gets written to a file. It is not a class,
+// so that the compilers don't add any compiler-private data to it.
+
+// Refer to CompactingPermGenGen::n_regions in compactingPermGenGen.hpp
+#define NUM_SHARED_MAPS 4
+
+// Refer to FileMapInfo::_current_version in filemap.hpp
+#define CURRENT_ARCHIVE_VERSION 1
+
+struct FileMapHeader {
+ int _magic; // identify file type.
+ int _version; // (from enum, above.)
+ size_t _alignment; // how shared archive should be aligned
+
+ struct space_info {
+ int _file_offset; // sizeof(this) rounded to vm page size
+ char* _base; // copy-on-write base address
+ size_t _capacity; // for validity checking
+ size_t _used; // for setting space top on read
+
+ // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
+ // the C type matching the C++ bool type on any given platform. For
+ // Hotspot on Linux we assume the corresponding C type is char but
+ // licensees on Linux versions may need to adjust the type of these fields.
+ char _read_only; // read only space?
+ char _allow_exec; // executable code in space?
+
+ } _space[NUM_SHARED_MAPS]; // was _space[CompactingPermGenGen::n_regions];
+
+ // Ignore the rest of the FileMapHeader. We don't need those fields here.
+};
+
+static bool read_int(struct ps_prochandle* ph, uintptr_t addr, int* pvalue) {
+ int i;
+ if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
+ *pvalue = i;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
+ uintptr_t uip;
+ if (ps_pdread(ph, (psaddr_t) addr, &uip, sizeof(uip)) == PS_OK) {
+ *pvalue = uip;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+// used to read strings from debuggee
+static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
+ size_t i = 0;
+ char c = ' ';
+
+ while (c != '\0') {
+ if (ps_pdread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK)
+ return false;
+ if (i < size - 1)
+ buf[i] = c;
+ else // smaller buffer
+ return false;
+ i++; addr++;
+ }
+
+ buf[i] = '\0';
+ return true;
+}
+
+#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
+// mangled name of Arguments::SharedArchivePath
+#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
+
+static bool init_classsharing_workaround(struct ps_prochandle* ph) {
+ lib_info* lib = ph->libs;
+ while (lib != NULL) {
+ // we are iterating over shared objects from the core dump. look for
+ // libjvm[_g].so.
+ const char *jvm_name = 0;
+ if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
+ (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
+ char classes_jsa[PATH_MAX];
+ struct FileMapHeader header;
+ size_t n = 0;
+ int fd = -1, m = 0;
+ uintptr_t base = 0, useSharedSpacesAddr = 0;
+ uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
+ int useSharedSpaces = 0;
+ map_info* mi = 0;
+
+ memset(classes_jsa, 0, sizeof(classes_jsa));
+ jvm_name = lib->name;
+ useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
+ if (useSharedSpacesAddr == 0) {
+ print_debug("can't lookup 'UseSharedSpaces' flag\n");
+ return false;
+ }
+
+ if (read_int(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
+ print_debug("can't read the value of 'UseSharedSpaces' flag\n");
+ return false;
+ }
+
+ if (useSharedSpaces == 0) {
+ print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
+ return true;
+ }
+
+ sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
+ if (sharedArchivePathAddrAddr == 0) {
+ print_debug("can't lookup shared archive path symbol\n");
+ return false;
+ }
+
+ if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
+ print_debug("can't read shared archive path pointer\n");
+ return false;
+ }
+
+ if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
+ print_debug("can't read shared archive path value\n");
+ return false;
+ }
+
+ print_debug("looking for %s\n", classes_jsa);
+ // open the class sharing archive file
+ fd = pathmap_open(classes_jsa);
+ if (fd < 0) {
+ print_debug("can't open %s!\n", classes_jsa);
+ ph->core->classes_jsa_fd = -1;
+ return false;
+ } else {
+ print_debug("opened %s\n", classes_jsa);
+ }
+
+ // read FileMapHeader from the file
+ memset(&header, 0, sizeof(struct FileMapHeader));
+ if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
+ != sizeof(struct FileMapHeader)) {
+ print_debug("can't read shared archive file map header from %s\n", classes_jsa);
+ close(fd);
+ return false;
+ }
+
+ // check file magic
+ if (header._magic != 0xf00baba2) {
+ print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
+ classes_jsa, header._magic);
+ close(fd);
+ return false;
+ }
+
+ // check version
+ if (header._version != CURRENT_ARCHIVE_VERSION) {
+ print_debug("%s has wrong shared archive file version %d, expecting %d\n",
+ classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
+ close(fd);
+ return false;
+ }
+
+ ph->core->classes_jsa_fd = fd;
+ // add read-only maps from classes[_g].jsa to the list of maps
+ for (m = 0; m < NUM_SHARED_MAPS; m++) {
+ if (header._space[m]._read_only) {
+ base = (uintptr_t) header._space[m]._base;
+ // no need to worry about the fractional pages at-the-end.
+ // possible fractional pages are handled by core_read_data.
+ add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
+ base, (size_t) header._space[m]._used);
+ print_debug("added a share archive map at 0x%lx\n", base);
+ }
+ }
+ return true;
+ }
+ lib = lib->next;
+ }
+ return true;
+}
+
+
+//---------------------------------------------------------------------------
+// functions to handle map_info
+
+// Order mappings based on virtual address. We use this function as the
+// callback for sorting the array of map_info pointers.
+static int core_cmp_mapping(const void *lhsp, const void *rhsp)
+{
+ const map_info *lhs = *((const map_info **)lhsp);
+ const map_info *rhs = *((const map_info **)rhsp);
+
+ if (lhs->vaddr == rhs->vaddr)
+ return (0);
+
+ return (lhs->vaddr < rhs->vaddr ? -1 : 1);
+}
+
+// we sort map_info by starting virtual address so that we can do
+// binary search to read from an address.
+static bool sort_map_array(struct ps_prochandle* ph) {
+ size_t num_maps = ph->core->num_maps;
+ map_info* map = ph->core->maps;
+ int i = 0;
+
+ // allocate map_array
+ map_info** array;
+ if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
+ print_debug("can't allocate memory for map array\n");
+ return false;
+ }
+
+ // add maps to array
+ while (map) {
+ array[i] = map;
+ i++;
+ map = map->next;
+ }
+
+ // sort is called twice. If this is second time, clear map array
+ if (ph->core->map_array) free(ph->core->map_array);
+ ph->core->map_array = array;
+ // sort the map_info array by base virtual address.
+ qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
+ core_cmp_mapping);
+
+ // print map
+ if (is_debug()) {
+ int j = 0;
+ print_debug("---- sorted virtual address map ----\n");
+ for (j = 0; j < ph->core->num_maps; j++) {
+ print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
+ ph->core->map_array[j]->memsz);
+ }
+ }
+
+ return true;
+}
+
+#ifndef MIN
+#define MIN(x, y) (((x) < (y))? (x): (y))
+#endif
+
+static bool core_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
+ ssize_t resid = size;
+ int page_size=sysconf(_SC_PAGE_SIZE);
+ while (resid != 0) {
+ map_info *mp = core_lookup(ph, addr);
+ uintptr_t mapoff;
+ ssize_t len, rem;
+ off_t off;
+ int fd;
+
+ if (mp == NULL)
+ break; /* No mapping for this address */
+
+ fd = mp->fd;
+ mapoff = addr - mp->vaddr;
+ len = MIN(resid, mp->memsz - mapoff);
+ off = mp->offset + mapoff;
+
+ if ((len = pread(fd, buf, len, off)) <= 0)
+ break;
+
+ resid -= len;
+ addr += len;
+ buf = (char *)buf + len;
+
+ // mappings always start at page boundary. But, may end in fractional
+ // page. fill zeros for possible fractional page at the end of a mapping.
+ rem = mp->memsz % page_size;
+ if (rem > 0) {
+ rem = page_size - rem;
+ len = MIN(resid, rem);
+ resid -= len;
+ addr += len;
+ // we are not assuming 'buf' to be zero initialized.
+ memset(buf, 0, len);
+ buf += len;
+ }
+ }
+
+ if (resid) {
+ print_debug("core read failed for %d byte(s) @ 0x%lx (%d more bytes)\n",
+ size, addr, resid);
+ return false;
+ } else {
+ return true;
+ }
+}
+
+// null implementation for write
+static bool core_write_data(struct ps_prochandle* ph,
+ uintptr_t addr, const char *buf , size_t size) {
+ return false;
+}
+
+static bool core_get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id,
+ struct user_regs_struct* regs) {
+ // for core we have cached the lwp regs from NOTE section
+ thread_info* thr = ph->threads;
+ while (thr) {
+ if (thr->lwp_id == lwp_id) {
+ memcpy(regs, &thr->regs, sizeof(struct user_regs_struct));
+ return true;
+ }
+ thr = thr->next;
+ }
+ return false;
+}
+
+static ps_prochandle_ops core_ops = {
+ release: core_release,
+ p_pread: core_read_data,
+ p_pwrite: core_write_data,
+ get_lwp_regs: core_get_lwp_regs
+};
+
+// read regs and create thread from NT_PRSTATUS entries from core file
+static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size_t nbytes) {
+ // we have to read prstatus_t from buf
+ // assert(nbytes == sizeof(prstaus_t), "size mismatch on prstatus_t");
+ prstatus_t* prstat = (prstatus_t*) buf;
+ thread_info* newthr;
+ print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
+ // we set pthread_t to -1 for core dump
+ if((newthr = add_thread_info(ph, (pthread_t) -1, prstat->pr_pid)) == NULL)
+ return false;
+
+ // copy regs
+ memcpy(&newthr->regs, prstat->pr_reg, sizeof(struct user_regs_struct));
+
+ if (is_debug()) {
+ print_debug("integer regset\n");
+#ifdef i386
+ // print the regset
+ print_debug("\teax = 0x%x\n", newthr->regs.eax);
+ print_debug("\tebx = 0x%x\n", newthr->regs.ebx);
+ print_debug("\tecx = 0x%x\n", newthr->regs.ecx);
+ print_debug("\tedx = 0x%x\n", newthr->regs.edx);
+ print_debug("\tesp = 0x%x\n", newthr->regs.esp);
+ print_debug("\tebp = 0x%x\n", newthr->regs.ebp);
+ print_debug("\tesi = 0x%x\n", newthr->regs.esi);
+ print_debug("\tedi = 0x%x\n", newthr->regs.edi);
+ print_debug("\teip = 0x%x\n", newthr->regs.eip);
+#endif
+
+#if defined(amd64) || defined(x86_64)
+ // print the regset
+ print_debug("\tr15 = 0x%lx\n", newthr->regs.r15);
+ print_debug("\tr14 = 0x%lx\n", newthr->regs.r14);
+ print_debug("\tr13 = 0x%lx\n", newthr->regs.r13);
+ print_debug("\tr12 = 0x%lx\n", newthr->regs.r12);
+ print_debug("\trbp = 0x%lx\n", newthr->regs.rbp);
+ print_debug("\trbx = 0x%lx\n", newthr->regs.rbx);
+ print_debug("\tr11 = 0x%lx\n", newthr->regs.r11);
+ print_debug("\tr10 = 0x%lx\n", newthr->regs.r10);
+ print_debug("\tr9 = 0x%lx\n", newthr->regs.r9);
+ print_debug("\tr8 = 0x%lx\n", newthr->regs.r8);
+ print_debug("\trax = 0x%lx\n", newthr->regs.rax);
+ print_debug("\trcx = 0x%lx\n", newthr->regs.rcx);
+ print_debug("\trdx = 0x%lx\n", newthr->regs.rdx);
+ print_debug("\trsi = 0x%lx\n", newthr->regs.rsi);
+ print_debug("\trdi = 0x%lx\n", newthr->regs.rdi);
+ print_debug("\torig_rax = 0x%lx\n", newthr->regs.orig_rax);
+ print_debug("\trip = 0x%lx\n", newthr->regs.rip);
+ print_debug("\tcs = 0x%lx\n", newthr->regs.cs);
+ print_debug("\teflags = 0x%lx\n", newthr->regs.eflags);
+ print_debug("\trsp = 0x%lx\n", newthr->regs.rsp);
+ print_debug("\tss = 0x%lx\n", newthr->regs.ss);
+ print_debug("\tfs_base = 0x%lx\n", newthr->regs.fs_base);
+ print_debug("\tgs_base = 0x%lx\n", newthr->regs.gs_base);
+ print_debug("\tds = 0x%lx\n", newthr->regs.ds);
+ print_debug("\tes = 0x%lx\n", newthr->regs.es);
+ print_debug("\tfs = 0x%lx\n", newthr->regs.fs);
+ print_debug("\tgs = 0x%lx\n", newthr->regs.gs);
+#endif
+ }
+
+ return true;
+}
+
+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
+
+// read NT_PRSTATUS entries from core NOTE segment
+static bool core_handle_note(struct ps_prochandle* ph, ELF_PHDR* note_phdr) {
+ char* buf = NULL;
+ char* p = NULL;
+ size_t size = note_phdr->p_filesz;
+
+ // we are interested in just prstatus entries. we will ignore the rest.
+ // Advance the seek pointer to the start of the PT_NOTE data
+ if (lseek(ph->core->core_fd, note_phdr->p_offset, SEEK_SET) == (off_t)-1) {
+ print_debug("failed to lseek to PT_NOTE data\n");
+ return false;
+ }
+
+ // Now process the PT_NOTE structures. Each one is preceded by
+ // an Elf{32/64}_Nhdr structure describing its type and size.
+ if ( (buf = (char*) malloc(size)) == NULL) {
+ print_debug("can't allocate memory for reading core notes\n");
+ goto err;
+ }
+
+ // read notes into buffer
+ if (read(ph->core->core_fd, buf, size) != size) {
+ print_debug("failed to read notes, core file must have been truncated\n");
+ goto err;
+ }
+
+ p = buf;
+ while (p < buf + size) {
+ ELF_NHDR* notep = (ELF_NHDR*) p;
+ char* descdata = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
+ print_debug("Note header with n_type = %d and n_descsz = %u\n",
+ notep->n_type, notep->n_descsz);
+
+ if (notep->n_type == NT_PRSTATUS) {
+ if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true)
+ return false;
+ }
+ p = descdata + ROUNDUP(notep->n_descsz, 4);
+ }
+
+ free(buf);
+ return true;
+
+err:
+ if (buf) free(buf);
+ return false;
+}
+
+// read all segments from core file
+static bool read_core_segments(struct ps_prochandle* ph, ELF_EHDR* core_ehdr) {
+ int i = 0;
+ ELF_PHDR* phbuf = NULL;
+ ELF_PHDR* core_php = NULL;
+
+ if ((phbuf = read_program_header_table(ph->core->core_fd, core_ehdr)) == NULL)
+ return false;
+
+ /*
+ * Now iterate through the program headers in the core file.
+ * We're interested in two types of Phdrs: PT_NOTE (which
+ * contains a set of saved /proc structures), and PT_LOAD (which
+ * represents a memory mapping from the process's address space).
+ *
+ * Difference b/w Solaris PT_NOTE and Linux PT_NOTE:
+ *
+ * In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
+ * contains /proc structs in the pre-2.6 unstructured /proc format. the last
+ * PT_NOTE has data in new /proc format.
+ *
+ * In Solaris, there is only one pstatus (process status). pstatus contains
+ * integer register set among other stuff. For each LWP, we have one lwpstatus
+ * entry that has integer regset for that LWP.
+ *
+ * Linux threads are actually 'clone'd processes. To support core analysis
+ * of "multithreaded" process, Linux creates more than one pstatus (called
+ * "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
+ * "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
+ * function "elf_core_dump".
+ */
+
+ for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
+ switch (core_php->p_type) {
+ case PT_NOTE:
+ if (core_handle_note(ph, core_php) != true) goto err;
+ break;
+
+ case PT_LOAD: {
+ if (core_php->p_filesz != 0) {
+ if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
+ core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
+ }
+ break;
+ }
+ }
+
+ core_php++;
+ }
+
+ free(phbuf);
+ return true;
+err:
+ free(phbuf);
+ return false;
+}
+
+// read segments of a shared object
+static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
+ int i = 0;
+ ELF_PHDR* phbuf;
+ ELF_PHDR* lib_php = NULL;
+
+ if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
+ return false;
+
+ // we want to process only PT_LOAD segments that are not writable.
+ // i.e., text segments. The read/write/exec (data) segments would
+ // have been already added from core file segments.
+ for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
+ if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
+ if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
+ goto err;
+ }
+ lib_php++;
+ }
+
+ free(phbuf);
+ return true;
+err:
+ free(phbuf);
+ return false;
+}
+
+// process segments from interpreter (ld.so or ld-linux.so)
+static bool read_interp_segments(struct ps_prochandle* ph) {
+ ELF_EHDR interp_ehdr;
+
+ if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
+ print_debug("interpreter is not a valid ELF file\n");
+ return false;
+ }
+
+ if (read_lib_segments(ph, ph->core->interp_fd, &interp_ehdr, ph->core->ld_base_addr) != true) {
+ print_debug("can't read segments of interpreter\n");
+ return false;
+ }
+
+ return true;
+}
+
+// process segments of a a.out
+static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
+ int i = 0;
+ ELF_PHDR* phbuf = NULL;
+ ELF_PHDR* exec_php = NULL;
+
+ if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL)
+ return false;
+
+ for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
+ switch (exec_php->p_type) {
+
+ // add mappings for PT_LOAD segments
+ case PT_LOAD: {
+ // add only non-writable segments of non-zero filesz
+ if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
+ if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
+ }
+ break;
+ }
+
+ // read the interpreter and it's segments
+ case PT_INTERP: {
+ char interp_name[BUF_SIZE];
+
+ pread(ph->core->exec_fd, interp_name, MIN(exec_php->p_filesz, BUF_SIZE), exec_php->p_offset);
+ print_debug("ELF interpreter %s\n", interp_name);
+ // read interpreter segments as well
+ if ((ph->core->interp_fd = pathmap_open(interp_name)) < 0) {
+ print_debug("can't open runtime loader\n");
+ goto err;
+ }
+ break;
+ }
+
+ // from PT_DYNAMIC we want to read address of first link_map addr
+ case PT_DYNAMIC: {
+ ph->core->dynamic_addr = exec_php->p_vaddr;
+ print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr);
+ break;
+ }
+
+ } // switch
+ exec_php++;
+ } // for
+
+ free(phbuf);
+ return true;
+err:
+ free(phbuf);
+ return false;
+}
+
+
+#define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug, r_map)
+#define LD_BASE_OFFSET offsetof(struct r_debug, r_ldbase)
+#define LINK_MAP_ADDR_OFFSET offsetof(struct link_map, l_addr)
+#define LINK_MAP_NAME_OFFSET offsetof(struct link_map, l_name)
+#define LINK_MAP_NEXT_OFFSET offsetof(struct link_map, l_next)
+
+// read shared library info from runtime linker's data structures.
+// This work is done by librtlb_db in Solaris
+static bool read_shared_lib_info(struct ps_prochandle* ph) {
+ uintptr_t addr = ph->core->dynamic_addr;
+ uintptr_t debug_base;
+ uintptr_t first_link_map_addr;
+ uintptr_t ld_base_addr;
+ uintptr_t link_map_addr;
+ uintptr_t lib_base_diff;
+ uintptr_t lib_base;
+ uintptr_t lib_name_addr;
+ char lib_name[BUF_SIZE];
+ ELF_DYN dyn;
+ ELF_EHDR elf_ehdr;
+ int lib_fd;
+
+ // _DYNAMIC has information of the form
+ // [tag] [data] [tag] [data] .....
+ // Both tag and data are pointer sized.
+ // We look for dynamic info with DT_DEBUG. This has shared object info.
+ // refer to struct r_debug in link.h
+
+ dyn.d_tag = DT_NULL;
+ while (dyn.d_tag != DT_DEBUG) {
+ if (ps_pdread(ph, (psaddr_t) addr, &dyn, sizeof(ELF_DYN)) != PS_OK) {
+ print_debug("can't read debug info from _DYNAMIC\n");
+ return false;
+ }
+ addr += sizeof(ELF_DYN);
+ }
+
+ // we have got Dyn entry with DT_DEBUG
+ debug_base = dyn.d_un.d_ptr;
+ // at debug_base we have struct r_debug. This has first link map in r_map field
+ if (ps_pdread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
+ &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
+ print_debug("can't read first link map address\n");
+ return false;
+ }
+
+ // read ld_base address from struct r_debug
+ if (ps_pdread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
+ sizeof(uintptr_t)) != PS_OK) {
+ print_debug("can't read ld base address\n");
+ return false;
+ }
+ ph->core->ld_base_addr = ld_base_addr;
+
+ print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
+
+ // now read segments from interp (i.e ld.so or ld-linux.so)
+ if (read_interp_segments(ph) != true)
+ return false;
+
+ // after adding interpreter (ld.so) mappings sort again
+ if (sort_map_array(ph) != true)
+ return false;
+
+ print_debug("first link map is at 0x%lx\n", first_link_map_addr);
+
+ link_map_addr = first_link_map_addr;
+ while (link_map_addr != 0) {
+ // read library base address of the .so. Note that even though calls
+ // link_map->l_addr as "base address", this is * not * really base virtual
+ // address of the shared object. This is actually the difference b/w the virtual
+ // address mentioned in shared object and the actual virtual base where runtime
+ // linker loaded it. We use "base diff" in read_lib_segments call below.
+
+ if (ps_pdread(ph, (psaddr_t) link_map_addr + LINK_MAP_ADDR_OFFSET,
+ &lib_base_diff, sizeof(uintptr_t)) != PS_OK) {
+ print_debug("can't read shared object base address diff\n");
+ return false;
+ }
+
+ // read address of the name
+ if (ps_pdread(ph, (psaddr_t) link_map_addr + LINK_MAP_NAME_OFFSET,
+ &lib_name_addr, sizeof(uintptr_t)) != PS_OK) {
+ print_debug("can't read address of shared object name\n");
+ return false;
+ }
+
+ // read name of the shared object
+ if (read_string(ph, (uintptr_t) lib_name_addr, lib_name, sizeof(lib_name)) != true) {
+ print_debug("can't read shared object name\n");
+ return false;
+ }
+
+ if (lib_name[0] != '\0') {
+ // ignore empty lib names
+ lib_fd = pathmap_open(lib_name);
+
+ if (lib_fd < 0) {
+ print_debug("can't open shared object %s\n", lib_name);
+ // continue with other libraries...
+ } else {
+ if (read_elf_header(lib_fd, &elf_ehdr)) {
+ lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
+ print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
+ lib_name, lib_base, lib_base_diff);
+ // while adding library mappings we need to use "base difference".
+ if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
+ print_debug("can't read shared object's segments\n");
+ close(lib_fd);
+ return false;
+ }
+ add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
+ // Map info is added for the library (lib_name) so
+ // we need to re-sort it before calling the p_pdread.
+ if (sort_map_array(ph) != true)
+ return false;
+ } else {
+ print_debug("can't read ELF header for shared object %s\n", lib_name);
+ close(lib_fd);
+ // continue with other libraries...
+ }
+ }
+ }
+
+ // read next link_map address
+ if (ps_pdread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
+ &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
+ print_debug("can't read next link in link_map\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// the one and only one exposed stuff from this file
+struct ps_prochandle* Pgrab_core(const char* exec_file, const char* core_file) {
+ ELF_EHDR core_ehdr;
+ ELF_EHDR exec_ehdr;
+ ELF_EHDR lib_ehdr;
+
+ struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
+ if (ph == NULL) {
+ print_debug("can't allocate ps_prochandle\n");
+ return NULL;
+ }
+
+ if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
+ free(ph);
+ print_debug("can't allocate ps_prochandle\n");
+ return NULL;
+ }
+
+ // initialize ph
+ ph->ops = &core_ops;
+ ph->core->core_fd = -1;
+ ph->core->exec_fd = -1;
+ ph->core->interp_fd = -1;
+
+ // open the core file
+ if ((ph->core->core_fd = open(core_file, O_RDONLY)) < 0) {
+ print_debug("can't open core file\n");
+ goto err;
+ }
+
+ // read core file ELF header
+ if (read_elf_header(ph->core->core_fd, &core_ehdr) != true || core_ehdr.e_type != ET_CORE) {
+ print_debug("core file is not a valid ELF ET_CORE file\n");
+ goto err;
+ }
+
+ if ((ph->core->exec_fd = open(exec_file, O_RDONLY)) < 0) {
+ print_debug("can't open executable file\n");
+ goto err;
+ }
+
+ if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
+ print_debug("executable file is not a valid ELF ET_EXEC file\n");
+ goto err;
+ }
+
+ // process core file segments
+ if (read_core_segments(ph, &core_ehdr) != true)
+ goto err;
+
+ // process exec file segments
+ if (read_exec_segments(ph, &exec_ehdr) != true)
+ goto err;
+
+ // exec file is also treated like a shared object for symbol search
+ if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
+ (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
+ goto err;
+
+ // allocate and sort maps into map_array, we need to do this
+ // here because read_shared_lib_info needs to read from debuggee
+ // address space
+ if (sort_map_array(ph) != true)
+ goto err;
+
+ if (read_shared_lib_info(ph) != true)
+ goto err;
+
+ // sort again because we have added more mappings from shared objects
+ if (sort_map_array(ph) != true)
+ goto err;
+
+ if (init_classsharing_workaround(ph) != true)
+ goto err;
+
+ return ph;
+
+err:
+ Prelease(ph);
+ return NULL;
+}
diff --git a/hotspot/agent/src/os/linux/ps_proc.c b/hotspot/agent/src/os/linux/ps_proc.c
new file mode 100644
index 00000000000..81ea1fb7aa0
--- /dev/null
+++ b/hotspot/agent/src/os/linux/ps_proc.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "libproc_impl.h"
+
+#if defined(x86_64) && !defined(amd64)
+#define amd64 1
+#endif
+
+#ifndef __WALL
+#define __WALL 0x40000000 // Copied from /usr/include/linux/wait.h
+#endif
+
+// This file has the libproc implementation specific to live process
+// For core files, refer to ps_core.c
+
+static inline uintptr_t align(uintptr_t ptr, size_t size) {
+ return (ptr & ~(size - 1));
+}
+
+// ---------------------------------------------
+// ptrace functions
+// ---------------------------------------------
+
+// read "size" bytes of data from "addr" within the target process.
+// unlike the standard ptrace() function, process_read_data() can handle
+// unaligned address - alignment check, if required, should be done
+// before calling process_read_data.
+
+static bool process_read_data(struct ps_prochandle* ph, uintptr_t addr, char *buf, size_t size) {
+ long rslt;
+ size_t i, words;
+ uintptr_t end_addr = addr + size;
+ uintptr_t aligned_addr = align(addr, sizeof(long));
+
+ if (aligned_addr != addr) {
+ char *ptr = (char *)&rslt;
+ errno = 0;
+ rslt = ptrace(PTRACE_PEEKDATA, ph->pid, aligned_addr, 0);
+ if (errno) {
+ print_debug("ptrace(PTRACE_PEEKDATA, ..) failed for %d bytes @ %lx\n", size, addr);
+ return false;
+ }
+ for (; aligned_addr != addr; aligned_addr++, ptr++);
+ for (; ((intptr_t)aligned_addr % sizeof(long)) && aligned_addr < end_addr;
+ aligned_addr++)
+ *(buf++) = *(ptr++);
+ }
+
+ words = (end_addr - aligned_addr) / sizeof(long);
+
+ // assert((intptr_t)aligned_addr % sizeof(long) == 0);
+ for (i = 0; i < words; i++) {
+ errno = 0;
+ rslt = ptrace(PTRACE_PEEKDATA, ph->pid, aligned_addr, 0);
+ if (errno) {
+ print_debug("ptrace(PTRACE_PEEKDATA, ..) failed for %d bytes @ %lx\n", size, addr);
+ return false;
+ }
+ *(long *)buf = rslt;
+ buf += sizeof(long);
+ aligned_addr += sizeof(long);
+ }
+
+ if (aligned_addr != end_addr) {
+ char *ptr = (char *)&rslt;
+ errno = 0;
+ rslt = ptrace(PTRACE_PEEKDATA, ph->pid, aligned_addr, 0);
+ if (errno) {
+ print_debug("ptrace(PTRACE_PEEKDATA, ..) failed for %d bytes @ %lx\n", size, addr);
+ return false;
+ }
+ for (; aligned_addr != end_addr; aligned_addr++)
+ *(buf++) = *(ptr++);
+ }
+ return true;
+}
+
+// null implementation for write
+static bool process_write_data(struct ps_prochandle* ph,
+ uintptr_t addr, const char *buf , size_t size) {
+ return false;
+}
+
+// "user" should be a pointer to a user_regs_struct
+static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct user_regs_struct *user) {
+ // we have already attached to all thread 'pid's, just use ptrace call
+ // to get regset now. Note that we don't cache regset upfront for processes.
+// Linux on x86 and sparc are different. On x86 ptrace(PTRACE_GETREGS, ...)
+// uses pointer from 4th argument and ignores 3rd argument. On sparc it uses
+// pointer from 3rd argument and ignores 4th argument
+#if defined(sparc) || defined(sparcv9)
+#define ptrace_getregs(request, pid, addr, data) ptrace(request, pid, addr, data)
+#else
+#define ptrace_getregs(request, pid, addr, data) ptrace(request, pid, data, addr)
+#endif
+
+#ifdef _LP64
+#ifdef PTRACE_GETREGS64
+#define PTRACE_GETREGS_REQ PTRACE_GETREGS64
+#endif
+#else
+#if defined(PTRACE_GETREGS) || defined(PT_GETREGS)
+#define PTRACE_GETREGS_REQ PTRACE_GETREGS
+#endif
+#endif /* _LP64 */
+
+#ifdef PTRACE_GETREGS_REQ
+ if (ptrace_getregs(PTRACE_GETREGS_REQ, pid, user, NULL) < 0) {
+ print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp %d\n", pid);
+ return false;
+ }
+ return true;
+#else
+ print_debug("ptrace(PTRACE_GETREGS, ...) not supported\n");
+ return false;
+#endif
+
+}
+
+// attach to a process/thread specified by "pid"
+static bool ptrace_attach(pid_t pid) {
+ if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
+ print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
+ return false;
+ } else {
+ int ret;
+ int status;
+ do {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret == -1 && errno == ECHILD) {
+ // try cloned process.
+ ret = waitpid(pid, &status, __WALL);
+ }
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Debuggee stopped.
+ return true;
+ } else {
+ print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ print_debug("waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ print_debug("waitpid() failed. Unexpected error %d\n",errno);
+ }
+ return false;
+ }
+ } while(true);
+ }
+}
+
+// -------------------------------------------------------
+// functions for obtaining library information
+// -------------------------------------------------------
+
+/*
+ * splits a string _str_ into substrings with delimiter _delim_ by replacing old * delimiters with _new_delim_ (ideally, '\0'). the address of each substring
+ * is stored in array _ptrs_ as the return value. the maximum capacity of _ptrs_ * array is specified by parameter _n_.
+ * RETURN VALUE: total number of substrings (always <= _n_)
+ * NOTE: string _str_ is modified if _delim_!=_new_delim_
+ */
+static int split_n_str(char * str, int n, char ** ptrs, char delim, char new_delim)
+{
+ int i;
+ for(i = 0; i < n; i++) ptrs[i] = NULL;
+ if (str == NULL || n < 1 ) return 0;
+
+ i = 0;
+
+ // skipping leading blanks
+ while(*str&&*str==delim) str++;
+
+ while(*str&&ipid);
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ print_debug("can't open /proc/%d/maps file\n", ph->pid);
+ return false;
+ }
+
+ while(fgets_no_cr(buf, 256, fp)){
+ char * word[6];
+ int nwords = split_n_str(buf, 6, word, ' ', '\0');
+ if (nwords > 5 && find_lib(ph, word[5]) == false) {
+ intptr_t base;
+ lib_info* lib;
+ sscanf(word[0], "%lx", &base);
+ if ((lib = add_lib_info(ph, word[5], (uintptr_t)base)) == NULL)
+ continue; // ignore, add_lib_info prints error
+
+ // we don't need to keep the library open, symtab is already
+ // built. Only for core dump we need to keep the fd open.
+ close(lib->fd);
+ lib->fd = -1;
+ }
+ }
+ fclose(fp);
+ return true;
+}
+
+// detach a given pid
+static bool ptrace_detach(pid_t pid) {
+ if (pid && ptrace(PTRACE_DETACH, pid, NULL, NULL) < 0) {
+ print_debug("ptrace(PTRACE_DETACH, ..) failed for %d\n", pid);
+ return false;
+ } else {
+ return true;
+ }
+}
+
+// detach all pids of a ps_prochandle
+static void detach_all_pids(struct ps_prochandle* ph) {
+ thread_info* thr = ph->threads;
+ while (thr) {
+ ptrace_detach(thr->lwp_id);
+ thr = thr->next;
+ }
+}
+
+static void process_cleanup(struct ps_prochandle* ph) {
+ detach_all_pids(ph);
+}
+
+static ps_prochandle_ops process_ops = {
+ release: process_cleanup,
+ p_pread: process_read_data,
+ p_pwrite: process_write_data,
+ get_lwp_regs: process_get_lwp_regs
+};
+
+// attach to the process. One and only one exposed stuff
+struct ps_prochandle* Pgrab(pid_t pid) {
+ struct ps_prochandle* ph = NULL;
+ thread_info* thr = NULL;
+
+ if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
+ print_debug("can't allocate memory for ps_prochandle\n");
+ return NULL;
+ }
+
+ if (ptrace_attach(pid) != true) {
+ free(ph);
+ return NULL;
+ }
+
+ // initialize ps_prochandle
+ ph->pid = pid;
+
+ // initialize vtable
+ ph->ops = &process_ops;
+
+ // read library info and symbol tables, must do this before attaching threads,
+ // as the symbols in the pthread library will be used to figure out
+ // the list of threads within the same process.
+ read_lib_info(ph);
+
+ // read thread info
+ read_thread_info(ph, add_new_thread);
+
+ // attach to the threads
+ thr = ph->threads;
+ while (thr) {
+ // don't attach to the main thread again
+ if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id) != true) {
+ // even if one attach fails, we get return NULL
+ Prelease(ph);
+ return NULL;
+ }
+ thr = thr->next;
+ }
+ return ph;
+}
diff --git a/hotspot/agent/src/os/linux/salibelf.c b/hotspot/agent/src/os/linux/salibelf.c
new file mode 100644
index 00000000000..bcc7092094e
--- /dev/null
+++ b/hotspot/agent/src/os/linux/salibelf.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "salibelf.h"
+#include
+#include
+
+extern void print_debug(const char*,...);
+
+// ELF file parsing helpers. Note that we do *not* use libelf here.
+int read_elf_header(int fd, ELF_EHDR* ehdr) {
+ if (pread(fd, ehdr, sizeof (ELF_EHDR), 0) != sizeof (ELF_EHDR) ||
+ memcmp(&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 ||
+ ehdr->e_version != EV_CURRENT) {
+ return 0;
+ }
+ return 1;
+}
+
+bool is_elf_file(int fd) {
+ ELF_EHDR ehdr;
+ return read_elf_header(fd, &ehdr);
+}
+
+// read program header table of an ELF file
+ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr) {
+ ELF_PHDR* phbuf = 0;
+ // allocate memory for program header table
+ size_t nbytes = hdr->e_phnum * hdr->e_phentsize;
+
+ if ((phbuf = (ELF_PHDR*) malloc(nbytes)) == NULL) {
+ print_debug("can't allocate memory for reading program header table\n");
+ return NULL;
+ }
+
+ if (pread(fd, phbuf, nbytes, hdr->e_phoff) != nbytes) {
+ print_debug("ELF file is truncated! can't read program header table\n");
+ free(phbuf);
+ return NULL;
+ }
+
+ return phbuf;
+}
+
+// read section header table of an ELF file
+ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr) {
+ ELF_SHDR* shbuf = 0;
+ // allocate memory for section header table
+ size_t nbytes = hdr->e_shnum * hdr->e_shentsize;
+
+ if ((shbuf = (ELF_SHDR*) malloc(nbytes)) == NULL) {
+ print_debug("can't allocate memory for reading section header table\n");
+ return NULL;
+ }
+
+ if (pread(fd, shbuf, nbytes, hdr->e_shoff) != nbytes) {
+ print_debug("ELF file is truncated! can't read section header table\n");
+ free(shbuf);
+ return NULL;
+ }
+
+ return shbuf;
+}
+
+// read a particular section's data
+void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr) {
+ void *buf = NULL;
+ if (shdr->sh_type == SHT_NOBITS || shdr->sh_size == 0) {
+ return buf;
+ }
+ if ((buf = calloc(shdr->sh_size, 1)) == NULL) {
+ print_debug("can't allocate memory for reading section data\n");
+ return NULL;
+ }
+ if (pread(fd, buf, shdr->sh_size, shdr->sh_offset) != shdr->sh_size) {
+ free(buf);
+ print_debug("section data read failed\n");
+ return NULL;
+ }
+ return buf;
+}
+
+uintptr_t find_base_address(int fd, ELF_EHDR* ehdr) {
+ uintptr_t baseaddr = (uintptr_t)-1;
+ int cnt;
+ ELF_PHDR *phbuf, *phdr;
+
+ // read program header table
+ if ((phbuf = read_program_header_table(fd, ehdr)) == NULL) {
+ goto quit;
+ }
+
+ // the base address of a shared object is the lowest vaddr of
+ // its loadable segments (PT_LOAD)
+ for (phdr = phbuf, cnt = 0; cnt < ehdr->e_phnum; cnt++, phdr++) {
+ if (phdr->p_type == PT_LOAD && phdr->p_vaddr < baseaddr) {
+ baseaddr = phdr->p_vaddr;
+ }
+ }
+
+quit:
+ if (phbuf) free(phbuf);
+ return baseaddr;
+}
diff --git a/hotspot/agent/src/os/linux/salibelf.h b/hotspot/agent/src/os/linux/salibelf.h
new file mode 100644
index 00000000000..4f688195912
--- /dev/null
+++ b/hotspot/agent/src/os/linux/salibelf.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _SALIBELF_H_
+#define _SALIBELF_H_
+
+#include
+#include "elfmacros.h"
+#include "libproc_impl.h"
+
+// read ELF file header.
+int read_elf_header(int fd, ELF_EHDR* ehdr);
+
+// is given file descriptor corresponds to an ELF file?
+bool is_elf_file(int fd);
+
+// read program header table of an ELF file. caller has to
+// free the result pointer after use. NULL on failure.
+ELF_PHDR* read_program_header_table(int fd, ELF_EHDR* hdr);
+
+// read section header table of an ELF file. caller has to
+// free the result pointer after use. NULL on failure.
+ELF_SHDR* read_section_header_table(int fd, ELF_EHDR* hdr);
+
+// read a particular section's data. caller has to free the
+// result pointer after use. NULL on failure.
+void* read_section_data(int fd, ELF_EHDR* ehdr, ELF_SHDR* shdr);
+
+// find the base address at which the library wants to load itself
+uintptr_t find_base_address(int fd, ELF_EHDR* ehdr);
+#endif /* _SALIBELF_H_ */
diff --git a/hotspot/agent/src/os/linux/symtab.c b/hotspot/agent/src/os/linux/symtab.c
new file mode 100644
index 00000000000..ec3b99ff326
--- /dev/null
+++ b/hotspot/agent/src/os/linux/symtab.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "symtab.h"
+#include "salibelf.h"
+
+
+// ----------------------------------------------------
+// functions for symbol lookups
+// ----------------------------------------------------
+
+struct elf_section {
+ ELF_SHDR *c_shdr;
+ void *c_data;
+};
+
+struct elf_symbol {
+ char *name;
+ uintptr_t offset;
+ uintptr_t size;
+};
+
+typedef struct symtab {
+ char *strs;
+ size_t num_symbols;
+ struct elf_symbol *symbols;
+ struct hsearch_data *hash_table;
+} symtab_t;
+
+// read symbol table from given fd.
+struct symtab* build_symtab(int fd) {
+ ELF_EHDR ehdr;
+ char *names = NULL;
+ struct symtab* symtab = NULL;
+
+ // Reading of elf header
+ struct elf_section *scn_cache = NULL;
+ int cnt = 0;
+ ELF_SHDR* shbuf = NULL;
+ ELF_SHDR* cursct = NULL;
+ ELF_PHDR* phbuf = NULL;
+ ELF_PHDR* phdr = NULL;
+
+ uintptr_t baseaddr = (uintptr_t)-1;
+
+ lseek(fd, (off_t)0L, SEEK_SET);
+ if (! read_elf_header(fd, &ehdr)) {
+ // not an elf
+ return NULL;
+ }
+
+ // read ELF header
+ if ((shbuf = read_section_header_table(fd, &ehdr)) == NULL) {
+ goto quit;
+ }
+
+ baseaddr = find_base_address(fd, &ehdr);
+
+ scn_cache = (struct elf_section *)
+ calloc(ehdr.e_shnum * sizeof(struct elf_section), 1);
+ if (scn_cache == NULL) {
+ goto quit;
+ }
+
+ for (cursct = shbuf, cnt = 0; cnt < ehdr.e_shnum; cnt++) {
+ scn_cache[cnt].c_shdr = cursct;
+ if (cursct->sh_type == SHT_SYMTAB || cursct->sh_type == SHT_STRTAB) {
+ if ( (scn_cache[cnt].c_data = read_section_data(fd, &ehdr, cursct)) == NULL) {
+ goto quit;
+ }
+ }
+ cursct++;
+ }
+
+ for (cnt = 1; cnt < ehdr.e_shnum; cnt++) {
+ ELF_SHDR *shdr = scn_cache[cnt].c_shdr;
+
+ if (shdr->sh_type == SHT_SYMTAB) {
+ ELF_SYM *syms;
+ int j, n, rslt;
+ size_t size;
+
+ // FIXME: there could be multiple data buffers associated with the
+ // same ELF section. Here we can handle only one buffer. See man page
+ // for elf_getdata on Solaris.
+
+ // guarantee(symtab == NULL, "multiple symtab");
+ symtab = (struct symtab*)calloc(1, sizeof(struct symtab));
+ if (symtab == NULL) {
+ goto quit;
+ }
+ // the symbol table
+ syms = (ELF_SYM *)scn_cache[cnt].c_data;
+
+ // number of symbols
+ n = shdr->sh_size / shdr->sh_entsize;
+
+ // create hash table, we use hcreate_r, hsearch_r and hdestroy_r to
+ // manipulate the hash table.
+ symtab->hash_table = (struct hsearch_data*) calloc(1, sizeof(struct hsearch_data));
+ rslt = hcreate_r(n, symtab->hash_table);
+ // guarantee(rslt, "unexpected failure: hcreate_r");
+
+ // shdr->sh_link points to the section that contains the actual strings
+ // for symbol names. the st_name field in ELF_SYM is just the
+ // string table index. we make a copy of the string table so the
+ // strings will not be destroyed by elf_end.
+ size = scn_cache[shdr->sh_link].c_shdr->sh_size;
+ symtab->strs = (char *)malloc(size);
+ memcpy(symtab->strs, scn_cache[shdr->sh_link].c_data, size);
+
+ // allocate memory for storing symbol offset and size;
+ symtab->num_symbols = n;
+ symtab->symbols = (struct elf_symbol *)calloc(n , sizeof(struct elf_symbol));
+
+ // copy symbols info our symtab and enter them info the hash table
+ for (j = 0; j < n; j++, syms++) {
+ ENTRY item, *ret;
+ char *sym_name = symtab->strs + syms->st_name;
+
+ // skip non-object and non-function symbols
+ int st_type = ELF_ST_TYPE(syms->st_info);
+ if ( st_type != STT_FUNC && st_type != STT_OBJECT)
+ continue;
+ // skip empty strings and undefined symbols
+ if (*sym_name == '\0' || syms->st_shndx == SHN_UNDEF) continue;
+
+ symtab->symbols[j].name = sym_name;
+ symtab->symbols[j].offset = syms->st_value - baseaddr;
+ symtab->symbols[j].size = syms->st_size;
+
+ item.key = sym_name;
+ item.data = (void *)&(symtab->symbols[j]);
+
+ hsearch_r(item, ENTER, &ret, symtab->hash_table);
+ }
+ }
+ }
+
+quit:
+ if (shbuf) free(shbuf);
+ if (phbuf) free(phbuf);
+ if (scn_cache) {
+ for (cnt = 0; cnt < ehdr.e_shnum; cnt++) {
+ if (scn_cache[cnt].c_data != NULL) {
+ free(scn_cache[cnt].c_data);
+ }
+ }
+ free(scn_cache);
+ }
+ return symtab;
+}
+
+void destroy_symtab(struct symtab* symtab) {
+ if (!symtab) return;
+ if (symtab->strs) free(symtab->strs);
+ if (symtab->symbols) free(symtab->symbols);
+ if (symtab->hash_table) {
+ hdestroy_r(symtab->hash_table);
+ free(symtab->hash_table);
+ }
+ free(symtab);
+}
+
+uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
+ const char *sym_name, int *sym_size) {
+ ENTRY item;
+ ENTRY* ret = NULL;
+
+ // library does not have symbol table
+ if (!symtab || !symtab->hash_table)
+ return (uintptr_t)NULL;
+
+ item.key = (char*) strdup(sym_name);
+ hsearch_r(item, FIND, &ret, symtab->hash_table);
+ if (ret) {
+ struct elf_symbol * sym = (struct elf_symbol *)(ret->data);
+ uintptr_t rslt = (uintptr_t) ((char*)base + sym->offset);
+ if (sym_size) *sym_size = sym->size;
+ free(item.key);
+ return rslt;
+ }
+
+quit:
+ free(item.key);
+ return (uintptr_t) NULL;
+}
+
+const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
+ uintptr_t* poffset) {
+ int n = 0;
+ if (!symtab) return NULL;
+ for (; n < symtab->num_symbols; n++) {
+ struct elf_symbol* sym = &(symtab->symbols[n]);
+ if (sym->name != NULL &&
+ offset >= sym->offset && offset < sym->offset + sym->size) {
+ if (poffset) *poffset = (offset - sym->offset);
+ return sym->name;
+ }
+ }
+ return NULL;
+}
diff --git a/hotspot/agent/src/os/linux/symtab.h b/hotspot/agent/src/os/linux/symtab.h
new file mode 100644
index 00000000000..371fc7fb166
--- /dev/null
+++ b/hotspot/agent/src/os/linux/symtab.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _SYMTAB_H_
+#define _SYMTAB_H_
+
+#include
+
+// interface to manage ELF symbol tables
+
+struct symtab;
+
+// build symbol table for a given ELF file descriptor
+struct symtab* build_symtab(int fd);
+
+// destroy the symbol table
+void destroy_symtab(struct symtab* symtab);
+
+// search for symbol in the given symbol table. Adds offset
+// to the base uintptr_t supplied. Returns NULL if not found.
+uintptr_t search_symbol(struct symtab* symtab, uintptr_t base,
+ const char *sym_name, int *sym_size);
+
+// look for nearest symbol for a given offset (not address - base
+// subtraction done by caller
+const char* nearest_symbol(struct symtab* symtab, uintptr_t offset,
+ uintptr_t* poffset);
+
+#endif /*_SYMTAB_H_*/
diff --git a/hotspot/agent/src/os/linux/test.c b/hotspot/agent/src/os/linux/test.c
new file mode 100644
index 00000000000..2327f2fc8ba
--- /dev/null
+++ b/hotspot/agent/src/os/linux/test.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+#include "libproc.h"
+
+int main(int argc, char** argv) {
+ struct ps_prochandle* ph;
+
+ init_libproc(true);
+ switch (argc) {
+ case 2: {
+ // process
+ ph = Pgrab(atoi(argv[1]));
+ break;
+ }
+
+ case 3: {
+ // core
+ ph = Pgrab_core(argv[1], argv[2]);
+ break;
+ }
+
+ default: {
+ printf("usage %s or %s \n");
+ return 1;
+ }
+ }
+
+ if (ph) {
+ Prelease(ph);
+ return 0;
+ } else {
+ printf("can't connect to debuggee\n");
+ return 1;
+ }
+}
diff --git a/hotspot/agent/src/os/solaris/Makefile b/hotspot/agent/src/os/solaris/Makefile
new file mode 100644
index 00000000000..e9ba9c1f093
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/Makefile
@@ -0,0 +1,32 @@
+#
+# Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+all:
+ cd dbx; $(MAKE) all
+ cd proc; $(MAKE) all
+
+clean:
+ cd dbx; $(MAKE) clean
+ cd proc; $(MAKE) clean
diff --git a/hotspot/agent/src/os/solaris/dbx/Makefile b/hotspot/agent/src/os/solaris/dbx/Makefile
new file mode 100644
index 00000000000..3ccda499cd1
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/Makefile
@@ -0,0 +1,91 @@
+#
+# Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+
+# Targets are:
+# 32bit: Build the 32 bit version in ./32bit
+# 64bit: Build the 64 bit version in ./64bit
+# helloWorld: Build the helloWorld test program
+# all: Build all of the above. This is the default.
+#
+# NOTE: This makefile uses IOBuf.cpp, IOBuf.hpp, Buffer.cpp, and
+# Buffer.hpp from the src/os/win32/agent directory.
+
+.PHONY: 32bit 64bit
+
+ARCH_ORIG = $(shell uname -p)
+
+# C++ := /java/devtools/$(ARCH_ORIG)/SUNWspro/SC6.1/bin/CC
+
+C++ := CC
+RM := /usr/bin/rm
+MKDIRS := /usr/bin/mkdir -p
+
+
+WIN32_DIR := ../../win32
+ARCH := $(subst i386,i486,$(ARCH_ORIG))
+# INCLUDES := -I/net/sparcworks.eng/export/set/sparcworks5/dbx_62_intg/dev/src/dbx -I$(WIN32_DIR)
+INCLUDES := -I. -I$(WIN32_DIR)
+CFLAGS_32bit := -xarch=v8
+CFLAGS_64bit := -xarch=v9
+CFLAGS := -PIC -xO3 $(INCLUDES)
+LIBS := -lsocket -lnsl -lrtld_db
+LDFLAGS := -G
+
+ifneq "$(ARCH)" "i486"
+ CFLAGS += $(CFLAGS_$(VERSION))
+ LDFLAGS += $(CFLAGS_$(VERSION))
+endif
+
+# We use IOBuf.hpp, IOBuf.cpp, Buffer.hpp, and Buffer.cpp from the win32 dir.
+vpath %.cpp .:$(WIN32_DIR)
+vpath %.hpp .:$(WIN32_DIR)
+
+OBJS = $(VERSION)/svc_agent_dbx.o $(VERSION)/IOBuf.o $(VERSION)/Buffer.o
+
+
+
+# The default is to make both 32 bit and 64 bit versions.
+all:: 32bit 64bit
+
+32bit 64bit::
+ $(MKDIRS) $@
+ $(MAKE) $@/libsvc_agent_dbx.so helloWorld VERSION=$@
+
+$(VERSION)/IOBuf.o: IOBuf.hpp
+$(VERSION)/Buffer.o: Buffer.hpp
+$(VERSION)/svc_agent_dbx.o: svc_agent_dbx.hpp
+
+$(VERSION)/%.o: %.cpp
+ $(C++) $(CFLAGS) -c $< -o $@
+
+$(VERSION)/libsvc_agent_dbx.so:: $(OBJS)
+ $(C++) $(LDFLAGS) -o $(VERSION)/libsvc_agent_dbx.so $(OBJS) $(LIBS)
+
+# Would be nice to move this into a shared directory
+helloWorld:: helloWorld.cpp
+ $(C++) -g $< -o $@
+
+clean::
+ $(RM) -rf 32bit 64bit *.o helloWorld
diff --git a/hotspot/agent/src/os/solaris/dbx/README b/hotspot/agent/src/os/solaris/dbx/README
new file mode 100644
index 00000000000..e043f7e1642
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/README
@@ -0,0 +1,9 @@
+shell_impl.h
+proc_service_2.h
+
+The above files are captured from the dbx build environment.
+Rather then use a -I that points to stuff in .eng domain that
+may not be accessible in other domains these files are just
+copied here so local builds in other domains will work.
+These files rarely change so the fact that we might have to
+strobe in new ones on rare occasions is no big deal.
diff --git a/hotspot/agent/src/os/solaris/dbx/README-commands.txt b/hotspot/agent/src/os/solaris/dbx/README-commands.txt
new file mode 100644
index 00000000000..4bc22d20d93
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/README-commands.txt
@@ -0,0 +1,82 @@
+This import module uses a largely text-based protocol, except for
+certain bulk data transfer operations. All text is in single-byte
+US-ASCII.
+
+Commands understood:
+
+address_size ::=
+
+ Returns 32 if attached to 32-bit process, 64 if 64-bit.
+
+peek_fail_fast ::=
+
+ Indicates whether "peek" requests should "fail fast"; that is, if
+ any of the addresses in the requested range are unmapped, report
+ the entire range as unmapped. This is substantially faster than
+ the alternative, which is to read the entire range byte-by-byte.
+ However, it should only be used when it is guaranteed by the
+ client application that peeks come from at most one page. The
+ default is that peek_fast_fail is not enabled.
+
+peek ::=
+ B
+ [ []...]...
+
+ NOTE that the binary portion of this message is prefixed by the
+ uppercase US-ASCII letter 'B', allowing easier synchronization by
+ clients. There is no data between the 'B' and the rest of the
+ message.
+
+ May only be called once attached. Reads the address space of the
+ target process starting at the given address (see below for format
+ specifications) and extending the given number of bytes. Whether
+ the read succeeded is indicated by a single byte containing a 1 or
+ 0 (success or failure). If successful, the return result is given
+ in a sequence of ranges. _len_, the length of each range, is
+ indicated by a 32-bit unsigned integer transmitted with big-endian
+ byte ordering (i.e., most significant byte first). _isMapped_
+ indicates whether the range is mapped or unmapped in the target
+ process's address space, and will contain the value 1 or 0 for
+ mapped or unmapped, respectively. If the range is mapped,
+ _isMapped_ is followed by _data_, containing the raw binary data
+ for the range. The sum of all ranges' lengths is guaranteed to be
+ equivalent to the number of bytes requested.
+
+poke B[]... ::=
+
+ NOTE that the binary portion of this message is prefixed by the
+ uppercase US-ASCII letter 'B', allowing easier synchronization by
+ clients. There is no data between the 'B' and the rest of the
+ message.
+
+ Writes the given data to the target process starting at the given
+ address. Returns 1 on success, 0 on failure (i.e., one or more of
+ target addresses were unmapped).
+
+mapped ::=
+
+ Returns 1 if entire address range [address...address + int arg) is
+ mapped in target process's address space, 0 if not
+
+lookup ::=
+
+ First symbol is object name; second is symbol to be looked up.
+ Looks up symbol in target process's symbol table and returns
+ address. Returns NULL (0x0) if symbol is not found.
+
+thr_gregs ::=
+
+ Fetch the "general" (integer) register set for the given thread.
+ Returned as a series of hexidecimal values. NOTE: the meaning of
+ the return value is architecture-dependent. In general it is the
+ contents of the prgregset_t.
+
+exit ::=
+
+ Exits the serviceability agent dbx module, returning control to
+ the dbx prompt.
+
+// Data formats and example values:
+ ::= 0x12345678[9ABCDEF0] /* up to 64-bit hex value */
+ ::= 5 /* up to 32-bit integer number; no leading sign */
+ ::= 1 /* ASCII '0' or '1' */
diff --git a/hotspot/agent/src/os/solaris/dbx/helloWorld.cpp b/hotspot/agent/src/os/solaris/dbx/helloWorld.cpp
new file mode 100644
index 00000000000..e332a7a1e1b
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/helloWorld.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+
+extern "C" {
+ const char* helloWorldString = "Hello, world!";
+ // Do not change these values without changing TestDebugger.java as well
+ // FIXME: should make these jbyte, jshort, etc...
+ volatile int8_t testByte = 132;
+ volatile int16_t testShort = 27890;
+ volatile int32_t testInt = 1020304050;
+ volatile int64_t testLong = 102030405060708090LL;
+ volatile float testFloat = 35.4F;
+ volatile double testDouble = 1.23456789;
+
+ volatile int helloWorldTrigger = 0;
+}
+
+int
+main(int, char**) {
+ while (1) {
+ while (helloWorldTrigger == 0) {
+ }
+
+ fprintf(stderr, "%s\n", helloWorldString);
+ fprintf(stderr, "testByte=%d\n", testByte);
+ fprintf(stderr, "testShort=%d\n", testShort);
+ fprintf(stderr, "testInt=%d\n", testInt);
+ fprintf(stderr, "testLong=%d\n", testLong);
+ fprintf(stderr, "testFloat=%d\n", testFloat);
+ fprintf(stderr, "testDouble=%d\n", testDouble);
+
+ while (helloWorldTrigger != 0) {
+ }
+ }
+}
diff --git a/hotspot/agent/src/os/solaris/dbx/proc_service_2.h b/hotspot/agent/src/os/solaris/dbx/proc_service_2.h
new file mode 100644
index 00000000000..8e370c006f8
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/proc_service_2.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _PROC_SERVICE_2_H
+#define _PROC_SERVICE_2_H
+
+/*
+ * Types, function definitions for the provider of services beyond
+ * proc_service. This interface will be used by import modules like
+ * BAT/prex, NEO debugger etc.
+ */
+
+/*
+ CCR info
+
+ Version history:
+
+ 1.0 - Initial CCR release
+
+ 1.1 - Changes for GLUE/neo.
+ New entry points ps_svnt_generic() and ps_svc_generic()
+ - New entry point ps_getpid()
+
+ Release information for automatic CCR updates:
+ BEGIN RELEASE NOTES: (signifies what gets put into CCR release notes)
+ 1.2 - Changes to support Solaris 2.7
+
+ END RELEASE NOTES: (signifies what gets put into CCR release notes)
+
+ Following is used for CCR version number:
+
+#define CCR_PROC_SERVICE_2_VERSION 1.2
+
+*/
+
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ps_loadobj {
+ int objfd; /* fd of the load object or executable
+ * -1 implies its not available.
+ * This file decriptor is live only during the
+ * particular call to ps_iter_f(). If you
+ * need it beyond that you need to dup() it.
+ */
+ psaddr_t
+ text_base; /* address where text of loadobj was mapped */
+ psaddr_t
+ data_base; /* address where data of loadobj was mapped */
+ const char *objname; /* loadobj name */
+};
+
+typedef int ps_iter_f(const struct ps_prochandle *, const struct ps_loadobj *,
+ void *cd);
+
+/*
+ * Returns the ps_prochandle for the current process under focus. Returns
+ * NULL if there is none.
+ */
+
+const struct ps_prochandle *
+ps_get_prochandle(void);
+
+/*
+ * Returns the ps_prochandle for the current process(allows core files to
+ * be specified) under focus. Returns NULL if there is none.
+ */
+const struct ps_prochandle *
+ps_get_prochandle2(int cores_too);
+
+/*
+ * Returns the pid of the process referred to by the ps_prochandle.
+ *
+ * 0 is returned in case the ps_prochandle is not valid or refers to dead
+ * process.
+ *
+ */
+pid_t
+ps_getpid(const struct ps_prochandle *);
+
+/*
+ * Iteration function that iterates over all load objects *and the
+ * executable*
+ *
+ * If the callback routine returns:
+ * 0 - continue processing link objects
+ * non zero - stop calling the callback function
+ *
+ */
+
+ps_err_e
+ps_loadobj_iter(const struct ps_prochandle *, ps_iter_f *, void *clnt_data);
+
+/*
+ * Address => function name mapping
+ *
+ * Given an address, returns a pointer to the function's
+ * linker name (null terminated).
+ */
+
+ps_err_e
+ps_find_fun_name(const struct ps_prochandle *, psaddr_t addr,
+ const char **name);
+
+/*
+ * Interface to LD_PRELOAD. LD_PRELOAD given library across the
+ * program 'exec'.
+ *
+ */
+
+/*
+ * Append/Prepend the 'lib' (has to be library name as understood by LD_PRELOAD)
+ * to the LD_PRELOAD variable setting to be used by the debugee
+ * Returns a cookie (in id).
+ */
+ps_err_e
+ps_ld_preload_append(const char *lib, int *id);
+ps_err_e
+ps_ld_preload_prepend(const char *lib, int *id);
+
+/*
+ * Remove the library associated with 'id' from the LD_PRELOAD setting.
+ *
+ */
+ps_err_e
+ps_ld_preload_remove(int id);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * The following are C++ only interfaces
+ */
+#ifdef __cplusplus
+
+/*
+ * classes ServiceDbx and ServantDbx and defined in "gp_dbx_svc.h" which is
+ * accessed via CCR
+ */
+extern class ServantDbx *ps_svnt_generic();
+extern class ServiceDbx *ps_svc_generic();
+
+#endif
+
+#endif /* _PROC_SERVICE_2_H */
diff --git a/hotspot/agent/src/os/solaris/dbx/shell_imp.h b/hotspot/agent/src/os/solaris/dbx/shell_imp.h
new file mode 100644
index 00000000000..c6af9eaf1e4
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/shell_imp.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef SHELL_IMP_H
+#define SHELL_IMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+
+/*
+ CCR info
+
+ Vesrion history:
+
+ 1.0 - Initial CCR release
+
+ Release information for automatic CCR updates:
+
+ BEGIN RELEASE NOTES: (signifies what gets put into CCR release notes)
+ 1.1
+ - Entry points for va_list style msgs; new shell_imp_vmsg()
+ and shell_imp_verrmsg()
+ - shell_imp_env_checker() is now shell_imp_var_checker().
+ Also the var_checker callback gets passed interp.
+ 1.2 - interposition framework (used by jdbx)
+ - access to input FILE pointer.
+
+ END RELEASE NOTES: (signifies what gets put into CCR release notes)
+
+Following is used as a CCR version number:
+#define CCR_SHELL_IMP_VERSION 1.1
+*/
+
+#include
+
+#define SHELL_IMP_MAJOR 1
+#define SHELL_IMP_MINOR 2
+#define SHELL_IMP_FLAG_GLOB 0x1
+#define SHELL_IMP_FLAG_ARGQ 0x2
+
+typedef void *shell_imp_interp_t;
+typedef void *shell_imp_command_t;
+typedef int shell_imp_fun_t(shell_imp_interp_t, int, char **, void *);
+
+int
+shell_imp_init(
+ int, /* major version number */
+ int, /* minor version number */
+ shell_imp_interp_t, /* interpreter */
+ int, /* argc */
+ char *[] /* argv */
+);
+
+int
+shell_imp_fini(shell_imp_interp_t);
+
+shell_imp_command_t
+shell_imp_define_command(char *, /* command name e.g. "tnf" */
+ shell_imp_fun_t *, /* callback function */
+ int, /* SHELL_IMP_FLAG_* bit vector */
+ void *, /* client_data Passed as last arg to
+ /* callback function */
+ char * /* help message, e.g. */
+ /* "enable the specified tnf probes" */
+ );
+
+int
+shell_imp_undefine_command(shell_imp_command_t);
+
+int
+shell_imp_var_checker(shell_imp_interp_t,
+ const char *, /* var name */
+ int (*)(shell_imp_interp_t, const char*) /* env checker */
+ );
+
+int
+shell_imp_execute(shell_imp_interp_t, const char *);
+
+const char *
+shell_imp_get_var(shell_imp_interp_t, const char *);
+
+void
+shell_imp_msg(shell_imp_interp_t, const char *, ...);
+
+void
+shell_imp_errmsg(shell_imp_interp_t, const char *, ...);
+
+void
+shell_imp_vmsg(shell_imp_interp_t, const char *, va_list);
+
+void
+shell_imp_verrmsg(shell_imp_interp_t, const char *, va_list);
+
+
+
+/*
+ * Stuff added for 1.2
+ */
+
+struct shell_imp_interposition_info_t {
+ shell_imp_fun_t *
+ new_func;
+ void * new_client_data;
+ shell_imp_fun_t *
+ original_func;
+ void * original_client_data;
+ int original_flags;
+};
+
+typedef int shell_imp_dispatcher_t(shell_imp_interp_t, int, char **,
+ shell_imp_interposition_info_t *);
+
+shell_imp_command_t
+shell_imp_interpose(char *name,
+ shell_imp_fun_t *new_func,
+ int flags,
+ void *client_data,
+ char * description,
+ shell_imp_dispatcher_t *);
+
+int shell_imp_uninterpose(shell_imp_command_t);
+
+int
+shell_imp_dispatch_interposition(shell_imp_interp_t,
+ shell_imp_interposition_info_t *,
+ int argc, char *argv[]);
+
+int
+shell_imp_dispatch_original(shell_imp_interp_t,
+ shell_imp_interposition_info_t *,
+ int argc, char *argv[]);
+
+FILE *
+shell_imp_cur_input(shell_imp_interp_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.cpp b/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.cpp
new file mode 100644
index 00000000000..8f8efde5d24
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.cpp
@@ -0,0 +1,1068 @@
+/*
+ * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// This is the implementation of a very simple dbx import module which
+// handles requests from the VM which come in over a socket. The
+// higher-level Java wrapper for dbx starts the debugger, attaches to
+// the process, imports this command, and runs it. After that, the SA
+// writes commands to this agent via its own private communications
+// channel. The intent is to move away from the text-based front-end
+// completely in the near future (no more calling "debug" by printing
+// text to dbx's stdin).
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include "proc_service_2.h"
+#include "svc_agent_dbx.hpp"
+
+static ServiceabilityAgentDbxModule* module = NULL;
+#define NEEDS_CLEANUP
+
+// Useful for debugging
+#define VERBOSE_DEBUGGING
+
+#ifdef VERBOSE_DEBUGGING
+# define debug_only(x) x
+#else
+# define debug_only(x)
+#endif
+
+// For profiling
+//#define PROFILING
+
+#ifdef PROFILING
+#define PROFILE_COUNT 200
+static Timer scanTimer;
+static Timer workTimer;
+static Timer writeTimer;
+static int numRequests = 0;
+#endif /* PROFILING */
+
+const char* ServiceabilityAgentDbxModule::CMD_ADDRESS_SIZE = "address_size";
+const char* ServiceabilityAgentDbxModule::CMD_PEEK_FAIL_FAST = "peek_fail_fast";
+const char* ServiceabilityAgentDbxModule::CMD_PEEK = "peek";
+const char* ServiceabilityAgentDbxModule::CMD_POKE = "poke";
+const char* ServiceabilityAgentDbxModule::CMD_MAPPED = "mapped";
+const char* ServiceabilityAgentDbxModule::CMD_LOOKUP = "lookup";
+const char* ServiceabilityAgentDbxModule::CMD_THR_GREGS = "thr_gregs";
+const char* ServiceabilityAgentDbxModule::CMD_EXIT = "exit";
+
+// The initialization routines must not have C++ name mangling
+extern "C" {
+
+/** This is the initialization routine called by dbx upon importing of
+ this module. Returns 0 upon successful initialization, -1 upon
+ failure. */
+int shell_imp_init(int major, int minor,
+ shell_imp_interp_t interp, int argc, char *argv[])
+{
+ // Ensure shell interpreter data structure is laid out the way we
+ // expect
+ if (major != SHELL_IMP_MAJOR) {
+ debug_only(fprintf(stderr, "Serviceability agent: unexpected value for SHELL_IMP_MAJOR (got %d, expected %d)\n", major, SHELL_IMP_MAJOR);)
+ return -1;
+ }
+ if (minor < SHELL_IMP_MINOR) {
+ debug_only(fprintf(stderr, "Serviceability agent: unexpected value for SHELL_IMP_MINOR (got %d, expected >= %d)\n", minor, SHELL_IMP_MINOR);)
+ return -1;
+ }
+
+ if (module != NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: module appears to already be initialized (should not happen)\n");)
+ // Already initialized. Should not happen.
+ return -1;
+ }
+
+ module = new ServiceabilityAgentDbxModule(major, minor, interp, argc, argv);
+ if (!module->install()) {
+ debug_only(fprintf(stderr, "Serviceability agent: error installing import module\n");)
+ delete module;
+ module = NULL;
+ return -1;
+ }
+
+ // Installation was successful. Next step will be for the user to
+ // enter the appropriate command on the command line, which will
+ // make the SA's dbx module wait for commands to come in over the
+ // socket.
+ return 0;
+}
+
+/** This is the routine called by dbx upon unloading of this module.
+ Returns 0 upon success, -1 upon failure. */
+int
+shell_imp_fini(shell_imp_interp_t)
+{
+ if (module == NULL) {
+ return -1;
+ }
+
+ bool res = module->uninstall();
+ delete module;
+ module = NULL;
+ if (!res) {
+ return -1;
+ }
+ return 0;
+}
+
+} // extern "C"
+
+/** This is the routine which is called by the dbx shell when the user
+ requests the serviceability agent module to run. This delegates to
+ ServiceabilityAgentDbxModule::run. This routine's signature must
+ match that of shell_imp_fun_t. */
+extern "C" {
+static int
+svc_agent_run(shell_imp_interp_t, int, char **, void *) {
+ if (module == NULL) {
+ return -1;
+ }
+
+ module->run();
+ return 0;
+}
+}
+
+/*
+ * Implementation of ServiceabilityAgentDbxModule class
+ */
+
+// NOTE: we need to forward declare the special "ps_get_prochandle2"
+// function which allows examination of core files as well. It isn't
+// currently in proc_service_2.h. Note also that it has name mangling
+// because it isn't declared extern "C".
+//const struct ps_prochandle *ps_get_prochandle2(int cores_too);
+
+ServiceabilityAgentDbxModule::ServiceabilityAgentDbxModule(int, int, shell_imp_interp_t interp,
+ int argc, char *argv[])
+ :myComm(32768, 131072)
+{
+ _interp = interp;
+ _argc = argc;
+ _argv = argv;
+ _tdb_agent = NULL;
+ peek_fail_fast = false;
+ libThreadName = NULL;
+}
+
+ServiceabilityAgentDbxModule::~ServiceabilityAgentDbxModule() {
+ if (_command != NULL) {
+ uninstall();
+ }
+}
+
+char*
+readCStringFromProcess(psaddr_t addr) {
+ char c;
+ int num = 0;
+ ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
+
+ // Search for null terminator
+ do {
+ if (ps_pread(cur_proc, addr + num, &c, 1) != PS_OK) {
+ return NULL;
+ }
+ ++num;
+ } while (c != 0);
+
+ // Allocate string
+ char* res = new char[num];
+ if (ps_pread(cur_proc, addr, res, num) != PS_OK) {
+ delete[] res;
+ return NULL;
+ }
+ return res;
+}
+
+int
+findLibThreadCB(const rd_loadobj_t* lo, void* data) {
+ ServiceabilityAgentDbxModule* module = (ServiceabilityAgentDbxModule*) data;
+ char* name = readCStringFromProcess(lo->rl_nameaddr);
+ if (strstr(name, "libthread.so") != NULL) {
+ module->libThreadName = name;
+ return 0;
+ } else {
+ delete[] name;
+ return 1;
+ }
+}
+
+bool
+ServiceabilityAgentDbxModule::install() {
+ // NOTE interdependency between here and Java side wrapper
+ // FIXME: casts of string literal to char * to match prototype
+ _command = shell_imp_define_command((char *) "svc_agent_run",
+ &svc_agent_run,
+ 0,
+ NULL,
+ (char *) "Run the serviceability agent's dbx module.\n"
+ "This routine causes the module to listen on a socket for requests.\n"
+ "It does not return until the Java-side code tells it to exit, at\n"
+ "which point control is returned to the dbx shell.");
+ if (_command == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to install svc_agent_run command\n"));
+ return false;
+ }
+
+ // This is fairly painful. Since dbx doesn't currently load
+ // libthread_db with RTLD_GLOBAL, we can't just use RTLD_DEFAULT for
+ // the argument to dlsym. Instead, we have to use rtld_db to search
+ // through the loaded objects in the target process for libthread.so and
+
+ // Try rtld_db
+ if (rd_init(RD_VERSION) != RD_OK) {
+ debug_only(fprintf(stderr, "Serviceability agent: Unable to init rtld_db\n"));
+ return false;
+ }
+
+ rd_agent_t* rda = rd_new((struct ps_prochandle*) ps_get_prochandle2(1));
+ if (rda == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: Unable to allocate rtld_db agent\n"));
+ return false;
+ }
+
+ if (rd_loadobj_iter(rda, (rl_iter_f*) findLibThreadCB, this) != RD_OK) {
+ debug_only(fprintf(stderr, "Serviceability agent: Loadobject iteration failed\n"));
+ return false;
+ }
+
+ if (libThreadName == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to find pathname to libthread.so in target process\n"));
+ return false;
+ }
+
+ // Find and open libthread_db.so
+ char* slash = strrchr(libThreadName, '/');
+ if (slash == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: can't parse path to libthread.so \"%s\"\n"));
+ return false;
+ }
+
+ int slashPos = slash - libThreadName;
+ char* buf = new char[slashPos + strlen("libthread_db.so") + 20]; // slop
+ if (buf == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: error allocating libthread_db.so pathname\n"));
+ return false;
+ }
+ strncpy(buf, libThreadName, slashPos + 1);
+
+ // Check dbx's data model; use sparcv9/ subdirectory if 64-bit and
+ // if target process is 32-bit
+ if ((sizeof(void*) == 8) &&
+ (strstr(libThreadName, "sparcv9") == NULL)) {
+ strcpy(buf + slashPos + 1, "sparcv9/");
+ slashPos += strlen("sparcv9/");
+ }
+
+ strcpy(buf + slashPos + 1, "libthread_db.so");
+
+ libThreadDB = dlopen(buf, RTLD_LAZY);
+ void* tmpDB = libThreadDB;
+ if (libThreadDB == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: Warning: unable to find libthread_db.so at \"%s\"\n", buf));
+ // Would like to handle this case as well. Maybe dbx has a better
+ // idea of where libthread_db.so lies. If the problem with dbx
+ // loading libthread_db without RTLD_GLOBAL specified ever gets
+ // fixed, we could run this code all the time.
+ tmpDB = RTLD_DEFAULT;
+ }
+
+ delete[] buf;
+
+ // Initialize access to libthread_db
+ td_init_fn = (td_init_fn_t*) dlsym(tmpDB, "td_init");
+ td_ta_new_fn = (td_ta_new_fn_t*) dlsym(tmpDB, "td_ta_new");
+ td_ta_delete_fn = (td_ta_delete_fn_t*) dlsym(tmpDB, "td_ta_delete");
+ td_ta_map_id2thr_fn = (td_ta_map_id2thr_fn_t*) dlsym(tmpDB, "td_ta_map_id2thr");
+ td_thr_getgregs_fn = (td_thr_getgregs_fn_t*) dlsym(tmpDB, "td_thr_getgregs");
+
+ if (td_init_fn == NULL ||
+ td_ta_new_fn == NULL ||
+ td_ta_delete_fn == NULL ||
+ td_ta_map_id2thr_fn == NULL ||
+ td_thr_getgregs_fn == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to find one or more libthread_db symbols:\n"));
+ debug_only(if (td_init_fn == NULL) fprintf(stderr, " td_init\n"));
+ debug_only(if (td_ta_new_fn == NULL) fprintf(stderr, " td_ta_new\n"));
+ debug_only(if (td_ta_delete_fn == NULL) fprintf(stderr, " td_ta_delete\n"));
+ debug_only(if (td_ta_map_id2thr_fn == NULL) fprintf(stderr, " td_ta_map_id2thr\n"));
+ debug_only(if (td_thr_getgregs_fn == NULL) fprintf(stderr, " td_thr_getgregs\n"));
+ return false;
+ }
+
+ if ((*td_init_fn)() != TD_OK) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to initialize libthread_db\n"));
+ return false;
+ }
+
+ return true;
+}
+
+bool
+ServiceabilityAgentDbxModule::uninstall() {
+ if (_command == NULL) {
+ return false;
+ }
+
+ if (libThreadDB != NULL) {
+ dlclose(libThreadDB);
+ libThreadDB = NULL;
+ }
+
+ int res = shell_imp_undefine_command(_command);
+
+ if (res != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+ServiceabilityAgentDbxModule::run() {
+ // This is where most of the work gets done.
+ // The command processor loop looks like the following:
+ // - create listening socket
+ // - accept a connection (only one for now)
+ // - while that connection is open and the "exit" command has not
+ // been received:
+ // - read command
+ // - if it's the exit command, cleanup and return
+ // - otherwise, process command and write result
+
+ int listening_socket = socket(AF_INET, SOCK_STREAM, 0);
+ if (listening_socket < 0) {
+ return false;
+ }
+
+ // Set the SO_REUSEADDR property on the listening socket. This
+ // prevents problems with calls to bind() to the same port failing
+ // after this process exits. This seems to work on all platforms.
+ int reuse_address = 1;
+ if (setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&reuse_address, sizeof(reuse_address)) < 0) {
+ close(listening_socket);
+ return false;
+ }
+
+ sockaddr_in server_address;
+ // Build the server address. We can bind the listening socket to the
+ // INADDR_ANY internet address.
+ memset((char*)&server_address, 0, sizeof(server_address));
+ server_address.sin_family = AF_INET;
+ server_address.sin_addr.s_addr = (unsigned long)htonl(INADDR_ANY);
+ server_address.sin_port = htons((short)PORT);
+
+ // Bind socket to port
+ if (bind(listening_socket, (sockaddr*) &server_address,
+ sizeof(server_address)) < 0) {
+ close(listening_socket);
+ return false;
+ }
+
+ // Arbitrarily chosen backlog of 5 (shouldn't matter since we expect
+ // at most one connection)
+ if (listen(listening_socket, 5) < 0) {
+ close(listening_socket);
+ return false;
+ }
+
+ // OK, now ready to wait for a data connection. This call to
+ // accept() will block.
+ struct sockaddr_in client_address;
+ int address_len = sizeof(client_address);
+ int client_socket = accept(listening_socket, (sockaddr*) &client_address,
+ &address_len);
+ // Close listening socket regardless of whether accept() succeeded.
+ // (FIXME: this may be annoying, especially during debugging, but I
+ // really feel that robustness and multiple connections should be
+ // handled higher up, e.g., at the Java level -- multiple clients
+ // could conceivably connect to the SA via RMI, and that would be a
+ // more robust solution than implementing multiple connections at
+ // this level)
+ NEEDS_CLEANUP;
+
+ // NOTE: the call to shutdown() usually fails, so don't panic if this happens
+ shutdown(listening_socket, 2);
+
+ if (close(listening_socket) < 0) {
+ debug_only(fprintf(stderr, "Serviceability agent: Error closing listening socket\n"));
+ return false;
+ }
+
+ if (client_socket < 0) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to open client socket\n"));
+ // No more cleanup necessary
+ return false;
+ }
+
+ // Attempt to disable TCP buffering on this socket. We send small
+ // amounts of data back and forth and don't want buffering.
+ int buffer_val = 1;
+ if (setsockopt(client_socket, IPPROTO_IP, TCP_NODELAY, (char *) &buffer_val, sizeof(buffer_val)) < 0) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to set TCP_NODELAY option on client socket\n"));
+ cleanup(client_socket);
+ return false;
+ }
+
+ // OK, we have the data socket through which we will communicate
+ // with the Java side. Wait for commands or until reading or writing
+ // caused an error.
+
+ bool should_continue = true;
+
+ myComm.setSocket(client_socket);
+
+#ifdef PROFILING
+ scanTimer.reset();
+ workTimer.reset();
+ writeTimer.reset();
+#endif
+
+ // Allocate a new thread agent for libthread_db
+ if ((*td_ta_new_fn)((ps_prochandle*) ps_get_prochandle2(1), &_tdb_agent) !=
+ TD_OK) {
+ debug_only(fprintf(stderr, "Serviceability agent: Failed to allocate thread agent\n"));
+ cleanup(client_socket);
+ return false;
+ }
+
+ do {
+ // Decided to use text to communicate between these processes.
+ // Probably will make debugging easier -- could telnet in if
+ // necessary. Will make scanning harder, but probably doesn't
+ // matter.
+
+ // Why not just do what workshop does and parse dbx's console?
+ // Probably could do that, but at least this way we are in control
+ // of the text format on both ends.
+
+ // FIXME: should have some way of synchronizing these commands
+ // between the C and Java sources.
+
+ NEEDS_CLEANUP;
+
+ // Do a blocking read of a line from the socket.
+ char *input_buffer = myComm.readLine();
+ if (input_buffer == NULL) {
+ debug_only(fprintf(stderr, "Serviceability agent: error during read: errno = %d\n", errno));
+ debug_only(perror("Serviceability agent"));
+ // Error occurred during read.
+ // FIXME: should guard against SIGPIPE
+ cleanup(client_socket);
+ return false;
+ }
+
+ // OK, now ready to scan. See README-commands.txt for syntax
+ // descriptions.
+
+ bool res = false;
+ if (!strncmp(input_buffer, CMD_ADDRESS_SIZE, strlen(CMD_ADDRESS_SIZE))) {
+ res = handleAddressSize(input_buffer + strlen(CMD_ADDRESS_SIZE));
+ } else if (!strncmp(input_buffer, CMD_PEEK_FAIL_FAST, strlen(CMD_PEEK_FAIL_FAST))) {
+ res = handlePeekFailFast(input_buffer + strlen(CMD_PEEK_FAIL_FAST));
+ } else if (!strncmp(input_buffer, CMD_PEEK, strlen(CMD_PEEK))) {
+ res = handlePeek(input_buffer + strlen(CMD_PEEK));
+ } else if (!strncmp(input_buffer, CMD_POKE, strlen(CMD_POKE))) {
+ res = handlePoke(input_buffer + strlen(CMD_POKE));
+ } else if (!strncmp(input_buffer, CMD_MAPPED, strlen(CMD_MAPPED))) {
+ res = handleMapped(input_buffer + strlen(CMD_MAPPED));
+ } else if (!strncmp(input_buffer, CMD_LOOKUP, strlen(CMD_LOOKUP))) {
+ res = handleLookup(input_buffer + strlen(CMD_LOOKUP));
+ } else if (!strncmp(input_buffer, CMD_THR_GREGS, strlen(CMD_THR_GREGS))) {
+ res = handleThrGRegs(input_buffer + strlen(CMD_THR_GREGS));
+ } else if (!strncmp(input_buffer, CMD_EXIT, strlen(CMD_EXIT))) {
+ should_continue = false;
+ }
+
+ if (should_continue) {
+ if (!res) {
+ cleanup(client_socket);
+ return false;
+ }
+ }
+
+#ifdef PROFILING
+ if (++numRequests == PROFILE_COUNT) {
+ fprintf(stderr, "%d requests: %d ms scanning, %d ms work, %d ms writing\n",
+ PROFILE_COUNT, scanTimer.total(), workTimer.total(), writeTimer.total());
+ fflush(stderr);
+ scanTimer.reset();
+ workTimer.reset();
+ writeTimer.reset();
+ numRequests = 0;
+ }
+#endif
+
+ } while (should_continue);
+
+ // Successful exit
+ cleanup(client_socket);
+ return true;
+}
+
+void
+ServiceabilityAgentDbxModule::cleanup(int client_socket) {
+ shutdown(client_socket, 2);
+ close(client_socket);
+ if (_tdb_agent != NULL) {
+ (*td_ta_delete_fn)(_tdb_agent);
+ }
+}
+
+bool
+ServiceabilityAgentDbxModule::handleAddressSize(char* data) {
+ int data_model;
+ ps_err_e result = ps_pdmodel((ps_prochandle*) ps_get_prochandle2(1),
+ &data_model);
+ if (result != PS_OK) {
+ myComm.writeString("0");
+ myComm.flush();
+ return false;
+ }
+
+ int val;
+ switch (data_model) {
+ case PR_MODEL_ILP32:
+ val = 32;
+ break;
+ case PR_MODEL_LP64:
+ val = 64;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ if (!myComm.writeInt(val)) {
+ return false;
+ }
+ if (!myComm.writeEOL()) {
+ return false;
+ }
+ return myComm.flush();
+}
+
+bool
+ServiceabilityAgentDbxModule::handlePeekFailFast(char* data) {
+ unsigned int val;
+ if (!scanUnsignedInt(&data, &val)) {
+ return false;
+ }
+ peek_fail_fast = (val ? true : false);
+ return true;
+}
+
+bool
+ServiceabilityAgentDbxModule::handlePeek(char* data) {
+ // Scan hex address, return false if failed
+ psaddr_t addr;
+#ifdef PROFILING
+ scanTimer.start();
+#endif /* PROFILING */
+ if (!scanAddress(&data, &addr)) {
+ return false;
+ }
+ unsigned int num;
+ if (!scanUnsignedInt(&data, &num)) {
+ return false;
+ }
+ if (num == 0) {
+#ifdef PROFILING
+ writeTimer.start();
+#endif /* PROFILING */
+ myComm.writeBinChar('B');
+ myComm.writeBinChar(1);
+ myComm.writeBinUnsignedInt(0);
+ myComm.writeBinChar(0);
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+ return true;
+ }
+#ifdef PROFILING
+ scanTimer.stop();
+ workTimer.start();
+#endif /* PROFILING */
+ char* buf = new char[num];
+ ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
+ ps_err_e result = ps_pread(cur_proc, addr, buf, num);
+ if (result == PS_OK) {
+ // Fast case; entire read succeeded.
+#ifdef PROFILING
+ workTimer.stop();
+ writeTimer.start();
+#endif /* PROFILING */
+ myComm.writeBinChar('B');
+ myComm.writeBinChar(1);
+ myComm.writeBinUnsignedInt(num);
+ myComm.writeBinChar(1);
+ myComm.writeBinBuf(buf, num);
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+ } else {
+#ifdef PROFILING
+ workTimer.stop();
+#endif /* PROFILING */
+
+ if (peek_fail_fast) {
+#ifdef PROFILING
+ writeTimer.start();
+#endif /* PROFILING */
+ // Fail fast
+ myComm.writeBinChar('B');
+ myComm.writeBinChar(1);
+ myComm.writeBinUnsignedInt(num);
+ myComm.writeBinChar(0);
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+ } else {
+ // Slow case: try to read one byte at a time
+ // FIXME: need better way of handling this, a la VirtualQuery
+
+ unsigned int strideLen = 0;
+ int bufIdx = 0;
+ bool lastByteMapped = (ps_pread(cur_proc, addr, buf, 1) == PS_OK ? true : false);
+
+#ifdef PROFILING
+ writeTimer.start();
+#endif /* PROFILING */
+ myComm.writeBinChar('B');
+ myComm.writeBinChar(1);
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+
+ for (int i = 0; i < num; ++i, ++addr) {
+#ifdef PROFILING
+ workTimer.start();
+#endif /* PROFILING */
+ result = ps_pread(cur_proc, addr, &buf[bufIdx], 1);
+#ifdef PROFILING
+ workTimer.stop();
+#endif /* PROFILING */
+ bool tmpMapped = (result == PS_OK ? true : false);
+#ifdef PROFILING
+ writeTimer.start();
+#endif /* PROFILING */
+ if (tmpMapped != lastByteMapped) {
+ // State change. Write the length of the last stride.
+ myComm.writeBinUnsignedInt(strideLen);
+ if (lastByteMapped) {
+ // Stop gathering data. Write the data of the last stride.
+ myComm.writeBinChar(1);
+ myComm.writeBinBuf(buf, strideLen);
+ bufIdx = 0;
+ } else {
+ // Start gathering data to write.
+ myComm.writeBinChar(0);
+ }
+ strideLen = 0;
+ lastByteMapped = tmpMapped;
+ }
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+ if (lastByteMapped) {
+ ++bufIdx;
+ }
+ ++strideLen;
+ }
+
+ // Write last stride (must be at least one byte long by definition)
+#ifdef PROFILING
+ writeTimer.start();
+#endif /* PROFILING */
+ myComm.writeBinUnsignedInt(strideLen);
+ if (lastByteMapped) {
+ myComm.writeBinChar(1);
+ myComm.writeBinBuf(buf, strideLen);
+ } else {
+ myComm.writeBinChar(0);
+ }
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+ }
+ }
+ delete[] buf;
+ myComm.flush();
+ return true;
+}
+
+bool
+ServiceabilityAgentDbxModule::handlePoke(char* data) {
+ // FIXME: not yet implemented
+ NEEDS_CLEANUP;
+ bool res = myComm.writeBoolAsInt(false);
+ myComm.flush();
+ return res;
+}
+
+bool
+ServiceabilityAgentDbxModule::handleMapped(char* data) {
+ // Scan address
+ psaddr_t addr;
+ if (!scanAddress(&data, &addr)) {
+ return false;
+ }
+ unsigned int num;
+ if (!scanUnsignedInt(&data, &num)) {
+ return false;
+ }
+ unsigned char val;
+ ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
+ char* buf = new char[num];
+ if (ps_pread(cur_proc, addr, buf, num) == PS_OK) {
+ myComm.writeBoolAsInt(true);
+ } else {
+ myComm.writeBoolAsInt(false);
+ }
+ delete[] buf;
+ myComm.writeEOL();
+ myComm.flush();
+ return true;
+}
+
+extern "C"
+int loadobj_iterator(const rd_loadobj_t* loadobj, void *) {
+ if (loadobj != NULL) {
+ fprintf(stderr, "loadobj_iterator: visited loadobj \"%p\"\n", (void*) loadobj->rl_nameaddr);
+ return 1;
+ }
+
+ fprintf(stderr, "loadobj_iterator: NULL loadobj\n");
+ return 0;
+}
+
+bool
+ServiceabilityAgentDbxModule::handleLookup(char* data) {
+ // Debugging: iterate over loadobjs
+ /*
+ rd_agent_t* rld_agent = rd_new((ps_prochandle*) ps_get_prochandle2(1));
+ rd_loadobj_iter(rld_agent, &loadobj_iterator, NULL);
+ rd_delete(rld_agent);
+ */
+
+#ifdef PROFILING
+ scanTimer.start();
+#endif /* PROFILING */
+
+ char* object_name = scanSymbol(&data);
+ if (object_name == NULL) {
+ return false;
+ }
+ char* symbol_name = scanSymbol(&data);
+ if (symbol_name == NULL) {
+ delete[] object_name;
+ return false;
+ }
+
+#ifdef PROFILING
+ scanTimer.stop();
+ workTimer.start();
+#endif /* PROFILING */
+
+ ps_sym_t sym;
+ // FIXME: check return values from write routines
+ ps_prochandle* process = (ps_prochandle*) ps_get_prochandle2(1);
+ ps_err_e lookup_res = ps_pglobal_sym(process,
+ object_name, symbol_name, &sym);
+#ifdef PROFILING
+ workTimer.stop();
+ writeTimer.start();
+#endif /* PROFILING */
+
+ delete[] object_name;
+ delete[] symbol_name;
+ if (lookup_res != PS_OK) {
+ // This is too noisy
+ // debug_only(fprintf(stderr, "ServiceabilityAgentDbxModule::handleLookup: error %d\n", lookup_res));
+ myComm.writeString("0x0");
+ } else {
+ myComm.writeAddress((void *)sym.st_value);
+ }
+ myComm.writeEOL();
+ myComm.flush();
+
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+
+ return true;
+}
+
+bool
+ServiceabilityAgentDbxModule::handleThrGRegs(char* data) {
+#ifdef PROFILING
+ scanTimer.start();
+#endif /* PROFILING */
+
+ unsigned int num;
+ // Get the thread ID
+ if (!scanUnsignedInt(&data, &num)) {
+ return false;
+ }
+
+#ifdef PROFILING
+ scanTimer.stop();
+ workTimer.start();
+#endif /* PROFILING */
+
+ // Map tid to thread handle
+ td_thrhandle_t thread_handle;
+ if ((*td_ta_map_id2thr_fn)(_tdb_agent, num, &thread_handle) != TD_OK) {
+ // fprintf(stderr, "Error mapping thread ID %d to thread handle\n", num);
+ return false;
+ }
+
+ // Fetch register set
+ prgregset_t reg_set;
+ memset(reg_set, 0, sizeof(reg_set));
+ td_err_e result = (*td_thr_getgregs_fn)(&thread_handle, reg_set);
+ if ((result != TD_OK) && (result != TD_PARTIALREG)) {
+ // fprintf(stderr, "Error fetching registers for thread handle %d: error = %d\n", num, result);
+ return false;
+ }
+
+#ifdef PROFILING
+ workTimer.stop();
+ writeTimer.start();
+#endif /* PROFILING */
+
+#if (defined(__sparc) || defined(__i386))
+ myComm.writeInt(NPRGREG);
+ myComm.writeSpace();
+ for (int i = 0; i < NPRGREG; i++) {
+ myComm.writeAddress((void *)reg_set[i]);
+ if (i == NPRGREG - 1) {
+ myComm.writeEOL();
+ } else {
+ myComm.writeSpace();
+ }
+ }
+#else
+#error Please port ServiceabilityAgentDbxModule::handleThrGRegs to your current platform
+#endif
+
+ myComm.flush();
+
+#ifdef PROFILING
+ writeTimer.stop();
+#endif /* PROFILING */
+
+ return true;
+}
+
+//
+// Input routines
+//
+
+bool
+ServiceabilityAgentDbxModule::scanAddress(char** data, psaddr_t* addr) {
+ *addr = 0;
+
+ // Skip whitespace
+ while ((**data != 0) && (isspace(**data))) {
+ ++*data;
+ }
+
+ if (**data == 0) {
+ return false;
+ }
+
+ if (strncmp(*data, "0x", 2) != 0) {
+ return false;
+ }
+
+ *data += 2;
+
+ while ((**data != 0) && (!isspace(**data))) {
+ int val;
+ bool res = charToNibble(**data, &val);
+ if (!res) {
+ return false;
+ }
+ *addr <<= 4;
+ *addr |= val;
+ ++*data;
+ }
+
+ return true;
+}
+
+bool
+ServiceabilityAgentDbxModule::scanUnsignedInt(char** data, unsigned int* num) {
+ *num = 0;
+
+ // Skip whitespace
+ while ((**data != 0) && (isspace(**data))) {
+ ++*data;
+ }
+
+ if (**data == 0) {
+ return false;
+ }
+
+ while ((**data != 0) && (!isspace(**data))) {
+ char cur = **data;
+ if ((cur < '0') || (cur > '9')) {
+ return false;
+ }
+ *num *= 10;
+ *num += cur - '0';
+ ++*data;
+ }
+
+ return true;
+}
+
+char*
+ServiceabilityAgentDbxModule::scanSymbol(char** data) {
+ // Skip whitespace
+ while ((**data != 0) && (isspace(**data))) {
+ ++*data;
+ }
+
+ if (**data == 0) {
+ return NULL;
+ }
+
+ // First count length
+ int len = 1; // Null terminator
+ char* tmpData = *data;
+ while ((*tmpData != 0) && (!isspace(*tmpData))) {
+ ++tmpData;
+ ++len;
+ }
+ char* buf = new char[len];
+ strncpy(buf, *data, len - 1);
+ buf[len - 1] = 0;
+ *data += len - 1;
+ return buf;
+}
+
+bool
+ServiceabilityAgentDbxModule::charToNibble(char ascii, int* value) {
+ if (ascii >= '0' && ascii <= '9') {
+ *value = ascii - '0';
+ return true;
+ } else if (ascii >= 'A' && ascii <= 'F') {
+ *value = 10 + ascii - 'A';
+ return true;
+ } else if (ascii >= 'a' && ascii <= 'f') {
+ *value = 10 + ascii - 'a';
+ return true;
+ }
+
+ return false;
+}
+
+
+char*
+ServiceabilityAgentDbxModule::readCStringFromProcess(psaddr_t addr) {
+ char c;
+ int num = 0;
+ ps_prochandle* cur_proc = (ps_prochandle*) ps_get_prochandle2(1);
+
+ // Search for null terminator
+ do {
+ if (ps_pread(cur_proc, addr + num, &c, 1) != PS_OK) {
+ return NULL;
+ }
+ ++num;
+ } while (c != 0);
+
+ // Allocate string
+ char* res = new char[num];
+ if (ps_pread(cur_proc, addr, res, num) != PS_OK) {
+ delete[] res;
+ return NULL;
+ }
+ return res;
+}
+
+
+//--------------------------------------------------------------------------------
+// Class Timer
+//
+
+Timer::Timer() {
+ reset();
+}
+
+Timer::~Timer() {
+}
+
+void
+Timer::start() {
+ gettimeofday(&startTime, NULL);
+}
+
+void
+Timer::stop() {
+ struct timeval endTime;
+ gettimeofday(&endTime, NULL);
+ totalMicroseconds += timevalDiff(&startTime, &endTime);
+ ++counter;
+}
+
+long
+Timer::total() {
+ return (totalMicroseconds / 1000);
+}
+
+long
+Timer::average() {
+ return (long) ((double) total() / (double) counter);
+}
+
+void
+Timer::reset() {
+ totalMicroseconds = 0;
+ counter = 0;
+}
+
+long long
+Timer::timevalDiff(struct timeval* start, struct timeval* end) {
+ long long secs = end->tv_sec - start->tv_sec;
+ secs *= 1000000;
+ long long usecs = end->tv_usec - start->tv_usec;
+ return (secs + usecs);
+}
diff --git a/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.hpp b/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.hpp
new file mode 100644
index 00000000000..1757d90878c
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/dbx/svc_agent_dbx.hpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "shell_imp.h"
+#include "IOBuf.hpp"
+#include
+#include
+
+typedef td_err_e td_init_fn_t();
+typedef td_err_e td_ta_new_fn_t(struct ps_prochandle *, td_thragent_t **);
+typedef td_err_e td_ta_delete_fn_t(td_thragent_t *);
+typedef td_err_e td_ta_map_id2thr_fn_t(const td_thragent_t *, thread_t, td_thrhandle_t *);
+typedef td_err_e td_thr_getgregs_fn_t(const td_thrhandle_t *, prgregset_t);
+
+class ServiceabilityAgentDbxModule {
+public:
+ ServiceabilityAgentDbxModule(int major, int minor,
+ shell_imp_interp_t interp, int argc, char *argv[]);
+ ~ServiceabilityAgentDbxModule();
+
+ bool install();
+ bool uninstall();
+
+ /* This is invoked through the dbx command interpreter. It listens
+ on a socket for commands and does not return until it receives an
+ "exit" command. At that point control is returned to dbx's main
+ loop, at which point if the user sends an exit command to dbx's
+ shell the dbx process will exit. Returns true if completed
+ successfully, false if an error occurred while running (for
+ example, unable to bind listening socket). */
+ bool run();
+
+private:
+
+ // This must be shared between the Java and C layers
+ static const int PORT = 21928;
+
+ // Command handlers
+ bool handleAddressSize(char* data);
+ bool handlePeekFailFast(char* data);
+ bool handlePeek(char* data);
+ bool handlePoke(char* data);
+ bool handleMapped(char* data);
+ bool handleLookup(char* data);
+ bool handleThrGRegs(char* data);
+
+ // Input routines
+
+ // May mutate addr argument even if result is false
+ bool scanAddress(char** data, psaddr_t* addr);
+ // May mutate num argument even if result is false
+ bool scanUnsignedInt(char** data, unsigned int* num);
+ // Returns NULL if error occurred while scanning. Otherwise, returns
+ // newly-allocated character array which must be freed with delete[].
+ char* scanSymbol(char** data);
+ // Helper routine: converts ASCII to 4-bit integer. Returns true if
+ // character is in range, false otherwise.
+ bool charToNibble(char ascii, int* value);
+
+ // Output routines
+
+ // Writes an int with no leading or trailing spaces
+ bool writeInt(int val, int fd);
+ // Writes an address in hex format with no leading or trailing
+ // spaces
+ bool writeAddress(psaddr_t addr, int fd);
+ // Writes a register in hex format with no leading or trailing
+ // spaces (addresses and registers might be of different size)
+ bool writeRegister(prgreg_t reg, int fd);
+ // Writes a space to given file descriptor
+ bool writeSpace(int fd);
+ // Writes carriage return to given file descriptor
+ bool writeCR(int fd);
+ // Writes a bool as [0|1]
+ bool writeBoolAsInt(bool val, int fd);
+ // Helper routine: converts low 4 bits to ASCII [0..9][A..F]
+ char nibbleToChar(unsigned char nibble);
+
+ // Base routine called by most of the above
+ bool writeString(const char* str, int fd);
+
+ // Writes a binary character
+ bool writeBinChar(char val, int fd);
+ // Writes a binary unsigned int in network (big-endian) byte order
+ bool writeBinUnsignedInt(unsigned int val, int fd);
+ // Writes a binary buffer
+ bool writeBinBuf(char* buf, int size, int fd);
+
+ // Routine to flush the socket
+ bool flush(int client_socket);
+
+ void cleanup(int client_socket);
+
+ // The shell interpreter on which we can invoke commands (?)
+ shell_imp_interp_t _interp;
+
+ // The "command line" arguments passed to us by dbx (?)
+ int _argc;
+ char **_argv;
+
+ // The installed command in the dbx shell
+ shell_imp_command_t _command;
+
+ // Access to libthread_db (dlsym'ed to be able to pick up the
+ // version loaded by dbx)
+ td_init_fn_t* td_init_fn;
+ td_ta_new_fn_t* td_ta_new_fn;
+ td_ta_delete_fn_t* td_ta_delete_fn;
+ td_ta_map_id2thr_fn_t* td_ta_map_id2thr_fn;
+ td_thr_getgregs_fn_t* td_thr_getgregs_fn;
+
+ // Our "thread agent" -- access to libthread_db
+ td_thragent_t* _tdb_agent;
+
+ // Path to libthread.so in target process; free with delete[]
+ char* libThreadName;
+
+ // Handle to dlopen'ed libthread_db.so
+ void* libThreadDB;
+
+ // Helper callback for finding libthread_db.so
+ friend int findLibThreadCB(const rd_loadobj_t* lo, void* data);
+
+ // Support for reading C strings out of the target process (so we
+ // can find the correct libthread_db). Returns newly-allocated char*
+ // which must be freed with delete[], or null if the read failed.
+ char* readCStringFromProcess(psaddr_t addr);
+
+ IOBuf myComm;
+
+ // Output buffer support (used by writeString, writeChar, flush)
+ char* output_buffer;
+ int output_buffer_size;
+ int output_buffer_pos;
+
+ // "Fail fast" flag
+ bool peek_fail_fast;
+
+ // Commands
+ static const char* CMD_ADDRESS_SIZE;
+ static const char* CMD_PEEK_FAIL_FAST;
+ static const char* CMD_PEEK;
+ static const char* CMD_POKE;
+ static const char* CMD_MAPPED;
+ static const char* CMD_LOOKUP;
+ static const char* CMD_THR_GREGS;
+ static const char* CMD_EXIT;
+};
+
+// For profiling. Times reported are in milliseconds.
+class Timer {
+public:
+ Timer();
+ ~Timer();
+
+ void start();
+ void stop();
+ long total();
+ long average();
+ void reset();
+
+private:
+ struct timeval startTime;
+ long long totalMicroseconds; // stored internally in microseconds
+ int counter;
+ long long timevalDiff(struct timeval* startTime, struct timeval* endTime);
+};
diff --git a/hotspot/agent/src/os/solaris/proc/Makefile b/hotspot/agent/src/os/solaris/proc/Makefile
new file mode 100644
index 00000000000..e7f80fba988
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/proc/Makefile
@@ -0,0 +1,80 @@
+#
+# Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+# Targets are:
+# sparc: Build the 32 bit sparc version in ./sparc
+# sparcv9: Build the 64 bit sparcv9 version in ./sparcv9
+# i386: Build the 32 bit i386 version in ./i386
+
+.PHONY: sparc sparcv9 i386
+
+ARCH_ORIG = $(shell uname -p)
+
+C++ := CC
+RM := /usr/bin/rm
+MKDIRS := /usr/bin/mkdir -p
+
+CLASSES_DIR = ../../../../build/classes
+
+ifeq "$(ARCH_ORIG)" "i386"
+ ALL_TARGET = i386 $(filter amd64,$(shell isalist))
+else
+ ALL_TARGET = sparc sparcv9
+endif
+
+all:: $(ALL_TARGET)
+
+javahomecheck::
+ @if [ "x$(JAVA_HOME)" = "x" ] ; then \
+ echo You must set the environment variable JAVA_HOME before executing this Makefile ; \
+ exit 1 ; \
+ fi
+
+i386:: javahomecheck
+ $(MKDIRS) $@
+ @javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
+ CC -G -KPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
+ -M mapfile -o $@/libsaproc.so -ldemangle
+
+amd64:: javahomecheck
+ $(MKDIRS) $@
+ @javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
+ CC -G -KPIC -xarch=amd64 -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
+ -M mapfile -o $@/libsaproc.so -ldemangle
+
+sparc:: javahomecheck
+ $(MKDIRS) $@
+ @javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
+ CC -G -KPIC -xarch=v8 -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
+ -M mapfile -o $@/libsaproc.so -ldemangle
+
+sparcv9:: javahomecheck
+ $(MKDIRS) $@
+ @javah -classpath $(CLASSES_DIR) -jni sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal
+ CC -G -KPIC -xarch=v9 -I${JAVA_HOME}/include -I${JAVA_HOME}/include/solaris saproc.cpp \
+ -M mapfile -o $@/libsaproc.so -ldemangle
+
+clean::
+ $(RM) -rf sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h
+ $(RM) -rf sparc sparcv9 i386
diff --git a/hotspot/agent/src/os/solaris/proc/libproc.h b/hotspot/agent/src/os/solaris/proc/libproc.h
new file mode 100644
index 00000000000..53091ef9339
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/proc/libproc.h
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * Interfaces available from the process control library, libproc.
+ *
+ * libproc provides process control functions for the /proc tools
+ * (commands in /usr/proc/bin), /usr/bin/truss, and /usr/bin/gcore.
+ * libproc is a private support library for these commands only.
+ * It is _not_ a public interface, although it might become one
+ * in the fullness of time, when the interfaces settle down.
+ *
+ * In the meantime, be aware that any program linked with libproc in this
+ * release of Solaris is almost guaranteed to break in the next release.
+ *
+ * In short, do not use this header file or libproc for any purpose.
+ */
+
+#ifndef _LIBPROC_H
+#define _LIBPROC_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Opaque structure tag reference to a process control structure.
+ * Clients of libproc cannot look inside the process control structure.
+ * The implementation of struct ps_prochandle can change w/o affecting clients.
+ */
+struct ps_prochandle;
+
+extern int _libproc_debug; /* set non-zero to enable debugging fprintfs */
+
+#if defined(sparc) || defined(__sparc)
+#define R_RVAL1 R_O0 /* register holding a function return value */
+#define R_RVAL2 R_O1 /* 32 more bits for a 64-bit return value */
+#define SYSCALL32 0x91d02008 /* 32-bit syscall (ta 8) instruction */
+#define SYSCALL64 0x91d02040 /* 64-bit syscall (ta 64) instruction */
+typedef uint32_t syscall_t; /* holds a syscall instruction */
+#endif /* sparc */
+
+#if defined(__i386) || defined(__ia64)
+#define R_PC EIP
+#define R_SP UESP
+#define R_RVAL1 EAX /* register holding a function return value */
+#define R_RVAL2 EDX /* 32 more bits for a 64-bit return value */
+#define SYSCALL 0x9a /* syscall (lcall) instruction opcode */
+typedef uchar_t syscall_t[7]; /* holds a syscall instruction */
+#endif /* __i386 || __ia64 */
+
+#define R_RVAL R_RVAL1 /* simple function return value register */
+
+/* maximum sizes of things */
+#define PRMAXSIG (32 * sizeof (sigset_t) / sizeof (uint32_t))
+#define PRMAXFAULT (32 * sizeof (fltset_t) / sizeof (uint32_t))
+#define PRMAXSYS (32 * sizeof (sysset_t) / sizeof (uint32_t))
+
+/* State values returned by Pstate() */
+#define PS_RUN 1 /* process is running */
+#define PS_STOP 2 /* process is stopped */
+#define PS_LOST 3 /* process is lost to control (EAGAIN) */
+#define PS_UNDEAD 4 /* process is terminated (zombie) */
+#define PS_DEAD 5 /* process is terminated (core file) */
+
+/* Flags accepted by Pgrab() */
+#define PGRAB_RETAIN 0x01 /* Retain tracing flags, else clear flags */
+#define PGRAB_FORCE 0x02 /* Open the process w/o O_EXCL */
+#define PGRAB_RDONLY 0x04 /* Open the process or core w/ O_RDONLY */
+#define PGRAB_NOSTOP 0x08 /* Open the process but do not stop it */
+
+/* Error codes from Pcreate() */
+#define C_STRANGE -1 /* Unanticipated error, errno is meaningful */
+#define C_FORK 1 /* Unable to fork */
+#define C_PERM 2 /* No permission (file set-id or unreadable) */
+#define C_NOEXEC 3 /* Cannot find executable file */
+#define C_INTR 4 /* Interrupt received while creating */
+#define C_LP64 5 /* Program is _LP64, self is _ILP32 */
+
+/* Error codes from Pgrab(), Pfgrab_core(), and Pgrab_core() */
+#define G_STRANGE -1 /* Unanticipated error, errno is meaningful */
+#define G_NOPROC 1 /* No such process */
+#define G_NOCORE 2 /* No such core file */
+#define G_NOPROCORCORE 3 /* No such proc or core (for proc_arg_grab) */
+#define G_NOEXEC 4 /* Cannot locate executable file */
+#define G_ZOMB 5 /* Zombie process */
+#define G_PERM 6 /* No permission */
+#define G_BUSY 7 /* Another process has control */
+#define G_SYS 8 /* System process */
+#define G_SELF 9 /* Process is self */
+#define G_INTR 10 /* Interrupt received while grabbing */
+#define G_LP64 11 /* Process is _LP64, self is ILP32 */
+#define G_FORMAT 12 /* File is not an ELF format core file */
+#define G_ELF 13 /* Libelf error, elf_errno() is meaningful */
+#define G_NOTE 14 /* Required PT_NOTE Phdr not present in core */
+
+/* Flags accepted by Prelease */
+#define PRELEASE_CLEAR 0x10 /* Clear all tracing flags */
+#define PRELEASE_RETAIN 0x20 /* Retain final tracing flags */
+#define PRELEASE_HANG 0x40 /* Leave the process stopped */
+#define PRELEASE_KILL 0x80 /* Terminate the process */
+
+typedef struct { /* argument descriptor for system call (Psyscall) */
+ long arg_value; /* value of argument given to system call */
+ void *arg_object; /* pointer to object in controlling process */
+ char arg_type; /* AT_BYVAL, AT_BYREF */
+ char arg_inout; /* AI_INPUT, AI_OUTPUT, AI_INOUT */
+ ushort_t arg_size; /* if AT_BYREF, size of object in bytes */
+} argdes_t;
+
+typedef struct { /* return values from system call (Psyscall) */
+ int sys_errno; /* syscall error number */
+ long sys_rval1; /* primary return value from system call */
+ long sys_rval2; /* second return value from system call */
+} sysret_t;
+
+/* values for type */
+#define AT_BYVAL 1
+#define AT_BYREF 2
+
+/* values for inout */
+#define AI_INPUT 1
+#define AI_OUTPUT 2
+#define AI_INOUT 3
+
+/* maximum number of syscall arguments */
+#define MAXARGS 8
+
+/* maximum size in bytes of a BYREF argument */
+#define MAXARGL (4*1024)
+
+/* Kludges to make things work on Solaris 2.6 */
+#if !defined(_LP64) && !defined(PR_MODEL_UNKNOWN)
+#define PR_MODEL_UNKNOWN 0
+#define PR_MODEL_ILP32 0 /* process data model is ILP32 */
+#define PR_MODEL_LP64 2 /* process data model is LP64 */
+#define PR_MODEL_NATIVE PR_MODEL_ILP32
+#define pr_dmodel pr_filler[0]
+#define STACK_BIAS 0
+#endif
+
+/*
+ * Function prototypes for routines in the process control package.
+ */
+extern struct ps_prochandle *Pcreate(const char *, char *const *,
+ int *, char *, size_t);
+
+extern const char *Pcreate_error(int);
+
+extern struct ps_prochandle *Pgrab(pid_t, int, int *);
+extern struct ps_prochandle *Pgrab_core(const char *, const char *, int, int *);
+extern struct ps_prochandle *Pfgrab_core(int, const char *, int *);
+
+extern const char *Pgrab_error(int);
+
+extern int Preopen(struct ps_prochandle *);
+extern void Prelease(struct ps_prochandle *, int);
+extern void Pfree(struct ps_prochandle *);
+
+extern int Pasfd(struct ps_prochandle *);
+extern int Pctlfd(struct ps_prochandle *);
+extern int Pcreate_agent(struct ps_prochandle *);
+extern void Pdestroy_agent(struct ps_prochandle *);
+extern int Pwait(struct ps_prochandle *, uint_t);
+extern int Pstop(struct ps_prochandle *, uint_t);
+extern int Pstate(struct ps_prochandle *);
+extern const psinfo_t *Ppsinfo(struct ps_prochandle *);
+extern const pstatus_t *Pstatus(struct ps_prochandle *);
+extern int Pcred(struct ps_prochandle *, prcred_t *, int);
+extern int Pgetareg(struct ps_prochandle *, int, prgreg_t *);
+extern int Pputareg(struct ps_prochandle *, int, prgreg_t);
+extern int Psetrun(struct ps_prochandle *, int, int);
+extern ssize_t Pread(struct ps_prochandle *, void *, size_t, uintptr_t);
+extern ssize_t Pread_string(struct ps_prochandle *, char *, size_t, uintptr_t);
+extern ssize_t Pwrite(struct ps_prochandle *, const void *, size_t, uintptr_t);
+extern int Pclearsig(struct ps_prochandle *);
+extern int Pclearfault(struct ps_prochandle *);
+extern int Psetbkpt(struct ps_prochandle *, uintptr_t, ulong_t *);
+extern int Pdelbkpt(struct ps_prochandle *, uintptr_t, ulong_t);
+extern int Pxecbkpt(struct ps_prochandle *, ulong_t);
+extern int Psetflags(struct ps_prochandle *, long);
+extern int Punsetflags(struct ps_prochandle *, long);
+extern int Psignal(struct ps_prochandle *, int, int);
+extern int Pfault(struct ps_prochandle *, int, int);
+extern int Psysentry(struct ps_prochandle *, int, int);
+extern int Psysexit(struct ps_prochandle *, int, int);
+extern void Psetsignal(struct ps_prochandle *, const sigset_t *);
+extern void Psetfault(struct ps_prochandle *, const fltset_t *);
+extern void Psetsysentry(struct ps_prochandle *, const sysset_t *);
+extern void Psetsysexit(struct ps_prochandle *, const sysset_t *);
+extern void Psync(struct ps_prochandle *);
+extern sysret_t Psyscall(struct ps_prochandle *, int, uint_t, argdes_t *);
+extern int Pisprocdir(struct ps_prochandle *, const char *);
+
+/*
+ * Function prototypes for system calls forced on the victim process.
+ */
+extern int pr_open(struct ps_prochandle *, const char *, int, mode_t);
+extern int pr_creat(struct ps_prochandle *, const char *, mode_t);
+extern int pr_close(struct ps_prochandle *, int);
+extern int pr_door_info(struct ps_prochandle *, int, struct door_info *);
+extern void *pr_mmap(struct ps_prochandle *,
+ void *, size_t, int, int, int, off_t);
+extern void *pr_zmap(struct ps_prochandle *,
+ void *, size_t, int, int);
+extern int pr_munmap(struct ps_prochandle *, void *, size_t);
+extern int pr_memcntl(struct ps_prochandle *,
+ caddr_t, size_t, int, caddr_t, int, int);
+extern int pr_sigaction(struct ps_prochandle *,
+ int, const struct sigaction *, struct sigaction *);
+extern int pr_getitimer(struct ps_prochandle *,
+ int, struct itimerval *);
+extern int pr_setitimer(struct ps_prochandle *,
+ int, const struct itimerval *, struct itimerval *);
+extern int pr_ioctl(struct ps_prochandle *, int, int, void *, size_t);
+extern int pr_fcntl(struct ps_prochandle *, int, int, void *);
+extern int pr_stat(struct ps_prochandle *, const char *, struct stat *);
+extern int pr_lstat(struct ps_prochandle *, const char *, struct stat *);
+extern int pr_fstat(struct ps_prochandle *, int, struct stat *);
+extern int pr_statvfs(struct ps_prochandle *, const char *, statvfs_t *);
+extern int pr_fstatvfs(struct ps_prochandle *, int, statvfs_t *);
+extern int pr_getrlimit(struct ps_prochandle *,
+ int, struct rlimit *);
+extern int pr_setrlimit(struct ps_prochandle *,
+ int, const struct rlimit *);
+#if defined(_LARGEFILE64_SOURCE)
+extern int pr_getrlimit64(struct ps_prochandle *,
+ int, struct rlimit64 *);
+extern int pr_setrlimit64(struct ps_prochandle *,
+ int, const struct rlimit64 *);
+#endif /* _LARGEFILE64_SOURCE */
+extern int pr_lwp_exit(struct ps_prochandle *);
+extern int pr_exit(struct ps_prochandle *, int);
+extern int pr_waitid(struct ps_prochandle *,
+ idtype_t, id_t, siginfo_t *, int);
+extern off_t pr_lseek(struct ps_prochandle *, int, off_t, int);
+extern offset_t pr_llseek(struct ps_prochandle *, int, offset_t, int);
+extern int pr_rename(struct ps_prochandle *, const char *, const char *);
+extern int pr_link(struct ps_prochandle *, const char *, const char *);
+extern int pr_unlink(struct ps_prochandle *, const char *);
+extern int pr_getpeername(struct ps_prochandle *,
+ int, struct sockaddr *, socklen_t *);
+extern int pr_getsockname(struct ps_prochandle *,
+ int, struct sockaddr *, socklen_t *);
+
+/*
+ * Function prototypes for accessing per-LWP register information.
+ */
+extern int Plwp_getregs(struct ps_prochandle *, lwpid_t, prgregset_t);
+extern int Plwp_setregs(struct ps_prochandle *, lwpid_t, const prgregset_t);
+
+extern int Plwp_getfpregs(struct ps_prochandle *, lwpid_t, prfpregset_t *);
+extern int Plwp_setfpregs(struct ps_prochandle *, lwpid_t,
+ const prfpregset_t *);
+
+#if defined(sparc) || defined(__sparc)
+
+extern int Plwp_getxregs(struct ps_prochandle *, lwpid_t, prxregset_t *);
+extern int Plwp_setxregs(struct ps_prochandle *, lwpid_t, const prxregset_t *);
+
+#if defined(__sparcv9)
+extern int Plwp_getasrs(struct ps_prochandle *, lwpid_t, asrset_t);
+extern int Plwp_setasrs(struct ps_prochandle *, lwpid_t, const asrset_t);
+#endif /* __sparcv9 */
+
+#endif /* __sparc */
+
+extern int Plwp_getpsinfo(struct ps_prochandle *, lwpid_t, lwpsinfo_t *);
+
+/*
+ * LWP iteration interface.
+ */
+typedef int proc_lwp_f(void *, const lwpstatus_t *);
+extern int Plwp_iter(struct ps_prochandle *, proc_lwp_f *, void *);
+
+/*
+ * Symbol table interfaces.
+ */
+
+/*
+ * Pseudo-names passed to Plookup_by_name() for well-known load objects.
+ * NOTE: It is required that PR_OBJ_EXEC and PR_OBJ_LDSO exactly match
+ * the definitions of PS_OBJ_EXEC and PS_OBJ_LDSO from .
+ */
+#define PR_OBJ_EXEC ((const char *)0) /* search the executable file */
+#define PR_OBJ_LDSO ((const char *)1) /* search ld.so.1 */
+#define PR_OBJ_EVERY ((const char *)-1) /* search every load object */
+
+/*
+ * 'object_name' is the name of a load object obtained from an
+ * iteration over the process's address space mappings (Pmapping_iter),
+ * or an iteration over the process's mapped objects (Pobject_iter),
+ * or else it is one of the special PR_OBJ_* values above.
+ */
+extern int Plookup_by_name(struct ps_prochandle *,
+ const char *, const char *, GElf_Sym *);
+
+extern int Plookup_by_addr(struct ps_prochandle *,
+ uintptr_t, char *, size_t, GElf_Sym *);
+
+typedef int proc_map_f(void *, const prmap_t *, const char *);
+
+extern int Pmapping_iter(struct ps_prochandle *, proc_map_f *, void *);
+extern int Pobject_iter(struct ps_prochandle *, proc_map_f *, void *);
+
+extern const prmap_t *Paddr_to_map(struct ps_prochandle *, uintptr_t);
+extern const prmap_t *Paddr_to_text_map(struct ps_prochandle *, uintptr_t);
+extern const prmap_t *Pname_to_map(struct ps_prochandle *, const char *);
+
+extern char *Pplatform(struct ps_prochandle *, char *, size_t);
+extern int Puname(struct ps_prochandle *, struct utsname *);
+
+extern char *Pexecname(struct ps_prochandle *, char *, size_t);
+extern char *Pobjname(struct ps_prochandle *, uintptr_t, char *, size_t);
+
+extern char *Pgetenv(struct ps_prochandle *, const char *, char *, size_t);
+extern long Pgetauxval(struct ps_prochandle *, int);
+
+/*
+ * Symbol table iteration interface.
+ */
+typedef int proc_sym_f(void *, const GElf_Sym *, const char *);
+
+extern int Psymbol_iter(struct ps_prochandle *,
+ const char *, int, int, proc_sym_f *, void *);
+
+/*
+ * 'which' selects which symbol table and can be one of the following.
+ */
+#define PR_SYMTAB 1
+#define PR_DYNSYM 2
+/*
+ * 'type' selects the symbols of interest by binding and type. It is a bit-
+ * mask of one or more of the following flags, whose order MUST match the
+ * order of STB and STT constants in .
+ */
+#define BIND_LOCAL 0x0001
+#define BIND_GLOBAL 0x0002
+#define BIND_WEAK 0x0004
+#define BIND_ANY (BIND_LOCAL|BIND_GLOBAL|BIND_WEAK)
+#define TYPE_NOTYPE 0x0100
+#define TYPE_OBJECT 0x0200
+#define TYPE_FUNC 0x0400
+#define TYPE_SECTION 0x0800
+#define TYPE_FILE 0x1000
+#define TYPE_ANY (TYPE_NOTYPE|TYPE_OBJECT|TYPE_FUNC|TYPE_SECTION|TYPE_FILE)
+
+/*
+ * This returns the rtld_db agent handle for the process.
+ * The handle will become invalid at the next successful exec() and
+ * must not be used beyond that point (see Preset_maps(), below).
+ */
+extern rd_agent_t *Prd_agent(struct ps_prochandle *);
+
+/*
+ * This should be called when an RD_DLACTIVITY event with the
+ * RD_CONSISTENT state occurs via librtld_db's event mechanism.
+ * This makes libproc's address space mappings and symbol tables current.
+ */
+extern void Pupdate_maps(struct ps_prochandle *);
+
+/*
+ * This must be called after the victim process performs a successful
+ * exec() if any of the symbol table interface functions have been called
+ * prior to that point. This is essential because an exec() invalidates
+ * all previous symbol table and address space mapping information.
+ * It is always safe to call, but if it is called other than after an
+ * exec() by the victim process it just causes unnecessary overhead.
+ *
+ * The rtld_db agent handle obtained from a previous call to Prd_agent() is
+ * made invalid by Preset_maps() and Prd_agent() must be called again to get
+ * the new handle.
+ */
+extern void Preset_maps(struct ps_prochandle *);
+
+/*
+ * Given an address, Ppltdest() determines if this is part of a PLT, and if
+ * so returns the target address of this PLT entry and a flag indicating
+ * whether or not this PLT entry has been bound by the run-time linker.
+ */
+extern uintptr_t Ppltdest(struct ps_prochandle *, uintptr_t, int *);
+
+/*
+ * Stack frame iteration interface.
+ */
+typedef int proc_stack_f(void *, const prgregset_t, uint_t, const long *);
+
+extern int Pstack_iter(struct ps_prochandle *,
+ const prgregset_t, proc_stack_f *, void *);
+
+/*
+ * Compute the full pathname of a named directory without using chdir().
+ * This is useful for dealing with /proc//cwd.
+ */
+extern char *proc_dirname(const char *, char *, size_t);
+
+/*
+ * Remove unprintable characters from psinfo.pr_psargs and replace with
+ * whitespace characters so it is safe for printing.
+ */
+extern void proc_unctrl_psinfo(psinfo_t *);
+
+/*
+ * Utility functions for processing arguments which should be /proc files,
+ * pids, and/or core files. The returned error code can be passed to
+ * Pgrab_error() in order to convert it to an error string.
+ */
+#define PR_ARG_PIDS 0x1 /* Allow pid and /proc file arguments */
+#define PR_ARG_CORES 0x2 /* Allow core file arguments */
+
+#define PR_ARG_ANY (PR_ARG_PIDS | PR_ARG_CORES)
+
+extern struct ps_prochandle *proc_arg_grab(const char *, int, int, int *);
+extern pid_t proc_arg_psinfo(const char *, int, psinfo_t *, int *);
+
+/*
+ * Utility functions for obtaining information via /proc without actually
+ * performing a Pcreate() or Pgrab():
+ */
+extern int proc_get_auxv(pid_t, auxv_t *, int);
+extern int proc_get_cred(pid_t, prcred_t *, int);
+extern int proc_get_psinfo(pid_t, psinfo_t *);
+extern int proc_get_status(pid_t, pstatus_t *);
+
+/*
+ * Utility functions for debugging tools to convert numeric fault,
+ * signal, and system call numbers to symbolic names:
+ */
+extern char *proc_fltname(int, char *, size_t);
+extern char *proc_signame(int, char *, size_t);
+extern char *proc_sysname(int, char *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBPROC_H */
diff --git a/hotspot/agent/src/os/solaris/proc/mapfile b/hotspot/agent/src/os/solaris/proc/mapfile
new file mode 100644
index 00000000000..74701ed11d8
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/proc/mapfile
@@ -0,0 +1,50 @@
+#
+
+#
+# Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+ global:
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0__Ljava_lang_String_2;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_demangle0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_detach0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillCFrameList0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillLoadObjectList0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillThreadList0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getPageSize0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getRemoteProcessAddressSize0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getThreadIntegerRegisterSet0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_initIDs;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByAddress0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByName0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_readBytesFromProcess0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_resume0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_suspend0;
+ Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_writeBytesToProcess0;
+local:
+ *;
+};
diff --git a/hotspot/agent/src/os/solaris/proc/salibproc.h b/hotspot/agent/src/os/solaris/proc/salibproc.h
new file mode 100644
index 00000000000..ba1262926f7
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/proc/salibproc.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+#ifndef _SALIBPROC_H_
+#define _SALIBPROC_H_
+
+/*
+ * The following definitions, prototypes are from Solaris libproc.h.
+ * We used to use the copy of it from Solaris 8.0. But there are
+ * problems with that approach in building this library across Solaris
+ * versions. Solaris 10 has libproc.h in /usr/include. And libproc.h
+ * varies slightly across Solaris versions. On Solaris 9, we get
+ * 'sysret_t multiply defined' error. This is common minimum subset we
+ * really need from libproc.h. The libproc.h in the current dir has
+ * been left for reference and not used in build.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 'object_name' is the name of a load object obtained from an
+ * iteration over the process's address space mappings (Pmapping_iter),
+ * or an iteration over the process's mapped objects (Pobject_iter),
+ * or else it is one of the special PR_OBJ_* values above.
+ */
+
+extern int Plookup_by_addr(struct ps_prochandle *,
+ uintptr_t, char *, size_t, GElf_Sym *);
+
+typedef int proc_map_f(void *, const prmap_t *, const char *);
+extern int Pobject_iter(struct ps_prochandle *, proc_map_f *, void *);
+
+/*
+ * Utility functions for processing arguments which should be /proc files,
+ * pids, and/or core files. The returned error code can be passed to
+ * Pgrab_error() in order to convert it to an error string.
+ */
+#define PR_ARG_PIDS 0x1 /* Allow pid and /proc file arguments */
+#define PR_ARG_CORES 0x2 /* Allow core file arguments */
+#define PR_ARG_ANY (PR_ARG_PIDS | PR_ARG_CORES)
+
+/* Flags accepted by Pgrab() (partial) */
+#define PGRAB_FORCE 0x02 /* Open the process w/o O_EXCL */
+
+/* Error codes from Pgrab(), Pfgrab_core(), and Pgrab_core() */
+#define G_STRANGE -1 /* Unanticipated error, errno is meaningful */
+#define G_NOPROC 1 /* No such process */
+#define G_NOCORE 2 /* No such core file */
+#define G_NOPROCORCORE 3 /* No such proc or core (for proc_arg_grab) */
+#define G_NOEXEC 4 /* Cannot locate executable file */
+#define G_ZOMB 5 /* Zombie process */
+#define G_PERM 6 /* No permission */
+#define G_BUSY 7 /* Another process has control */
+#define G_SYS 8 /* System process */
+#define G_SELF 9 /* Process is self */
+#define G_INTR 10 /* Interrupt received while grabbing */
+#define G_LP64 11 /* Process is _LP64, self is ILP32 */
+#define G_FORMAT 12 /* File is not an ELF format core file */
+#define G_ELF 13 /* Libelf error, elf_errno() is meaningful */
+#define G_NOTE 14 /* Required PT_NOTE Phdr not present in core */
+
+extern struct ps_prochandle *proc_arg_grab(const char *, int, int, int *);
+extern const pstatus_t *Pstatus(struct ps_prochandle *);
+
+/* Flags accepted by Prelease (partial) */
+#define PRELEASE_CLEAR 0x10 /* Clear all tracing flags */
+
+extern void Prelease(struct ps_prochandle *, int);
+extern int Psetrun(struct ps_prochandle *, int, int);
+extern int Pstop(struct ps_prochandle *, uint_t);
+
+/*
+ * Stack frame iteration interface.
+ */
+typedef int proc_stack_f(void *, const prgregset_t, uint_t, const long *);
+extern int Pstack_iter(struct ps_prochandle *,
+ const prgregset_t, proc_stack_f *, void *);
+
+#define PR_OBJ_EVERY ((const char *)-1) /* search every load object */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SALIBPROC_H_ */
diff --git a/hotspot/agent/src/os/solaris/proc/saproc.cpp b/hotspot/agent/src/os/solaris/proc/saproc.cpp
new file mode 100644
index 00000000000..231773c5647
--- /dev/null
+++ b/hotspot/agent/src/os/solaris/proc/saproc.cpp
@@ -0,0 +1,1300 @@
+/*
+ * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "salibproc.h"
+#include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
+#define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}
+#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throwNewDebuggerException(env, str); return value; }
+#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); return;}
+
+#define SYMBOL_BUF_SIZE 256
+#define ERR_MSG_SIZE (PATH_MAX + 256)
+
+// debug mode
+static int _libsaproc_debug = 0;
+
+static void print_debug(const char* format,...) {
+ if (_libsaproc_debug) {
+ va_list alist;
+
+ va_start(alist, format);
+ fputs("libsaproc DEBUG: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+ }
+}
+
+struct Debugger {
+ JNIEnv* env;
+ jobject this_obj;
+};
+
+struct DebuggerWithObject : Debugger {
+ jobject obj;
+};
+
+struct DebuggerWith2Objects : DebuggerWithObject {
+ jobject obj2;
+};
+
+/*
+* Portions of user thread level detail gathering code is from pstack source
+* code. See pstack.c in Solaris 2.8 user commands source code.
+*/
+
+static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {
+ env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
+}
+
+// JNI ids for some fields, methods
+
+// libproc handler pointer
+static jfieldID p_ps_prochandle_ID = 0;
+
+// libthread.so dlopen handle, thread agent ptr and function pointers
+static jfieldID libthread_db_handle_ID = 0;
+static jfieldID p_td_thragent_t_ID = 0;
+static jfieldID p_td_init_ID = 0;
+static jfieldID p_td_ta_new_ID = 0;
+static jfieldID p_td_ta_delete_ID = 0;
+static jfieldID p_td_ta_thr_iter_ID = 0;
+static jfieldID p_td_thr_get_info_ID = 0;
+static jfieldID p_td_ta_map_id2thr_ID = 0;
+static jfieldID p_td_thr_getgregs_ID = 0;
+
+// reg index fields
+static jfieldID pcRegIndex_ID = 0;
+static jfieldID fpRegIndex_ID = 0;
+
+// part of the class sharing workaround
+static jfieldID classes_jsa_fd_ID = 0;
+static jfieldID p_file_map_header_ID = 0;
+
+// method ids
+
+static jmethodID getThreadForThreadId_ID = 0;
+static jmethodID createSenderFrame_ID = 0;
+static jmethodID createLoadObject_ID = 0;
+static jmethodID createClosestSymbol_ID = 0;
+static jmethodID listAdd_ID = 0;
+
+/*
+ * Functions we need from libthread_db
+ */
+typedef td_err_e
+ (*p_td_init_t)(void);
+typedef td_err_e
+ (*p_td_ta_new_t)(void *, td_thragent_t **);
+typedef td_err_e
+ (*p_td_ta_delete_t)(td_thragent_t *);
+typedef td_err_e
+ (*p_td_ta_thr_iter_t)(const td_thragent_t *, td_thr_iter_f *, void *,
+ td_thr_state_e, int, sigset_t *, unsigned);
+typedef td_err_e
+ (*p_td_thr_get_info_t)(const td_thrhandle_t *, td_thrinfo_t *);
+typedef td_err_e
+ (*p_td_ta_map_id2thr_t)(const td_thragent_t *, thread_t, td_thrhandle_t *);
+typedef td_err_e
+ (*p_td_thr_getgregs_t)(const td_thrhandle_t *, prgregset_t);
+
+static void
+clear_libthread_db_ptrs(JNIEnv* env, jobject this_obj) {
+ // release libthread_db agent, if we had created
+ p_td_ta_delete_t p_td_ta_delete = 0;
+ p_td_ta_delete = (p_td_ta_delete_t) env->GetLongField(this_obj, p_td_ta_delete_ID);
+
+ td_thragent_t *p_td_thragent_t = 0;
+ p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID);
+ if (p_td_thragent_t != 0 && p_td_ta_delete != 0) {
+ p_td_ta_delete(p_td_thragent_t);
+ }
+
+ // dlclose libthread_db.so
+ void* libthread_db_handle = (void*) env->GetLongField(this_obj, libthread_db_handle_ID);
+ if (libthread_db_handle != 0) {
+ dlclose(libthread_db_handle);
+ }
+
+ env->SetLongField(this_obj, libthread_db_handle_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_init_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_ta_new_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_ta_delete_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_ta_thr_iter_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_thr_get_info_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_ta_map_id2thr_ID, (jlong)0);
+ env->SetLongField(this_obj, p_td_thr_getgregs_ID, (jlong)0);
+}
+
+
+static void detach_internal(JNIEnv* env, jobject this_obj) {
+ // clear libthread_db stuff
+ clear_libthread_db_ptrs(env, this_obj);
+
+ // release ptr to ps_prochandle
+ jlong p_ps_prochandle;
+ p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ if (p_ps_prochandle != 0L) {
+ Prelease((struct ps_prochandle*) p_ps_prochandle, PRELEASE_CLEAR);
+ }
+
+ // part of the class sharing workaround
+ int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
+ if (classes_jsa_fd != -1) {
+ close(classes_jsa_fd);
+ struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
+ if (pheader != NULL) {
+ free(pheader);
+ }
+ }
+}
+
+// Is it okay to ignore libthread_db failure? Set env var to ignore
+// libthread_db failure. You can still debug, but will miss threads
+// related functionality.
+static bool sa_ignore_threaddb = (getenv("SA_IGNORE_THREADDB") != 0);
+
+#define HANDLE_THREADDB_FAILURE(msg) \
+ if (sa_ignore_threaddb) { \
+ printf("libsaproc WARNING: %s\n", msg); \
+ return; \
+ } else { \
+ THROW_NEW_DEBUGGER_EXCEPTION(msg); \
+ }
+
+#define HANDLE_THREADDB_FAILURE_(msg, ret) \
+ if (sa_ignore_threaddb) { \
+ printf("libsaproc WARNING: %s\n", msg); \
+ return ret; \
+ } else { \
+ THROW_NEW_DEBUGGER_EXCEPTION_(msg, ret); \
+ }
+
+static const char * alt_root = NULL;
+static int alt_root_len = -1;
+
+#define SA_ALTROOT "SA_ALTROOT"
+
+static void init_alt_root() {
+ if (alt_root_len == -1) {
+ alt_root = getenv(SA_ALTROOT);
+ if (alt_root)
+ alt_root_len = strlen(alt_root);
+ else
+ alt_root_len = 0;
+ }
+}
+
+static int find_file_hook(const char * name, int elf_checksum) {
+ init_alt_root();
+
+ if (_libsaproc_debug) {
+ printf("libsaproc DEBUG: find_file_hook %s 0x%x\n", name, elf_checksum);
+ }
+
+ if (alt_root_len > 0) {
+ int fd = -1;
+ char alt_path[PATH_MAX+1];
+
+ strcpy(alt_path, alt_root);
+ strcat(alt_path, name);
+ fd = open(alt_path, O_RDONLY);
+ if (fd >= 0) {
+ if (_libsaproc_debug) {
+ printf("libsaproc DEBUG: find_file_hook substituted %s\n", alt_path);
+ }
+ return fd;
+ }
+
+ if (strrchr(name, '/')) {
+ strcpy(alt_path, alt_root);
+ strcat(alt_path, strrchr(name, '/'));
+ fd = open(alt_path, O_RDONLY);
+ if (fd >= 0) {
+ if (_libsaproc_debug) {
+ printf("libsaproc DEBUG: find_file_hook substituted %s\n", alt_path);
+ }
+ return fd;
+ }
+ }
+ }
+ return -1;
+}
+
+static int pathmap_open(const char* name) {
+ int fd = open(name, O_RDONLY);
+ if (fd < 0) {
+ fd = find_file_hook(name, 0);
+ }
+ return fd;
+}
+
+static void * pathmap_dlopen(const char * name, int mode) {
+ init_alt_root();
+
+ if (_libsaproc_debug) {
+ printf("libsaproc DEBUG: pathmap_dlopen %s\n", name);
+ }
+
+ void * handle = NULL;
+ if (alt_root_len > 0) {
+ char alt_path[PATH_MAX+1];
+ strcpy(alt_path, alt_root);
+ strcat(alt_path, name);
+ handle = dlopen(alt_path, mode);
+ if (_libsaproc_debug && handle) {
+ printf("libsaproc DEBUG: pathmap_dlopen substituted %s\n", alt_path);
+ }
+
+ if (handle == NULL && strrchr(name, '/')) {
+ strcpy(alt_path, alt_root);
+ strcat(alt_path, strrchr(name, '/'));
+ handle = dlopen(alt_path, mode);
+ if (_libsaproc_debug && handle) {
+ printf("libsaproc DEBUG: pathmap_dlopen substituted %s\n", alt_path);
+ }
+ }
+ }
+ if (handle == NULL) {
+ handle = dlopen(name, mode);
+ }
+ if (_libsaproc_debug) {
+ printf("libsaproc DEBUG: pathmap_dlopen %s return 0x%x\n", name, handle);
+ }
+ return handle;
+}
+
+// libproc and libthread_db callback functions
+
+extern "C" {
+
+static int
+init_libthread_db_ptrs(void *cd, const prmap_t *pmp, const char *object_name) {
+ Debugger* dbg = (Debugger*) cd;
+ JNIEnv* env = dbg->env;
+ jobject this_obj = dbg->this_obj;
+ struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);
+
+ char *s1 = 0, *s2 = 0;
+ char libthread_db[PATH_MAX];
+
+ if (strstr(object_name, "/libthread.so.") == NULL)
+ return (0);
+
+ /*
+ * We found a libthread.
+ * dlopen() the matching libthread_db and get the thread agent handle.
+ */
+ if (Pstatus(ph)->pr_dmodel == PR_MODEL_NATIVE) {
+ (void) strcpy(libthread_db, object_name);
+ s1 = (char*) strstr(object_name, ".so.");
+ s2 = (char*) strstr(libthread_db, ".so.");
+ (void) strcpy(s2, "_db");
+ s2 += 3;
+ (void) strcpy(s2, s1);
+ } else {
+#ifdef _LP64
+ /*
+ * The victim process is 32-bit, we are 64-bit.
+ * We have to find the 64-bit version of libthread_db
+ * that matches the victim's 32-bit version of libthread.
+ */
+ (void) strcpy(libthread_db, object_name);
+ s1 = (char*) strstr(object_name, "/libthread.so.");
+ s2 = (char*) strstr(libthread_db, "/libthread.so.");
+ (void) strcpy(s2, "/64");
+ s2 += 3;
+ (void) strcpy(s2, s1);
+ s1 = (char*) strstr(s1, ".so.");
+ s2 = (char*) strstr(s2, ".so.");
+ (void) strcpy(s2, "_db");
+ s2 += 3;
+ (void) strcpy(s2, s1);
+#else
+ return (0);
+#endif /* _LP64 */
+ }
+
+ void* libthread_db_handle = 0;
+ if ((libthread_db_handle = pathmap_dlopen(libthread_db, RTLD_LAZY|RTLD_LOCAL)) == NULL) {
+ char errMsg[PATH_MAX + 256];
+ sprintf(errMsg, "Can't load %s!", libthread_db);
+ HANDLE_THREADDB_FAILURE_(errMsg, 0);
+ }
+ env->SetLongField(this_obj, libthread_db_handle_ID, (jlong)(uintptr_t)libthread_db_handle);
+
+ void* tmpPtr = 0;
+ tmpPtr = dlsym(libthread_db_handle, "td_init");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_init!", 0);
+ }
+ env->SetLongField(this_obj, p_td_init_ID, (jlong)(uintptr_t) tmpPtr);
+
+ tmpPtr =dlsym(libthread_db_handle, "td_ta_new");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_ta_new!", 0);
+ }
+ env->SetLongField(this_obj, p_td_ta_new_ID, (jlong)(uintptr_t) tmpPtr);
+
+ tmpPtr = dlsym(libthread_db_handle, "td_ta_delete");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_ta_delete!", 0);
+ }
+ env->SetLongField(this_obj, p_td_ta_delete_ID, (jlong)(uintptr_t) tmpPtr);
+
+ tmpPtr = dlsym(libthread_db_handle, "td_ta_thr_iter");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_ta_thr_iter!", 0);
+ }
+ env->SetLongField(this_obj, p_td_ta_thr_iter_ID, (jlong)(uintptr_t) tmpPtr);
+
+ tmpPtr = dlsym(libthread_db_handle, "td_thr_get_info");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_thr_get_info!", 0);
+ }
+ env->SetLongField(this_obj, p_td_thr_get_info_ID, (jlong)(uintptr_t) tmpPtr);
+
+ tmpPtr = dlsym(libthread_db_handle, "td_ta_map_id2thr");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_ta_map_id2thr!", 0);
+ }
+ env->SetLongField(this_obj, p_td_ta_map_id2thr_ID, (jlong)(uintptr_t) tmpPtr);
+
+ tmpPtr = dlsym(libthread_db_handle, "td_thr_getgregs");
+ if (tmpPtr == 0) {
+ HANDLE_THREADDB_FAILURE_("dlsym failed on td_thr_getgregs!", 0);
+ }
+ env->SetLongField(this_obj, p_td_thr_getgregs_ID, (jlong)(uintptr_t) tmpPtr);
+
+ return 1;
+}
+
+static int
+fill_thread_list(const td_thrhandle_t *p_td_thragent_t, void* cd) {
+ DebuggerWithObject* dbgo = (DebuggerWithObject*) cd;
+ JNIEnv* env = dbgo->env;
+ jobject this_obj = dbgo->this_obj;
+ jobject list = dbgo->obj;
+
+ td_thrinfo_t thrinfo;
+ p_td_thr_get_info_t p_td_thr_get_info = (p_td_thr_get_info_t) env->GetLongField(this_obj, p_td_thr_get_info_ID);
+
+ if (p_td_thr_get_info(p_td_thragent_t, &thrinfo) != TD_OK)
+ return (0);
+
+ jobject threadProxy = env->CallObjectMethod(this_obj, getThreadForThreadId_ID, (jlong)(uintptr_t) thrinfo.ti_tid);
+ CHECK_EXCEPTION_(1);
+ env->CallBooleanMethod(list, listAdd_ID, threadProxy);
+ CHECK_EXCEPTION_(1);
+ return 0;
+}
+
+static int
+fill_load_object_list(void *cd, const prmap_t* pmp, const char* obj_name) {
+
+ if (obj_name) {
+ DebuggerWithObject* dbgo = (DebuggerWithObject*) cd;
+ JNIEnv* env = dbgo->env;
+ jobject this_obj = dbgo->this_obj;
+ jobject list = dbgo->obj;
+
+ jstring objectName = env->NewStringUTF(obj_name);
+ CHECK_EXCEPTION_(1);
+
+ jlong mapSize = (jlong) pmp->pr_size;
+ jobject sharedObject = env->CallObjectMethod(this_obj, createLoadObject_ID,
+ objectName, mapSize, (jlong)(uintptr_t)pmp->pr_vaddr);
+ CHECK_EXCEPTION_(1);
+ env->CallBooleanMethod(list, listAdd_ID, sharedObject);
+ CHECK_EXCEPTION_(1);
+ }
+
+ return 0;
+}
+
+static int
+fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc, const long *argv) {
+ DebuggerWith2Objects* dbgo2 = (DebuggerWith2Objects*) cd;
+ JNIEnv* env = dbgo2->env;
+ jobject this_obj = dbgo2->this_obj;
+ jobject curFrame = dbgo2->obj2;
+
+ jint pcRegIndex = env->GetIntField(this_obj, pcRegIndex_ID);
+ jint fpRegIndex = env->GetIntField(this_obj, fpRegIndex_ID);
+
+ jlong pc = (jlong) (uintptr_t) regs[pcRegIndex];
+ jlong fp = (jlong) (uintptr_t) regs[fpRegIndex];
+
+ dbgo2->obj2 = env->CallObjectMethod(this_obj, createSenderFrame_ID,
+ curFrame, pc, fp);
+ CHECK_EXCEPTION_(1);
+ if (dbgo2->obj == 0) {
+ dbgo2->obj = dbgo2->obj2;
+ }
+ return 0;
+}
+
+// part of the class sharing workaround
+
+// FIXME: !!HACK ALERT!!
+
+// The format of sharing achive file header is needed to read shared heap
+// file mappings. For now, I am hard coding portion of FileMapHeader here.
+// Refer to filemap.hpp.
+
+// FileMapHeader describes the shared space data in the file to be
+// mapped. This structure gets written to a file. It is not a class, so
+// that the compilers don't add any compiler-private data to it.
+
+// Refer to CompactingPermGenGen::n_regions in compactingPermGenGen.hpp
+const int NUM_SHARED_MAPS = 4;
+
+// Refer to FileMapInfo::_current_version in filemap.hpp
+const int CURRENT_ARCHIVE_VERSION = 1;
+
+struct FileMapHeader {
+ int _magic; // identify file type.
+ int _version; // (from enum, above.)
+ size_t _alignment; // how shared archive should be aligned
+
+
+ struct space_info {
+ int _file_offset; // sizeof(this) rounded to vm page size
+ char* _base; // copy-on-write base address
+ size_t _capacity; // for validity checking
+ size_t _used; // for setting space top on read
+
+ bool _read_only; // read only space?
+ bool _allow_exec; // executable code in space?
+
+ } _space[NUM_SHARED_MAPS]; // was _space[CompactingPermGenGen::n_regions];
+
+ // Ignore the rest of the FileMapHeader. We don't need those fields here.
+};
+
+static bool
+read_int(struct ps_prochandle* ph, psaddr_t addr, int* pvalue) {
+ int i;
+ if (ps_pread(ph, addr, &i, sizeof(i)) == PS_OK) {
+ *pvalue = i;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool
+read_pointer(struct ps_prochandle* ph, psaddr_t addr, uintptr_t* pvalue) {
+ uintptr_t uip;
+ if (ps_pread(ph, addr, &uip, sizeof(uip)) == PS_OK) {
+ *pvalue = uip;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool
+read_string(struct ps_prochandle* ph, psaddr_t addr, char* buf, size_t size) {
+ char ch = ' ';
+ size_t i = 0;
+
+ while (ch != '\0') {
+ if (ps_pread(ph, addr, &ch, sizeof(ch)) != PS_OK)
+ return false;
+
+ if (i < size - 1) {
+ buf[i] = ch;
+ } else { // smaller buffer
+ return false;
+ }
+
+ i++; addr++;
+ }
+
+ buf[i] = '\0';
+ return true;
+}
+
+#define USE_SHARED_SPACES_SYM "UseSharedSpaces"
+// mangled symbol name for Arguments::SharedArchivePath
+#define SHARED_ARCHIVE_PATH_SYM "__1cJArgumentsRSharedArchivePath_"
+
+static int
+init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name) {
+ Debugger* dbg = (Debugger*) cd;
+ JNIEnv* env = dbg->env;
+ jobject this_obj = dbg->this_obj;
+ const char* jvm_name = 0;
+ if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL ||
+ (jvm_name = strstr(obj_name, "libjvm_g.so")) != NULL) {
+ jvm_name = obj_name;
+ } else {
+ return 0;
+ }
+
+ struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);
+
+ // initialize classes[_g].jsa file descriptor field.
+ dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, -1);
+
+ // check whether class sharing is on by reading variable "UseSharedSpaces"
+ psaddr_t useSharedSpacesAddr = 0;
+ ps_pglobal_lookup(ph, jvm_name, USE_SHARED_SPACES_SYM, &useSharedSpacesAddr);
+ if (useSharedSpacesAddr == 0) {
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'UseSharedSpaces' flag\n", 1);
+ }
+
+ // read the value of the flag "UseSharedSpaces"
+ int value = 0;
+ if (read_int(ph, useSharedSpacesAddr, &value) != true) {
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1);
+ } else if (value == 0) {
+ print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
+ return 1;
+ }
+
+ char classes_jsa[PATH_MAX];
+ psaddr_t sharedArchivePathAddrAddr = 0;
+ ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedArchivePathAddrAddr);
+ if (sharedArchivePathAddrAddr == 0) {
+ print_debug("can't find symbol 'Arguments::SharedArchivePath'\n");
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
+ }
+
+ uintptr_t sharedArchivePathAddr = 0;
+ if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
+ print_debug("can't find read pointer 'Arguments::SharedArchivePath'\n");
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
+ }
+
+ if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
+ print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
+ }
+
+ print_debug("looking for %s\n", classes_jsa);
+
+ // open the classes[_g].jsa
+ int fd = pathmap_open(classes_jsa);
+ if (fd < 0) {
+ char errMsg[ERR_MSG_SIZE];
+ sprintf(errMsg, "can't open shared archive file %s", classes_jsa);
+ THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
+ } else {
+ print_debug("opened shared archive file %s\n", classes_jsa);
+ }
+
+ // parse classes[_g].jsa
+ struct FileMapHeader* pheader = (struct FileMapHeader*) malloc(sizeof(struct FileMapHeader));
+ if (pheader == NULL) {
+ close(fd);
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't allocate memory for shared file map header", 1);
+ }
+
+ memset(pheader, 0, sizeof(struct FileMapHeader));
+ // read FileMapHeader
+ size_t n = read(fd, pheader, sizeof(struct FileMapHeader));
+ if (n != sizeof(struct FileMapHeader)) {
+ free(pheader);
+ close(fd);
+ char errMsg[ERR_MSG_SIZE];
+ sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
+ THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
+ }
+
+ // check file magic
+ if (pheader->_magic != 0xf00baba2) {
+ free(pheader);
+ close(fd);
+ char errMsg[ERR_MSG_SIZE];
+ sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0xf00baba2",
+ classes_jsa, pheader->_magic);
+ THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
+ }
+
+ // check version
+ if (pheader->_version != CURRENT_ARCHIVE_VERSION) {
+ free(pheader);
+ close(fd);
+ char errMsg[ERR_MSG_SIZE];
+ sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
+ classes_jsa, pheader->_version, CURRENT_ARCHIVE_VERSION);
+ THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
+ }
+
+ if (_libsaproc_debug) {
+ for (int m = 0; m < NUM_SHARED_MAPS; m++) {
+ print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
+ pheader->_space[m]._file_offset, pheader->_space[m]._base,
+ pheader->_space[m]._used, pheader->_space[m]._read_only);
+ }
+ }
+
+ // FIXME: For now, omitting other checks such as VM version etc.
+
+ // store class archive file fd and map header in debugger object fields
+ dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
+ dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
+ return 1;
+}
+
+} // extern "C"
+
+// error messages for proc_arg_grab failure codes. The messages are
+// modified versions of comments against corresponding #defines in
+// libproc.h.
+static const char* proc_arg_grab_errmsgs[] = {
+ "",
+ /* G_NOPROC */ "No such process",
+ /* G_NOCORE */ "No such core file",
+ /* G_NOPROCORCORE */ "No such process or core",
+ /* G_NOEXEC */ "Cannot locate executable file",
+ /* G_ZOMB */ "Zombie processs",
+ /* G_PERM */ "No permission to attach",
+ /* G_BUSY */ "Another process has already attached",
+ /* G_SYS */ "System process - can not attach",
+ /* G_SELF */ "Process is self - can't debug myself!",
+ /* G_INTR */ "Interrupt received while grabbing",
+ /* G_LP64 */ "debuggee is 64 bit, use java -d64 for debugger",
+ /* G_FORMAT */ "File is not an ELF format core file - corrupted core?",
+ /* G_ELF */ "Libelf error while parsing an ELF file",
+ /* G_NOTE */ "Required PT_NOTE Phdr not present - corrupted core?",
+};
+
+static void attach_internal(JNIEnv* env, jobject this_obj, jstring cmdLine, jboolean isProcess) {
+ jboolean isCopy;
+ int gcode;
+ const char* cmdLine_cstr = env->GetStringUTFChars(cmdLine, &isCopy);
+ CHECK_EXCEPTION;
+
+ // some older versions of libproc.so crash when trying to attach 32 bit
+ // debugger to 64 bit core file. check and throw error.
+#ifndef _LP64
+ atoi(cmdLine_cstr);
+ if (errno) {
+ // core file
+ int core_fd;
+ if ((core_fd = open64(cmdLine_cstr, O_RDONLY)) >= 0) {
+ Elf32_Ehdr e32;
+ if (pread64(core_fd, &e32, sizeof (e32), 0) == sizeof (e32) &&
+ memcmp(&e32.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0 &&
+ e32.e_type == ET_CORE && e32.e_ident[EI_CLASS] == ELFCLASS64) {
+ close(core_fd);
+ THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use java -d64 for debugger");
+ }
+ close(core_fd);
+ }
+ // all other conditions are handled by libproc.so.
+ }
+#endif
+
+ // connect to process/core
+ struct ps_prochandle* ph = proc_arg_grab(cmdLine_cstr, (isProcess? PR_ARG_PIDS : PR_ARG_CORES), PGRAB_FORCE, &gcode);
+ env->ReleaseStringUTFChars(cmdLine, cmdLine_cstr);
+ if (! ph) {
+ if (gcode > 0 && gcode < sizeof(proc_arg_grab_errmsgs)/sizeof(const char*)) {
+ char errMsg[ERR_MSG_SIZE];
+ sprintf(errMsg, "Attach failed : %s", proc_arg_grab_errmsgs[gcode]);
+ THROW_NEW_DEBUGGER_EXCEPTION(errMsg);
+ } else {
+ if (_libsaproc_debug && gcode == G_STRANGE) {
+ perror("libsaproc DEBUG: ");
+ }
+ if (isProcess) {
+ THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to process!");
+ } else {
+ THROW_NEW_DEBUGGER_EXCEPTION("Not able to attach to core file!");
+ }
+ }
+ }
+
+ // even though libproc.so supports 64 bit debugger and 32 bit debuggee, we don't
+ // support such cross-bit-debugging. check for that combination and throw error.
+#ifdef _LP64
+ int data_model;
+ if (ps_pdmodel(ph, &data_model) != PS_OK) {
+ Prelease(ph, PRELEASE_CLEAR);
+ THROW_NEW_DEBUGGER_EXCEPTION("can't determine debuggee data model (ILP32? or LP64?)");
+ }
+ if (data_model == PR_MODEL_ILP32) {
+ Prelease(ph, PRELEASE_CLEAR);
+ THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
+ }
+#endif
+
+ env->SetLongField(this_obj, p_ps_prochandle_ID, (jlong)(uintptr_t)ph);
+
+ Debugger dbg;
+ dbg.env = env;
+ dbg.this_obj = this_obj;
+ jthrowable exception = 0;
+ if (! isProcess) {
+ /*
+ * With class sharing, shared perm. gen heap is allocated in with MAP_SHARED|PROT_READ.
+ * These pages are mapped from the file "classes[_g].jsa". MAP_SHARED pages are not dumped
+ * in Solaris core.To read shared heap pages, we have to read classes[_g].jsa file.
+ */
+ Pobject_iter(ph, init_classsharing_workaround, &dbg);
+ exception = env->ExceptionOccurred();
+ if (exception) {
+ env->ExceptionClear();
+ detach_internal(env, this_obj);
+ env->Throw(exception);
+ return;
+ }
+ }
+
+ /*
+ * Iterate over the process mappings looking
+ * for libthread and then dlopen the appropriate
+ * libthread_db and get function pointers.
+ */
+ Pobject_iter(ph, init_libthread_db_ptrs, &dbg);
+ exception = env->ExceptionOccurred();
+ if (exception) {
+ env->ExceptionClear();
+ if (!sa_ignore_threaddb) {
+ detach_internal(env, this_obj);
+ env->Throw(exception);
+ }
+ return;
+ }
+
+ // init libthread_db and create thread_db agent
+ p_td_init_t p_td_init = (p_td_init_t) env->GetLongField(this_obj, p_td_init_ID);
+ if (p_td_init == 0) {
+ if (!sa_ignore_threaddb) {
+ detach_internal(env, this_obj);
+ }
+ HANDLE_THREADDB_FAILURE("Did not find libthread in target process/core!");
+ }
+
+ if (p_td_init() != TD_OK) {
+ if (!sa_ignore_threaddb) {
+ detach_internal(env, this_obj);
+ }
+ HANDLE_THREADDB_FAILURE("Can't initialize thread_db!");
+ }
+
+ p_td_ta_new_t p_td_ta_new = (p_td_ta_new_t) env->GetLongField(this_obj, p_td_ta_new_ID);
+
+ td_thragent_t *p_td_thragent_t = 0;
+ if (p_td_ta_new(ph, &p_td_thragent_t) != TD_OK) {
+ if (!sa_ignore_threaddb) {
+ detach_internal(env, this_obj);
+ }
+ HANDLE_THREADDB_FAILURE("Can't create thread_db agent!");
+ }
+ env->SetLongField(this_obj, p_td_thragent_t_ID, (jlong)(uintptr_t) p_td_thragent_t);
+
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: attach0
+ * Signature: (Ljava/lang/String;)V
+ * Description: process detach
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0__Ljava_lang_String_2
+ (JNIEnv *env, jobject this_obj, jstring pid) {
+ attach_internal(env, this_obj, pid, JNI_TRUE);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: attach0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ * Description: core file detach
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
+ (JNIEnv *env, jobject this_obj, jstring executable, jstring corefile) {
+ // ignore executable file name, libproc.so can detect a.out name anyway.
+ attach_internal(env, this_obj, corefile, JNI_FALSE);
+}
+
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: detach0
+ * Signature: ()V
+ * Description: process/core file detach
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_detach0
+ (JNIEnv *env, jobject this_obj) {
+ detach_internal(env, this_obj);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: getRemoteProcessAddressSize0
+ * Signature: ()I
+ * Description: get process/core address size
+ */
+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getRemoteProcessAddressSize0
+ (JNIEnv *env, jobject this_obj) {
+ jlong p_ps_prochandle;
+ p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ int data_model = PR_MODEL_ILP32;
+ ps_pdmodel((struct ps_prochandle*) p_ps_prochandle, &data_model);
+ print_debug("debuggee is %d bit\n", data_model == PR_MODEL_ILP32? 32 : 64);
+ return (jint) data_model == PR_MODEL_ILP32? 32 : 64;
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: getPageSize0
+ * Signature: ()I
+ * Description: get process/core page size
+ */
+JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getPageSize0
+ (JNIEnv *env, jobject this_obj) {
+
+/*
+ We are not yet attached to a java process or core file. getPageSize is called from
+ the constructor of ProcDebuggerLocal. The following won't work!
+
+ jlong p_ps_prochandle;
+ p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ CHECK_EXCEPTION_(-1);
+ struct ps_prochandle* prochandle = (struct ps_prochandle*) p_ps_prochandle;
+ return (Pstate(prochandle) == PS_DEAD) ? Pgetauxval(prochandle, AT_PAGESZ)
+ : getpagesize();
+
+ So even though core may have been generated with a different page size settings, for now
+ call getpagesize.
+*/
+
+ return getpagesize();
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: getThreadIntegerRegisterSet0
+ * Signature: (J)[J
+ * Description: get gregset for a given thread specified by thread id
+ */
+JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getThreadIntegerRegisterSet0
+ (JNIEnv *env, jobject this_obj, jlong tid) {
+ // map the thread id to thread handle
+ p_td_ta_map_id2thr_t p_td_ta_map_id2thr = (p_td_ta_map_id2thr_t) env->GetLongField(this_obj, p_td_ta_map_id2thr_ID);
+
+ td_thragent_t* p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID);
+ if (p_td_thragent_t == 0) {
+ return 0;
+ }
+
+ td_thrhandle_t thr_handle;
+ if (p_td_ta_map_id2thr(p_td_thragent_t, (thread_t) tid, &thr_handle) != TD_OK) {
+ THROW_NEW_DEBUGGER_EXCEPTION_("can't map thread id to thread handle!", 0);
+ }
+
+ p_td_thr_getgregs_t p_td_thr_getgregs = (p_td_thr_getgregs_t) env->GetLongField(this_obj, p_td_thr_getgregs_ID);
+ prgregset_t gregs;
+ p_td_thr_getgregs(&thr_handle, gregs);
+
+ jlongArray res = env->NewLongArray(NPRGREG);
+ CHECK_EXCEPTION_(0);
+ jboolean isCopy;
+ jlong* ptr = env->GetLongArrayElements(res, &isCopy);
+ for (int i = 0; i < NPRGREG; i++) {
+ ptr[i] = (jlong) (uintptr_t) gregs[i];
+ }
+ env->ReleaseLongArrayElements(res, ptr, JNI_COMMIT);
+ return res;
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: fillThreadList0
+ * Signature: (Ljava/util/List;)V
+ * Description: fills thread list of the debuggee process/core
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillThreadList0
+ (JNIEnv *env, jobject this_obj, jobject list) {
+
+ td_thragent_t* p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID);
+ if (p_td_thragent_t == 0) {
+ return;
+ }
+
+ p_td_ta_thr_iter_t p_td_ta_thr_iter = (p_td_ta_thr_iter_t) env->GetLongField(this_obj, p_td_ta_thr_iter_ID);
+
+ DebuggerWithObject dbgo;
+ dbgo.env = env;
+ dbgo.this_obj = this_obj;
+ dbgo.obj = list;
+
+ p_td_ta_thr_iter(p_td_thragent_t, fill_thread_list, &dbgo,
+ TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: fillCFrameList0
+ * Signature: ([J)Lsun/jvm/hotspot/debugger/proc/ProcCFrame;
+ * Description: fills CFrame list for a given thread
+ */
+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillCFrameList0
+ (JNIEnv *env, jobject this_obj, jlongArray regsArray) {
+ jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+
+ DebuggerWith2Objects dbgo2;
+ dbgo2.env = env;
+ dbgo2.this_obj = this_obj;
+ dbgo2.obj = NULL;
+ dbgo2.obj2 = NULL;
+
+ jboolean isCopy;
+ jlong* ptr = env->GetLongArrayElements(regsArray, &isCopy);
+ CHECK_EXCEPTION_(0);
+
+ prgregset_t gregs;
+ for (int i = 0; i < NPRGREG; i++) {
+ gregs[i] = (uintptr_t) ptr[i];
+ }
+
+ env->ReleaseLongArrayElements(regsArray, ptr, JNI_ABORT);
+ CHECK_EXCEPTION_(0);
+ Pstack_iter((struct ps_prochandle*) p_ps_prochandle, gregs, fill_cframe_list, &dbgo2);
+ return dbgo2.obj;
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: fillLoadObjectList0
+ * Signature: (Ljava/util/List;)V
+ * Description: fills shared objects of the debuggee process/core
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_fillLoadObjectList0
+ (JNIEnv *env, jobject this_obj, jobject list) {
+ DebuggerWithObject dbgo;
+ dbgo.env = env;
+ dbgo.this_obj = this_obj;
+ dbgo.obj = list;
+
+ jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ Pobject_iter((struct ps_prochandle*) p_ps_prochandle, fill_load_object_list, &dbgo);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: readBytesFromProcess0
+ * Signature: (JJ)[B
+ * Description: read bytes from debuggee process/core
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_readBytesFromProcess0
+ (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes) {
+
+ jbyteArray array = env->NewByteArray(numBytes);
+ CHECK_EXCEPTION_(0);
+ jboolean isCopy;
+ jbyte* bufPtr = env->GetByteArrayElements(array, &isCopy);
+ CHECK_EXCEPTION_(0);
+
+ jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ ps_err_e ret = ps_pread((struct ps_prochandle*) p_ps_prochandle,
+ (psaddr_t)address, bufPtr, (size_t)numBytes);
+
+ if (ret != PS_OK) {
+ // part of the class sharing workaround. try shared heap area
+ int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
+ if (classes_jsa_fd != -1 && address != (jlong)0) {
+ print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);
+
+ struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
+ // walk through the shared mappings -- we just have 4 of them.
+ // so, linear walking is okay.
+ for (int m = 0; m < NUM_SHARED_MAPS; m++) {
+
+ // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
+ // and hence will be read by libproc. Besides, the file copy may be
+ // stale because the process might have modified those pages.
+ if (pheader->_space[m]._read_only) {
+ jlong baseAddress = (jlong) (uintptr_t) pheader->_space[m]._base;
+ size_t usedSize = pheader->_space[m]._used;
+ if (address >= baseAddress && address < (baseAddress + usedSize)) {
+ // the given address falls in this shared heap area
+ print_debug("found shared map at 0x%lx\n", (long) baseAddress);
+
+
+ // If more data is asked than actually mapped from file, we need to zero fill
+ // till the end-of-page boundary. But, java array new does that for us. we just
+ // need to read as much as data available.
+
+#define MIN2(x, y) (((x) < (y))? (x) : (y))
+
+ jlong diff = address - baseAddress;
+ jlong bytesToRead = MIN2(numBytes, usedSize - diff);
+ off_t offset = pheader->_space[m]._file_offset + off_t(diff);
+ ssize_t bytesRead = pread(classes_jsa_fd, bufPtr, bytesToRead, offset);
+ if (bytesRead != bytesToRead) {
+ env->ReleaseByteArrayElements(array, bufPtr, JNI_ABORT);
+ print_debug("shared map read failed\n");
+ return jbyteArray(0);
+ } else {
+ print_debug("shared map read succeeded\n");
+ env->ReleaseByteArrayElements(array, bufPtr, 0);
+ return array;
+ }
+ } // is in current map
+ } // is read only map
+ } // for shared maps
+ } // classes_jsa_fd != -1
+ env->ReleaseByteArrayElements(array, bufPtr, JNI_ABORT);
+ return jbyteArray(0);
+ } else {
+ env->ReleaseByteArrayElements(array, bufPtr, 0);
+ return array;
+ }
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: writeBytesToProcess0
+ * Signature: (JJ[B)V
+ * Description: write bytes into debugger process
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_writeBytesToProcess0
+ (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes, jbyteArray data) {
+ jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ jboolean isCopy;
+ jbyte* ptr = env->GetByteArrayElements(data, &isCopy);
+ CHECK_EXCEPTION;
+
+ if (ps_pwrite((struct ps_prochandle*) p_ps_prochandle, address, ptr, numBytes) != PS_OK) {
+ env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+ THROW_NEW_DEBUGGER_EXCEPTION("Process write failed!");
+ }
+
+ env->ReleaseByteArrayElements(data, ptr, JNI_ABORT);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: suspend0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_suspend0
+ (JNIEnv *env, jobject this_obj) {
+ jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ // for now don't check return value. revisit this again.
+ Pstop((struct ps_prochandle*) p_ps_prochandle, 1000);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: resume0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_resume0
+ (JNIEnv *env, jobject this_obj) {
+ jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+ // for now don't check return value. revisit this again.
+ Psetrun((struct ps_prochandle*) p_ps_prochandle, 0, PRCFAULT|PRSTOP);
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: lookupByName0
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)J
+ * Description: symbol lookup by name
+*/
+JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByName0
+ (JNIEnv *env, jobject this_obj, jstring objectName, jstring symbolName) {
+ jlong p_ps_prochandle;
+ p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+
+ jboolean isCopy;
+ const char* objectName_cstr = NULL;
+ if (objectName != NULL) {
+ objectName_cstr = env->GetStringUTFChars(objectName, &isCopy);
+ CHECK_EXCEPTION_(0);
+ } else {
+ objectName_cstr = PR_OBJ_EVERY;
+ }
+
+ const char* symbolName_cstr = env->GetStringUTFChars(symbolName, &isCopy);
+ CHECK_EXCEPTION_(0);
+
+ psaddr_t symbol_addr = (psaddr_t) 0;
+ ps_pglobal_lookup((struct ps_prochandle*) p_ps_prochandle, objectName_cstr,
+ symbolName_cstr, &symbol_addr);
+
+ if (symbol_addr == 0) {
+ print_debug("lookup for %s in %s failed\n", symbolName_cstr, objectName_cstr);
+ }
+
+ if (objectName_cstr != PR_OBJ_EVERY) {
+ env->ReleaseStringUTFChars(objectName, objectName_cstr);
+ }
+ env->ReleaseStringUTFChars(symbolName, symbolName_cstr);
+ return (jlong) (uintptr_t) symbol_addr;
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: lookupByAddress0
+ * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
+ * Description: lookup symbol name for a given address
+ */
+JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_lookupByAddress0
+ (JNIEnv *env, jobject this_obj, jlong address) {
+ jlong p_ps_prochandle;
+ p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
+
+ char nameBuf[SYMBOL_BUF_SIZE + 1];
+ GElf_Sym sym;
+ int res = Plookup_by_addr((struct ps_prochandle*) p_ps_prochandle, (uintptr_t) address,
+ nameBuf, sizeof(nameBuf), &sym);
+ if (res != 0) { // failed
+ return 0;
+ }
+
+ jstring resSym = env->NewStringUTF(nameBuf);
+ CHECK_EXCEPTION_(0);
+
+ return env->CallObjectMethod(this_obj, createClosestSymbol_ID, resSym, (address - sym.st_value));
+}
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: demangle0
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_demangle0
+ (JNIEnv *env, jobject this_object, jstring name) {
+ jboolean isCopy;
+ const char* ptr = env->GetStringUTFChars(name, &isCopy);
+ char buf[2*SYMBOL_BUF_SIZE + 1];
+ jstring res = 0;
+ if (cplus_demangle((char*) ptr, buf, sizeof(buf)) != DEMANGLE_ESPACE) {
+ res = env->NewStringUTF(buf);
+ } else {
+ res = name;
+ }
+ env->ReleaseStringUTFChars(name, ptr);
+ return res;
+}
+
+typedef int (*find_file_hook_t)(const char *, int elf_checksum);
+
+/*
+ * Class: sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
+ * Method: initIDs
+ * Signature: ()V
+ * Description: get JNI ids for fields and methods of ProcDebuggerLocal class
+ */
+JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_initIDs
+ (JNIEnv *env, jclass clazz) {
+ _libsaproc_debug = getenv("LIBSAPROC_DEBUG") != NULL;
+ if (_libsaproc_debug) {
+ // propagate debug mode to libproc.so
+ static const char* var = "LIBPROC_DEBUG=1";
+ putenv((char*)var);
+ }
+
+ void* libproc_handle = dlopen("libproc.so", RTLD_LAZY | RTLD_GLOBAL);
+ if (libproc_handle == 0)
+ THROW_NEW_DEBUGGER_EXCEPTION("can't load libproc.so, if you are using Solaris 5.7 or below, copy libproc.so from 5.8!");
+
+ // If possible, set shared object find file hook.
+ void (*set_hook)(find_file_hook_t) = (void(*)(find_file_hook_t))dlsym(libproc_handle, "Pset_find_file_hook");
+ if (set_hook) {
+ // we found find file hook symbol, set up our hook function.
+ set_hook(find_file_hook);
+ } else if (getenv(SA_ALTROOT)) {
+ printf("libsaproc WARNING: %s set, but can't set file hook. " \
+ "Did you use right version of libproc.so?\n", SA_ALTROOT);
+ }
+
+ p_ps_prochandle_ID = env->GetFieldID(clazz, "p_ps_prochandle", "J");
+ CHECK_EXCEPTION;
+
+ libthread_db_handle_ID = env->GetFieldID(clazz, "libthread_db_handle", "J");
+ CHECK_EXCEPTION;
+
+ p_td_thragent_t_ID = env->GetFieldID(clazz, "p_td_thragent_t", "J");
+ CHECK_EXCEPTION;
+
+ p_td_init_ID = env->GetFieldID(clazz, "p_td_init", "J");
+ CHECK_EXCEPTION;
+
+ p_td_ta_new_ID = env->GetFieldID(clazz, "p_td_ta_new", "J");
+ CHECK_EXCEPTION;
+
+ p_td_ta_delete_ID = env->GetFieldID(clazz, "p_td_ta_delete", "J");
+ CHECK_EXCEPTION;
+
+ p_td_ta_thr_iter_ID = env->GetFieldID(clazz, "p_td_ta_thr_iter", "J");
+ CHECK_EXCEPTION;
+
+ p_td_thr_get_info_ID = env->GetFieldID(clazz, "p_td_thr_get_info", "J");
+ CHECK_EXCEPTION;
+
+ p_td_ta_map_id2thr_ID = env->GetFieldID(clazz, "p_td_ta_map_id2thr", "J");
+ CHECK_EXCEPTION;
+
+ p_td_thr_getgregs_ID = env->GetFieldID(clazz, "p_td_thr_getgregs", "J");
+ CHECK_EXCEPTION;
+
+ getThreadForThreadId_ID = env->GetMethodID(clazz,
+ "getThreadForThreadId", "(J)Lsun/jvm/hotspot/debugger/ThreadProxy;");
+ CHECK_EXCEPTION;
+
+ pcRegIndex_ID = env->GetFieldID(clazz, "pcRegIndex", "I");
+ CHECK_EXCEPTION;
+
+ fpRegIndex_ID = env->GetFieldID(clazz, "fpRegIndex", "I");
+ CHECK_EXCEPTION;
+
+ createSenderFrame_ID = env->GetMethodID(clazz,
+ "createSenderFrame", "(Lsun/jvm/hotspot/debugger/proc/ProcCFrame;JJ)Lsun/jvm/hotspot/debugger/proc/ProcCFrame;");
+ CHECK_EXCEPTION;
+
+ createLoadObject_ID = env->GetMethodID(clazz,
+ "createLoadObject", "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;");
+ CHECK_EXCEPTION;
+
+ createClosestSymbol_ID = env->GetMethodID(clazz,
+ "createClosestSymbol", "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
+ CHECK_EXCEPTION;
+
+ listAdd_ID = env->GetMethodID(env->FindClass("java/util/List"), "add", "(Ljava/lang/Object;)Z");
+ CHECK_EXCEPTION;
+
+ // part of the class sharing workaround
+ classes_jsa_fd_ID = env->GetFieldID(clazz, "classes_jsa_fd", "I");
+ CHECK_EXCEPTION;
+ p_file_map_header_ID = env->GetFieldID(clazz, "p_file_map_header", "J");
+ CHECK_EXCEPTION;
+}
diff --git a/hotspot/agent/src/os/win32/BasicList.hpp b/hotspot/agent/src/os/win32/BasicList.hpp
new file mode 100644
index 00000000000..eebf8ebed9a
--- /dev/null
+++ b/hotspot/agent/src/os/win32/BasicList.hpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _BASIC_LIST_
+#define _BASIC_LIST_
+
+#include
+
+template
+class BasicList {
+protected:
+ typedef std::vector InternalListType;
+ InternalListType internalList;
+
+public:
+ BasicList() {
+ }
+ virtual ~BasicList() {
+ }
+
+ void add(T arg) {
+ internalList.push_back(arg);
+ }
+
+ bool remove(T arg) {
+ for (InternalListType::iterator iter = internalList.begin();
+ iter != internalList.end(); iter++) {
+ if (*iter == arg) {
+ internalList.erase(iter);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ int size() {
+ return internalList.size();
+ }
+
+ T get(int index) {
+ return internalList[index];
+ }
+};
+
+#endif // #defined _BASIC_LIST_
diff --git a/hotspot/agent/src/os/win32/Buffer.cpp b/hotspot/agent/src/os/win32/Buffer.cpp
new file mode 100644
index 00000000000..24fb71077b1
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Buffer.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "Buffer.hpp"
+
+#include
+
+Buffer::Buffer(int bufSize) {
+ buf = new char[bufSize];
+ sz = bufSize;
+ fill = 0;
+ drain = 0;
+}
+
+Buffer::~Buffer() {
+ delete[] buf;
+}
+
+char*
+Buffer::fillPos() {
+ return buf + fill;
+}
+
+int
+Buffer::remaining() {
+ return sz - fill;
+}
+
+int
+Buffer::size() {
+ return sz;
+}
+
+bool
+Buffer::incrFillPos(int amt) {
+ if (fill + amt >= sz) {
+ return false;
+ }
+ fill += amt;
+ return true;
+}
+
+int
+Buffer::readByte() {
+ if (drain < fill) {
+ return buf[drain++] & 0xFF;
+ } else {
+ return -1;
+ }
+}
+
+int
+Buffer::readBytes(char* data, int len) {
+ int numRead = 0;
+ while (numRead < len) {
+ int c = readByte();
+ if (c < 0) break;
+ data[numRead++] = (char) c;
+ }
+ return numRead;
+}
+
+char*
+Buffer::drainPos() {
+ return buf + drain;
+}
+
+int
+Buffer::drainRemaining() {
+ return fill - drain;
+}
+
+bool
+Buffer::incrDrainPos(int amt) {
+ if (drainRemaining() < amt) {
+ return false;
+ }
+ drain += amt;
+ return true;
+}
+
+void
+Buffer::compact() {
+ // Copy down data
+ memmove(buf, buf + drain, fill - drain);
+ // Adjust positions
+ fill -= drain;
+ drain = 0;
+}
diff --git a/hotspot/agent/src/os/win32/Buffer.hpp b/hotspot/agent/src/os/win32/Buffer.hpp
new file mode 100644
index 00000000000..63a33c9609f
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Buffer.hpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _BUFFER_
+#define _BUFFER_
+
+// A Buffer is the backing store for the IOBuf abstraction and
+// supports producer-consumer filling and draining.
+
+class Buffer {
+public:
+ Buffer(int bufSize);
+ ~Buffer();
+
+ char* fillPos(); // Position of the place where buffer should be filled
+ int remaining(); // Number of bytes that can be placed starting at fillPos
+ int size(); // Size of the buffer
+ // Move up fill position by amount (decreases remaining()); returns
+ // false if not enough space
+ bool incrFillPos(int amt);
+
+ // Read single byte (0..255); returns -1 if no data available.
+ int readByte();
+ // Read multiple bytes, non-blocking (this buffer does not define a
+ // fill mechanism), into provided buffer. Returns number of bytes read.
+ int readBytes(char* buf, int len);
+
+ // Access to drain position. Be very careful using this.
+ char* drainPos();
+ int drainRemaining();
+ bool incrDrainPos(int amt);
+
+ // Compact buffer, removing already-consumed input. This must be
+ // called periodically to yield the illusion of an infinite buffer.
+ void compact();
+
+private:
+ Buffer(const Buffer&);
+ Buffer& operator=(const Buffer&);
+
+ char* buf;
+ int sz;
+ int fill;
+ int drain;
+};
+
+#endif // #defined _BUFFER_
diff --git a/hotspot/agent/src/os/win32/Dispatcher.cpp b/hotspot/agent/src/os/win32/Dispatcher.cpp
new file mode 100644
index 00000000000..6f09ed2de6a
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Dispatcher.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+#include "dispatcher.hpp"
+
+const char* CMD_ASCII = "ascii";
+const char* CMD_UNICODE = "unicode";
+const char* CMD_PROCLIST = "proclist";
+const char* CMD_ATTACH = "attach";
+const char* CMD_DETACH = "detach";
+const char* CMD_LIBINFO = "libinfo";
+const char* CMD_PEEK = "peek";
+const char* CMD_POKE = "poke";
+const char* CMD_THREADLIST = "threadlist";
+const char* CMD_DUPHANDLE = "duphandle";
+const char* CMD_CLOSEHANDLE = "closehandle";
+const char* CMD_GETCONTEXT = "getcontext";
+const char* CMD_SETCONTEXT = "setcontext";
+const char* CMD_SELECTORENTRY = "selectorentry";
+const char* CMD_SUSPEND = "suspend";
+const char* CMD_RESUME = "resume";
+const char* CMD_POLLEVENT = "pollevent";
+const char* CMD_CONTINUEEVENT = "continueevent";
+const char* CMD_EXIT = "exit";
+
+// Uncomment the #define below to get messages on stderr
+// #define DEBUGGING
+
+void
+Dispatcher::dispatch(char* cmd, Handler* handler) {
+ if (!strncmp(cmd, CMD_ASCII, strlen(CMD_ASCII))) {
+ handler->ascii(cmd + strlen(CMD_ASCII));
+
+ } else if (!strncmp(cmd, CMD_UNICODE, strlen(CMD_UNICODE))) {
+ handler->unicode(cmd + strlen(CMD_UNICODE));
+
+ } else if (!strncmp(cmd, CMD_PROCLIST, strlen(CMD_PROCLIST))) {
+ handler->procList(cmd + strlen(CMD_PROCLIST));
+
+ } else if (!strncmp(cmd, CMD_ATTACH, strlen(CMD_ATTACH))) {
+ handler->attach(cmd + strlen(CMD_ATTACH));
+
+ } else if (!strncmp(cmd, CMD_DETACH, strlen(CMD_DETACH))) {
+ handler->detach(cmd + strlen(CMD_DETACH));
+
+ } else if (!strncmp(cmd, CMD_LIBINFO, strlen(CMD_LIBINFO))) {
+ handler->libInfo(cmd + strlen(CMD_LIBINFO));
+
+ } else if (!strncmp(cmd, CMD_PEEK, strlen(CMD_PEEK))) {
+ handler->peek(cmd + strlen(CMD_PEEK));
+
+ } else if (!strncmp(cmd, CMD_POKE, strlen(CMD_POKE))) {
+ handler->poke(cmd + strlen(CMD_POKE));
+
+ } else if (!strncmp(cmd, CMD_THREADLIST, strlen(CMD_THREADLIST))) {
+ handler->threadList(cmd + strlen(CMD_THREADLIST));
+
+ } else if (!strncmp(cmd, CMD_DUPHANDLE, strlen(CMD_DUPHANDLE))) {
+ handler->dupHandle(cmd + strlen(CMD_DUPHANDLE));
+
+ } else if (!strncmp(cmd, CMD_CLOSEHANDLE, strlen(CMD_CLOSEHANDLE))) {
+ handler->closeHandle(cmd + strlen(CMD_CLOSEHANDLE));
+
+ } else if (!strncmp(cmd, CMD_GETCONTEXT, strlen(CMD_GETCONTEXT))) {
+ handler->getContext(cmd + strlen(CMD_GETCONTEXT));
+
+ } else if (!strncmp(cmd, CMD_SETCONTEXT, strlen(CMD_SETCONTEXT))) {
+ handler->setContext(cmd + strlen(CMD_SETCONTEXT));
+
+ } else if (!strncmp(cmd, CMD_SELECTORENTRY, strlen(CMD_SELECTORENTRY))) {
+ handler->selectorEntry(cmd + strlen(CMD_SELECTORENTRY));
+
+ } else if (!strncmp(cmd, CMD_SUSPEND, strlen(CMD_SUSPEND))) {
+ handler->suspend(cmd + strlen(CMD_SUSPEND));
+
+ } else if (!strncmp(cmd, CMD_RESUME, strlen(CMD_RESUME))) {
+ handler->resume(cmd + strlen(CMD_RESUME));
+
+ } else if (!strncmp(cmd, CMD_POLLEVENT, strlen(CMD_POLLEVENT))) {
+ handler->pollEvent(cmd + strlen(CMD_POLLEVENT));
+
+ } else if (!strncmp(cmd, CMD_CONTINUEEVENT, strlen(CMD_CONTINUEEVENT))) {
+ handler->continueEvent(cmd + strlen(CMD_CONTINUEEVENT));
+
+ } else if (!strcmp(cmd, CMD_EXIT)) {
+ handler->exit(cmd + strlen(CMD_EXIT));
+ }
+
+#ifdef DEBUGGING
+ else fprintf(stderr, "Ignoring illegal command \"%s\"\n", cmd);
+#endif
+}
diff --git a/hotspot/agent/src/os/win32/Dispatcher.hpp b/hotspot/agent/src/os/win32/Dispatcher.hpp
new file mode 100644
index 00000000000..af07c0749f0
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Dispatcher.hpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _DISPATCHER_
+#define _DISPATCHER_
+
+#include "Handler.hpp"
+
+/** This class understands the commands supported by the system and
+ calls the appropriate handler routines. */
+
+class Dispatcher {
+public:
+ static void dispatch(char* cmd, Handler* handler);
+};
+
+#endif // #defined _DISPATCHER_
diff --git a/hotspot/agent/src/os/win32/Handler.hpp b/hotspot/agent/src/os/win32/Handler.hpp
new file mode 100644
index 00000000000..b9b05ef7349
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Handler.hpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _HANDLER_
+#define _HANDLER_
+
+/** An abstract base class encapsulating the handlers for all commands
+ understood by the system. */
+class Handler {
+public:
+ virtual void ascii(char* arg) = 0;
+ virtual void unicode(char* arg) = 0;
+ virtual void procList(char* arg) = 0;
+ virtual void attach(char* arg) = 0;
+ virtual void detach(char* arg) = 0;
+ virtual void libInfo(char* arg) = 0;
+ virtual void peek(char* arg) = 0;
+ virtual void poke(char* arg) = 0;
+ virtual void threadList(char* arg) = 0;
+ virtual void dupHandle(char* arg) = 0;
+ virtual void closeHandle(char* arg) = 0;
+ virtual void getContext(char* arg) = 0;
+ virtual void setContext(char* arg) = 0;
+ virtual void selectorEntry(char* arg) = 0;
+ virtual void suspend(char* arg) = 0;
+ virtual void resume(char* arg) = 0;
+ virtual void pollEvent(char* arg) = 0;
+ virtual void continueEvent(char* arg) = 0;
+ virtual void exit(char* arg) = 0;
+};
+
+#endif // #defined _HANDLER_
diff --git a/hotspot/agent/src/os/win32/IOBuf.cpp b/hotspot/agent/src/os/win32/IOBuf.cpp
new file mode 100644
index 00000000000..41a3e2bcc2f
--- /dev/null
+++ b/hotspot/agent/src/os/win32/IOBuf.cpp
@@ -0,0 +1,490 @@
+/*
+ * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+
+// This file is currently used for os/solaris/agent too. At some point in time
+// the source will be reorganized to avoid these ifdefs.
+
+#ifdef __sun
+ #include
+ #include
+ #include
+#endif
+
+#include "IOBuf.hpp"
+
+// Formats for printing pointers
+#ifdef _LP64
+# define INTPTR_FORMAT "0x%016lx"
+#else /* ! _LP64 */
+# define INTPTR_FORMAT "0x%08lx"
+#endif /* _LP64 */
+
+// Uncomment the #define below to get messages on stderr
+// #define DEBUGGING
+
+IOBuf::IOBuf(int inLen, int outLen) {
+ inBuf = new Buffer(inLen);
+ outBuf = new Buffer(outLen);
+ fd = INVALID_SOCKET;
+ outHandle = NULL;
+ usingSocket = true;
+ reset();
+}
+
+IOBuf::~IOBuf() {
+ delete inBuf;
+ delete outBuf;
+}
+
+void
+IOBuf::setSocket(SOCKET sock) {
+ fd = sock;
+ usingSocket = true;
+}
+
+// Reading/writing files is only needed and used on windows.
+#ifdef WIN32
+void
+IOBuf::setOutputFileHandle(HANDLE handle) {
+ outHandle = handle;
+ usingSocket = false;
+}
+#endif
+
+void
+IOBuf::reset() {
+ gotDataLastTime = false;
+ state = TEXT_STATE;
+ binPos = 0;
+ binLength = 0;
+}
+
+IOBuf::ReadLineResult
+IOBuf::tryReadLine() {
+ return doReadLine(false);
+}
+
+char*
+IOBuf::readLine() {
+ ReadLineResult rr = doReadLine(true);
+ if (rr != RL_GOT_DATA) {
+ return NULL;
+ }
+ return getLine();
+}
+
+IOBuf::ReadLineResult
+IOBuf::doReadLine(bool shouldWait) {
+
+ if (!usingSocket) {
+ return IOBuf::RL_ERROR;
+ }
+
+ if (gotDataLastTime) {
+ curLine.clear();
+ }
+
+ int c;
+ do {
+ c = readChar(shouldWait);
+ if (c >= 0) {
+ Action act = processChar((char) c);
+ if (act == GOT_LINE) {
+ curLine.push_back('\0');
+ gotDataLastTime = true;
+ return IOBuf::RL_GOT_DATA;
+ } else if (act == SKIP_EOL_CHAR) {
+ // Do nothing
+ } else {
+ curLine.push_back((char) c);
+ }
+ }
+ } while (shouldWait || c >= 0);
+
+ gotDataLastTime = false;
+ return IOBuf::RL_NO_DATA;
+}
+
+bool
+IOBuf::flushImpl(bool moreDataToCome) {
+ int numWritten = 0;
+
+#ifdef WIN32
+ // When running on Windows and using IOBufs for inter-process
+ // communication, we need to write metadata into the stream
+ // indicating how many bytes are coming down. Five bytes are written
+ // per flush() call, four containing the integer number of bytes
+ // coming (not including the five-byte header) and one (a 0 or 1)
+ // indicating whether there is more data coming.
+ if (!usingSocket) {
+ int numToWrite = outBuf->drainRemaining();
+ char moreToCome = (moreDataToCome ? 1 : 0);
+ DWORD numBytesWritten;
+ if (!WriteFile(outHandle, &numToWrite, sizeof(int), &numBytesWritten, NULL)) {
+ return false;
+ }
+ if (numBytesWritten != sizeof(int)) {
+ return false;
+ }
+ if (!WriteFile(outHandle, &moreToCome, 1, &numBytesWritten, NULL)) {
+ return false;
+ }
+ if (numBytesWritten != 1) {
+ return false;
+ }
+ }
+#endif
+
+ while (outBuf->drainRemaining() != 0) {
+#ifdef DEBUGGING
+ fprintf(stderr, "Flushing %d bytes\n", outBuf->drainRemaining());
+#endif
+ if (usingSocket) {
+ numWritten = send(fd, outBuf->drainPos(), outBuf->drainRemaining(), 0);
+ } else {
+#ifdef WIN32
+ DWORD numBytesWritten;
+ if (!WriteFile(outHandle, outBuf->drainPos(), outBuf->drainRemaining(), &numBytesWritten, NULL)) {
+ numWritten = -1;
+ } else {
+ numWritten = numBytesWritten;
+ }
+#endif
+ }
+ if (numWritten != -1) {
+#ifdef DEBUGGING
+ fprintf(stderr, "Flushed %d bytes\n", numWritten);
+#endif
+ outBuf->incrDrainPos(numWritten);
+ } else {
+ return false;
+ }
+ }
+
+ outBuf->compact();
+
+ return true;
+}
+
+int
+IOBuf::readChar(bool block) {
+ do {
+ int c = inBuf->readByte();
+ if (c >= 0) {
+ return c;
+ }
+ // See whether we need to compact the input buffer
+ if (inBuf->remaining() < inBuf->size() / 2) {
+ inBuf->compact();
+ }
+ // See whether socket is ready
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ if (block || select(1 + fd, &fds, NULL, NULL, &timeout) > 0) {
+ if (block || FD_ISSET(fd, &fds)) {
+#ifdef DEBUGGING
+ int b = (block ? 1 : 0);
+ fprintf(stderr, "calling recv: block = %d\n", b);
+#endif
+ // Read data from socket
+ int numRead = recv(fd, inBuf->fillPos(), inBuf->remaining(), 0);
+ if (numRead < 0) {
+#ifdef DEBUGGING
+ fprintf(stderr, "recv failed\n");
+#endif
+ return -1;
+ }
+ inBuf->incrFillPos(numRead);
+ }
+ }
+ } while (block);
+
+ return inBuf->readByte();
+}
+
+char*
+IOBuf::getLine() {
+#ifdef DEBUGGING
+ fprintf(stderr, "Returning (first 10 chars) \"%.10s\"\n", curLine.begin());
+#endif
+ return curLine.begin();
+}
+
+bool
+IOBuf::flush() {
+ return flushImpl(false);
+}
+
+bool
+IOBuf::writeString(const char* str) {
+ int len = strlen(str);
+
+ if (len > outBuf->size()) {
+ return false;
+ }
+
+ if (len > outBuf->remaining()) {
+ if (!flushImpl(true)) {
+ return false;
+ }
+ }
+
+ // NOTE we do not copy the null terminator of the string.
+
+ strncpy(outBuf->fillPos(), str, len);
+ outBuf->incrFillPos(len);
+ return true;
+}
+
+bool
+IOBuf::writeInt(int val) {
+ char buf[128];
+ sprintf(buf, "%d", val);
+ return writeString(buf);
+}
+
+bool
+IOBuf::writeUnsignedInt(unsigned int val) {
+ char buf[128];
+ sprintf(buf, "%u", val);
+ return writeString(buf);
+}
+
+bool
+IOBuf::writeBoolAsInt(bool val) {
+ if (val) {
+ return writeString("1");
+ } else {
+ return writeString("0");
+ }
+}
+
+bool
+IOBuf::writeAddress(void* val) {
+ char buf[128];
+ sprintf(buf, INTPTR_FORMAT, val);
+ return writeString(buf);
+}
+
+bool
+IOBuf::writeSpace() {
+ return writeString(" ");
+}
+
+bool
+IOBuf::writeEOL() {
+ return writeString("\n\r");
+}
+
+bool
+IOBuf::writeBinChar(char c) {
+ return writeBinBuf((char*) &c, sizeof(c));
+}
+
+bool
+IOBuf::writeBinUnsignedShort(unsigned short i) {
+ i = htons(i);
+ return writeBinBuf((char*) &i, sizeof(i));
+}
+
+bool
+IOBuf::writeBinUnsignedInt(unsigned int i) {
+ i = htonl(i);
+ return writeBinBuf((char*) &i, sizeof(i));
+}
+
+bool
+IOBuf::writeBinBuf(char* buf, int size) {
+ while (size > 0) {
+ int spaceRemaining = outBuf->remaining();
+ if (spaceRemaining == 0) {
+ if (!flushImpl(true)) {
+ return false;
+ }
+ spaceRemaining = outBuf->remaining();
+ }
+ int toCopy = (size > spaceRemaining) ? spaceRemaining : size;
+ memcpy(outBuf->fillPos(), buf, toCopy);
+ outBuf->incrFillPos(toCopy);
+ buf += toCopy;
+ size -= toCopy;
+ if (size > 0) {
+ if (!flushImpl(true)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+#ifdef WIN32
+IOBuf::FillState
+IOBuf::fillFromFileHandle(HANDLE fh, DWORD* numBytesRead) {
+ int totalToRead;
+ char moreToCome;
+
+ outBuf->compact();
+
+ DWORD numRead;
+ if (!ReadFile(fh, &totalToRead, sizeof(int), &numRead, NULL)) {
+ return FAILED;
+ }
+ if (numRead != sizeof(int)) {
+ return FAILED;
+ }
+ if (!ReadFile(fh, &moreToCome, 1, &numRead, NULL)) {
+ return FAILED;
+ }
+ if (numRead != 1) {
+ return FAILED;
+ }
+ if (outBuf->remaining() < totalToRead) {
+ return FAILED;
+ }
+
+ int tmp = totalToRead;
+
+ while (totalToRead > 0) {
+ if (!ReadFile(fh, outBuf->fillPos(), totalToRead, &numRead, NULL)) {
+ return FAILED;
+ }
+ outBuf->incrFillPos((int) numRead);
+ totalToRead -= numRead;
+ }
+
+ *numBytesRead = tmp;
+ return ((moreToCome == 0) ? DONE : MORE_DATA_PENDING);
+}
+#endif
+
+bool
+IOBuf::isBinEscapeChar(char c) {
+ return (c == '|');
+}
+
+IOBuf::Action
+IOBuf::processChar(char c) {
+ Action action = NO_ACTION;
+ switch (state) {
+ case TEXT_STATE: {
+ // Looking for text char, bin escape char, or EOL
+ if (isBinEscapeChar(c)) {
+#ifdef DEBUGGING
+ fprintf(stderr, "[a: '%c'] ", inBuf[0]);
+#endif
+ binPos = 0;
+#ifdef DEBUGGING
+ fprintf(stderr, "[b: '%c'] ", inBuf[0]);
+#endif
+ binLength = 0;
+#ifdef DEBUGGING
+ fprintf(stderr, "[c: '%c'] ", inBuf[0]);
+#endif
+ state = BIN_STATE;
+#ifdef DEBUGGING
+ fprintf(stderr, "[d: '%c'] ", inBuf[0]);
+#endif
+#ifdef DEBUGGING
+ fprintf(stderr, "\nSwitching to BIN_STATE\n");
+#endif
+ } else if (isEOL(c)) {
+ state = EOL_STATE;
+ action = GOT_LINE;
+#ifdef DEBUGGING
+ fprintf(stderr, "\nSwitching to EOL_STATE (GOT_LINE)\n");
+#endif
+ }
+#ifdef DEBUGGING
+ else {
+ fprintf(stderr, "'%c' ", c);
+ fflush(stderr);
+ }
+#endif
+ break;
+ }
+
+ case BIN_STATE: {
+ // Seeking to finish read of input
+ if (binPos < 4) {
+ int cur = c & 0xFF;
+ binLength <<= 8;
+ binLength |= cur;
+ ++binPos;
+ } else {
+#ifdef DEBUGGING
+ fprintf(stderr, "Reading binary byte %d of %d\n",
+ binPos - 4, binLength);
+#endif
+ ++binPos;
+ if (binPos == 4 + binLength) {
+ state = TEXT_STATE;
+#ifdef DEBUGGING
+ fprintf(stderr, "Switching to TEXT_STATE\n");
+#endif
+ }
+ }
+ break;
+ }
+
+ case EOL_STATE: {
+ // More EOL characters just cause us to re-enter this state
+ if (isEOL(c)) {
+ action = SKIP_EOL_CHAR;
+ } else if (isBinEscapeChar(c)) {
+ binPos = 0;
+ binLength = 0;
+ state = BIN_STATE;
+ } else {
+ state = TEXT_STATE;
+#ifdef DEBUGGING
+ fprintf(stderr, "'%c' ", c);
+ fflush(stderr);
+#endif
+ }
+ break;
+ }
+
+ } // switch
+
+ return action;
+}
+
+
+bool
+IOBuf::isEOL(char c) {
+#ifdef WIN32
+ return ((c == '\n') || (c == '\r'));
+#elif defined(__sun)
+ return c == '\n';
+#else
+ #error Please port isEOL() to your platform
+ return false;
+#endif
+}
diff --git a/hotspot/agent/src/os/win32/IOBuf.hpp b/hotspot/agent/src/os/win32/IOBuf.hpp
new file mode 100644
index 00000000000..a6e84b884c6
--- /dev/null
+++ b/hotspot/agent/src/os/win32/IOBuf.hpp
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _IO_BUF_
+#define _IO_BUF_
+
+// This file is currently used for os/solaris/agent/ too. At some point in time
+// the source will be reorganized to avoid these ifdefs.
+// Note that this class can read/write from a file as well as a socket. This
+// file capability is only implemented on win32.
+
+#ifdef WIN32
+ #include
+#else
+ #include
+ #include
+ // These are from win32 winsock2.h
+ typedef unsigned int SOCKET;
+ typedef void * HANDLE;
+ typedef unsigned long DWORD;
+ #define INVALID_SOCKET (SOCKET)(~0)
+#endif
+
+#include
+#include "Buffer.hpp"
+
+/** Manages an input/output buffer pair for a socket or file handle. */
+class IOBuf {
+public:
+ IOBuf(int inBufLen, int outBufLen);
+ ~IOBuf();
+
+ enum ReadLineResult {
+ RL_GOT_DATA,
+ RL_NO_DATA,
+ RL_ERROR
+ };
+
+ /** Change the socket with which this buffer is associated */
+ void setSocket(SOCKET sock);
+
+ // Reading/writing files is only supported on windows.
+#ifdef WIN32
+ /** Change the output file handle with which this buffer is
+ associated. Currently IOBufs can not be used to read from a file
+ handle. */
+ void setOutputFileHandle(HANDLE handle);
+#endif
+
+ /** Reset the input and output buffers, without flushing the output
+ data to the socket */
+ void reset();
+
+ /** Try to read a line of data from the given socket without
+ blocking. If was able to read a complete line of data, returns a
+ character pointer to the beginning of the (null-terminated)
+ string. If not, returns NULL, but maintains enough state that
+ subsequent calls to tryReadLine() will not ignore the data
+ already read. NOTE: this skips end-of-line characters (typically
+ CR/LF) as defined by "isEOL()". When switching back and forth
+ between binary and text modes, to be sure no data is lost, pad
+ the beginning and end of the binary transmission with bytes
+ which can not be confused with these characters. */
+ ReadLineResult tryReadLine();
+
+ /** Read a line of data from the given socket, blocking until a
+ line, including EOL, appears. Return the line, or NULL if
+ something goes wrong. */
+ char *readLine();
+
+ /** Get the pointer to the beginning of the (null-terminated) line.
+ This should only be called if tryReadLine() has returned
+ RL_GOT_DATA. This sets the "parsing cursor" to the beginning of
+ the line. */
+ char* getLine();
+
+ // NOTE: any further data-acquisition routines must ALWAYS call
+ // fixupData() at the beginning!
+
+ //----------------------------------------------------------------------
+ // Output routines
+ //
+
+ /** Flush the output buffer to the socket. Returns true if
+ succeeded, false if write error occurred. */
+ bool flush();
+
+ /** Write the given string to the output buffer. May flush if output
+ buffer becomes too full to store the data. Not guaranteed to
+ work if string is longer than the size of the output buffer.
+ Does not include the null terminator of the string. Returns true
+ if succeeded, false if write error occurred. */
+ bool writeString(const char* str);
+
+ /** Write the given int to the output buffer. May flush if output
+ buffer becomes too full to store the data. Returns true if
+ succeeded, false if write error occurred. */
+ bool writeInt(int val);
+
+ /** Write the given unsigned int to the output buffer. May flush if
+ output buffer becomes too full to store the data. Returns true
+ if succeeded, false if write error occurred. */
+ bool writeUnsignedInt(unsigned int val);
+
+ /** Write the given boolean to the output buffer. May flush if
+ output buffer becomes too full to store the data. Returns true
+ if succeeded, false if write error occurred. */
+ bool writeBoolAsInt(bool val);
+
+ /** Write the given address to the output buffer. May flush if
+ output buffer becomes too full to store the data. Returns true
+ if succeeded, false if write error occurred. */
+ bool writeAddress(void* val);
+
+ /** Writes a space to the output buffer. May flush if output buffer
+ becomes too full to store the data. Returns true if succeeded,
+ false if write error occurred. */
+ bool writeSpace();
+
+ /** Writes an end-of-line sequence to the output buffer. May flush
+ if output buffer becomes too full to store the data. Returns
+ true if succeeded, false if write error occurred. */
+ bool writeEOL();
+
+ /** Writes a binary character to the output buffer. */
+ bool writeBinChar(char c);
+
+ /** Writes a binary unsigned short in network (big-endian) byte
+ order to the output buffer. */
+ bool writeBinUnsignedShort(unsigned short i);
+
+ /** Writes a binary unsigned int in network (big-endian) byte order
+ to the output buffer. */
+ bool writeBinUnsignedInt(unsigned int i);
+
+ /** Writes a binary buffer to the output buffer. */
+ bool writeBinBuf(char* buf, int size);
+
+#ifdef WIN32
+ enum FillState {
+ DONE = 1,
+ MORE_DATA_PENDING = 2,
+ FAILED = 3
+ };
+
+ /** Very specialized routine; fill the output buffer from the given
+ file handle. Caller is responsible for ensuring that there is
+ data to be read on the file handle. */
+ FillState fillFromFileHandle(HANDLE fh, DWORD* numRead);
+#endif
+
+ /** Binary utility routine (for poke) */
+ static bool isBinEscapeChar(char c);
+
+private:
+ IOBuf(const IOBuf&);
+ IOBuf& operator=(const IOBuf&);
+
+ // Returns -1 if non-blocking and no data available
+ int readChar(bool block);
+ // Line-oriented reading
+ std::vector curLine;
+ bool gotDataLastTime;
+
+ ReadLineResult doReadLine(bool);
+
+ bool flushImpl(bool moreDataToCome);
+
+ SOCKET fd;
+ HANDLE outHandle;
+ bool usingSocket;
+
+ // Buffers
+ Buffer* inBuf;
+ Buffer* outBuf;
+
+ // Simple finite-state machine to handle binary data
+ enum State {
+ TEXT_STATE,
+ BIN_STATE,
+ EOL_STATE
+ };
+ enum Action {
+ NO_ACTION,
+ GOT_LINE, // TEXT_STATE -> EOL_STATE transition
+ SKIP_EOL_CHAR // EOL_STATE -> EOL_STATE transition
+ };
+
+ State state;
+ Action processChar(char c);
+
+ // Handling incoming binary buffers (poke command)
+ int binPos; // Number of binary characters read so far;
+ // total number to read is binLength + 4
+ int binLength; // Number of binary characters in message;
+ // not valid until binPos >= 4
+
+ bool isEOL(char c);
+};
+
+#endif // #defined _IO_BUF_
diff --git a/hotspot/agent/src/os/win32/LockableList.hpp b/hotspot/agent/src/os/win32/LockableList.hpp
new file mode 100644
index 00000000000..a18e11eba83
--- /dev/null
+++ b/hotspot/agent/src/os/win32/LockableList.hpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _LOCKABLE_LIST_
+#define _LOCKABLE_LIST_
+
+#include
+#include "BasicList.hpp"
+
+template
+class LockableList : public BasicList {
+private:
+ CRITICAL_SECTION crit;
+
+public:
+ LockableList() {
+ InitializeCriticalSection(&crit);
+ }
+
+ ~LockableList() {
+ DeleteCriticalSection(&crit);
+ }
+
+ void lock() {
+ EnterCriticalSection(&crit);
+ }
+
+ void unlock() {
+ LeaveCriticalSection(&crit);
+ }
+};
+
+#endif // #defined _LOCKABLE_LIST_
diff --git a/hotspot/agent/src/os/win32/Makefile b/hotspot/agent/src/os/win32/Makefile
new file mode 100644
index 00000000000..ba9e6560374
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Makefile
@@ -0,0 +1,80 @@
+#
+# Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+#
+
+SERVER=SwDbgSrv.exe
+SUBPROCESS=SwDbgSub.exe
+
+SERVER_SOURCES = \
+ Buffer.cpp \
+ Dispatcher.cpp \
+ initWinsock.cpp \
+ IOBuf.cpp \
+ ioUtils.cpp \
+ isNT4.cpp \
+ nt4internals.cpp \
+ procList.cpp \
+ Reaper.cpp \
+ SwDbgSrv.cpp \
+ serverLists.cpp \
+ toolHelp.cpp
+
+SUBPROCESS_SOURCES = \
+ SwDbgSub.cpp \
+ Buffer.cpp \
+ IOBuf.cpp \
+ isNT4.cpp \
+ libInfo.cpp \
+ Monitor.cpp \
+ nt4internals.cpp \
+ toolHelp.cpp
+
+SERVER_OBJS = $(SERVER_SOURCES:.cpp=.obj)
+SUBPROCESS_OBJS = $(SUBPROCESS_SOURCES:.cpp=.obj)
+
+CPP=cl.exe
+LINK32=link.exe
+
+# These do not need to be optimized (don't run a lot of code) and it
+# will be useful to have the assertion checks in place
+
+CFLAGS=/nologo /MD /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+
+LIBS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib \
+ ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib \
+ winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib \
+ odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386
+
+default: $(SERVER) $(SUBPROCESS)
+
+$(SERVER): $(SERVER_OBJS)
+ $(LINK32) /out:$@ $(SERVER_OBJS) $(LIBS)
+
+$(SUBPROCESS): $(SUBPROCESS_OBJS)
+ $(LINK32) /out:$@ $(SUBPROCESS_OBJS) $(LIBS)
+
+clean:
+ rm -f *.obj *.idb *.pch *.pdb *.ncb *.opt *.plg *.exe *.ilk
+
+.cpp.obj:
+ @ $(CPP) $(CFLAGS) /o $@ $<
diff --git a/hotspot/agent/src/os/win32/Message.hpp b/hotspot/agent/src/os/win32/Message.hpp
new file mode 100644
index 00000000000..9f79d3b6f49
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Message.hpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _MESSAGE_
+#define _MESSAGE_
+
+// These are the commands sent from the server to the child processes
+// over the child processes' stdin pipes. A subset of the commands
+// understood by the overall system, these require responses from the
+// child process. Having a data structure rather than sending text
+// simplifies parsing on the child side. The child replies by sending
+// back fully-formatted replies which are copied by the server process
+// to the clients' sockets.
+
+struct PeekArg {
+ DWORD address;
+ DWORD numBytes;
+};
+
+// NOTE: when sending a PokeArg to the child process, we handle the
+// buffer specially
+struct PokeArg {
+ DWORD address;
+ DWORD numBytes;
+ void* data;
+};
+
+// Used for continueevent
+struct BoolArg {
+ bool val;
+};
+
+// Used for duphandle, closehandle, and getcontext
+struct HandleArg {
+ HANDLE handle;
+};
+
+// Used for setcontext
+const int NUM_REGS_IN_CONTEXT = 22;
+struct SetContextArg {
+ HANDLE handle;
+ DWORD Eax;
+ DWORD Ebx;
+ DWORD Ecx;
+ DWORD Edx;
+ DWORD Esi;
+ DWORD Edi;
+ DWORD Ebp;
+ DWORD Esp;
+ DWORD Eip;
+ DWORD Ds;
+ DWORD Es;
+ DWORD Fs;
+ DWORD Gs;
+ DWORD Cs;
+ DWORD Ss;
+ DWORD EFlags;
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr6;
+ DWORD Dr7;
+};
+
+// Used for selectorentry
+struct SelectorEntryArg {
+ HANDLE handle;
+ DWORD selector;
+};
+
+struct Message {
+ typedef enum {
+ ATTACH,
+ DETACH,
+ LIBINFO,
+ PEEK,
+ POKE,
+ THREADLIST,
+ DUPHANDLE,
+ CLOSEHANDLE,
+ GETCONTEXT,
+ SETCONTEXT,
+ SELECTORENTRY,
+ SUSPEND,
+ RESUME,
+ POLLEVENT,
+ CONTINUEEVENT
+ } Type;
+
+ Type type;
+ union {
+ PeekArg peekArg;
+ PokeArg pokeArg;
+ BoolArg boolArg;
+ HandleArg handleArg;
+ SetContextArg setContextArg;
+ SelectorEntryArg selectorArg;
+ };
+};
+
+#endif // #defined _MESSAGE_
diff --git a/hotspot/agent/src/os/win32/Monitor.cpp b/hotspot/agent/src/os/win32/Monitor.cpp
new file mode 100644
index 00000000000..5825ab62b06
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Monitor.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include
+#include "Monitor.hpp"
+
+Monitor::Monitor() {
+ _lock_count = -1; // No threads have entered the critical section
+ _owner = NULL;
+ _lock_event = CreateEvent(NULL, false, false, NULL);
+ _wait_event = CreateEvent(NULL, true, false, NULL);
+ _counter = 0;
+ _tickets = 0;
+ _waiters = 0;
+}
+
+Monitor::~Monitor() {
+ assert(_owner == NULL); // Otherwise, owned monitor being deleted
+ assert(_lock_count == -1); // Otherwise, monitor being deleted with non -1 lock count
+ CloseHandle(_lock_event);
+ CloseHandle(_wait_event);
+}
+
+void
+Monitor::lock() {
+ if (InterlockedIncrement(&_lock_count) == 0) {
+ // Success, we now own the lock
+ } else {
+ DWORD dwRet = WaitForSingleObject((HANDLE)_lock_event, INFINITE);
+ assert(dwRet == WAIT_OBJECT_0); // Unexpected return value from WaitForSingleObject
+ }
+ assert(owner() == NULL); // Otherwise, lock count and owner are inconsistent
+ setOwner(GetCurrentThread());
+}
+
+void
+Monitor::unlock() {
+ setOwner(NULL);
+ if (InterlockedDecrement(&_lock_count) >= 0) {
+ // Wake a waiting thread up
+ DWORD dwRet = SetEvent(_lock_event);
+ assert(dwRet != 0); // Unexpected return value from SetEvent
+ }
+}
+
+bool
+Monitor::wait(long timeout) {
+ assert(owner() != NULL);
+ assert(owner() == GetCurrentThread());
+
+ // 0 means forever. Convert to Windows specific code.
+ DWORD timeout_value = (timeout == 0) ? INFINITE : timeout;
+ DWORD which;
+
+ long c = _counter;
+ bool retry = false;
+
+ _waiters++;
+ // Loop until condition variable is signaled. The event object is
+ // set whenever the condition variable is signaled, and tickets will
+ // reflect the number of threads which have been notified. The counter
+ // field is used to make sure we don't respond to notifications that
+ // have occurred *before* we started waiting, and is incremented each
+ // time the condition variable is signaled.
+
+ while (true) {
+
+ // Leave critical region
+ unlock();
+
+ // If this is a retry, let other low-priority threads have a chance
+ // to run. Make sure that we sleep outside of the critical section.
+ if (retry) {
+ Sleep(1);
+ } else {
+ retry = true;
+ }
+
+ which = WaitForSingleObject(_wait_event, timeout_value);
+ // Enter critical section
+ lock();
+
+ if (_tickets != 0 && _counter != c) break;
+
+ if (which == WAIT_TIMEOUT) {
+ --_waiters;
+ return true;
+ }
+ }
+ _waiters--;
+
+ // If this was the last thread to be notified, then we need to reset
+ // the event object.
+ if (--_tickets == 0) {
+ ResetEvent(_wait_event);
+ }
+
+ return false;
+}
+
+// Notify a single thread waiting on this monitor
+bool
+Monitor::notify() {
+ assert(ownedBySelf()); // Otherwise, notify on unknown thread
+
+ if (_waiters > _tickets) {
+ if (!SetEvent(_wait_event)) {
+ return false;
+ }
+ _tickets++;
+ _counter++;
+ }
+
+ return true;
+}
+
+// Notify all threads waiting on this monitor
+bool
+Monitor::notifyAll() {
+ assert(ownedBySelf()); // Otherwise, notifyAll on unknown thread
+
+ if (_waiters > 0) {
+ if (!SetEvent(_wait_event)) {
+ return false;
+ }
+ _tickets = _waiters;
+ _counter++;
+ }
+
+ return true;
+}
+
+HANDLE
+Monitor::owner() {
+ return _owner;
+}
+
+void
+Monitor::setOwner(HANDLE owner) {
+ if (owner != NULL) {
+ assert(_owner == NULL); // Setting owner thread of already owned monitor
+ assert(owner == GetCurrentThread()); // Else should not be doing this
+ } else {
+ HANDLE oldOwner = _owner;
+ assert(oldOwner != NULL); // Removing the owner thread of an unowned mutex
+ assert(oldOwner == GetCurrentThread());
+ }
+ _owner = owner;
+}
+
+bool
+Monitor::ownedBySelf() {
+ return (_owner == GetCurrentThread());
+}
diff --git a/hotspot/agent/src/os/win32/Monitor.hpp b/hotspot/agent/src/os/win32/Monitor.hpp
new file mode 100644
index 00000000000..2eeacd24ccd
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Monitor.hpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _MONITOR_
+#define _MONITOR_
+
+#include
+
+class Monitor {
+public:
+ Monitor();
+ ~Monitor();
+
+ void lock();
+ void unlock();
+ // Default time is forever (i.e, zero). Returns true if it times-out, otherwise
+ // false.
+ bool wait(long timeout = 0);
+ bool notify();
+ bool notifyAll();
+
+private:
+ HANDLE owner();
+ void setOwner(HANDLE owner);
+ bool ownedBySelf();
+
+ HANDLE _owner;
+ long _lock_count;
+ HANDLE _lock_event; // Auto-reset event for blocking in lock()
+ HANDLE _wait_event; // Manual-reset event for notifications
+ long _counter; // Current number of notifications
+ long _waiters; // Number of threads waiting for notification
+ long _tickets; // Number of waiters to be notified
+};
+
+
+#endif // #defined _MONITOR_
diff --git a/hotspot/agent/src/os/win32/README-commands.txt b/hotspot/agent/src/os/win32/README-commands.txt
new file mode 100644
index 00000000000..0a1cb13a59f
--- /dev/null
+++ b/hotspot/agent/src/os/win32/README-commands.txt
@@ -0,0 +1,246 @@
+This debug server uses a largely text-based protocol, except for
+certain bulk data transfer operations. All text is in single-byte
+US-ASCII except for the strings returned in "proclist".
+
+NOTE that the character '|' (vertical bar) is used as an escape
+character to switch the incoming data stream to the debug server into
+binary mode, so no text command may contain that character.
+
+Commands understood:
+
+ascii ::=
+
+ Changes to ASCII mode. This affects all outgoing strings. At
+ startup the system is in unicode mode.
+
+unicode ::=
+
+ Changes to UNICODE mode. This affects all outgoing strings. This
+ is the default mode upon startup.
+
+proclist ::=
+ [ []...]...
+
+ Returns integer indicating number of processes to follow, followed
+ by (pid, name) pairs. Names are given by (charSize, numChars,
+ [char_t]...) tuples; charSize indicates the size of each character
+ in bytes, numChars the number of characters in the string, and
+ name the raw data for the string. Each individual character of the
+ string, if multi-byte, is transmitted in network byte order.
+ numChars and name are guaranteed to be separated by precisely one
+ US-ASCII space. If process list is not available because of
+ limitations of the underlying operating system, number of
+ processes returned is 0.
+
+attach ::=
+
+ Attempts to attach to the specified process. Returns 1 if
+ successful, 0 if not. Will fail if already attached or if the
+ process ID does not exist. Attaching to a process causes the
+ process to be suspended.
+
+detach ::=
+
+ Detaches from the given process. Attaching and detaching multiple
+ times during a debugging session is allowed. Detaching causes the
+ process to resume execution.
+
+libinfo ::=
+ [ []... ]...
+
+ May only be called once attached and the target process must be
+ suspended; otherwise, returns 0. Returns list of the full path
+ names of all of the loaded modules (including the executable
+ image) in the target process, as well as the base address at which
+ each module was relocated. See proclist for format of strings, but
+ NOTE that charSize is ALWAYS 1 for this particular routine,
+ regardless of the setting of ASCII/UNICODE.
+
+peek ::=
+ B
+ [ []...]...
+
+ NOTE that the binary portion of this message is prefixed by the
+ uppercase US-ASCII letter 'B', allowing easier synchronization by
+ clients. There is no data between the 'B' and the rest of the
+ message.
+
+ May only be called once attached. Reads the address space of the
+ target process starting at the given address (see below for format
+ specifications) and extending the given number of bytes. Whether
+ the read succeeded is indicated by a single byte containing a 1 or
+ 0 (success or failure). If successful, the return result is given
+ in a sequence of ranges. _len_, the length of each range, is
+ indicated by a 32-bit unsigned integer transmitted with big-endian
+ byte ordering (i.e., most significant byte first). _isMapped_
+ indicates whether the range is mapped or unmapped in the target
+ process's address space, and will contain the value 1 or 0 for
+ mapped or unmapped, respectively. If the range is mapped,
+ _isMapped_ is followed by _data_, containing the raw binary data
+ for the range. The sum of all ranges' lengths is guaranteed to be
+ equivalent to the number of bytes requested.
+
+poke |[ []] ::=
+
+
+ NOTE that the binary portion of this message is prefixed by the
+ uppercase US-ASCII character '|' (vertical bar), allowing easier
+ synchronization by the server. There is no data between the '|'
+ and the rest of the message. ('B' is not used here because
+ addresses can contain that letter; no alphanumeric characters are
+ used because some of the parsing routines are used by the Solaris
+ SA port, and in that port any alphanumeric character can show up
+ as a part of a symbol being looked up.)
+
+ May only be called once attached. Writes the address space of the
+ target process starting at the given address (see below for format
+ specifications), extending the given number of bytes, and
+ containing the given data. The number of bytes is a 32-bit
+ unsigned integer transmitted with big-endian byte ordering (i.e.,
+ most significant byte first). This is followed by the raw binary
+ data to be placed at that address. The number of bytes of data
+ must match the number of bytes specified in the message.
+
+ Returns true if the write succeeded; false if it failed, for
+ example because a portion of the region was not mapped in the
+ target address space.
+
+threadlist ::= [...]
+
+ May only be called once attached and the target process must be
+ suspended; otherwise, returns 0. If available, returns handles for
+ all of the threads in the target process. These handles may be
+ used as arguments to the getcontext and selectorentry
+ commands. They do not need to be (and should not be) duplicated
+ via the duphandle command and must not be closed via the
+ closehandle command.
+
+duphandle ::=
+ []
+
+ Duplicates a HANDLE read from the target process's address space.
+ HANDLE is a Windows construct (typically typedef'd to void *).
+ The returned handle should ultimately be closed via the
+ closehandle command; failing to do so can cause resource leaks.
+
+ The purpose of this command is to allow the debugger to read the
+ value of a thread handle from the target process and query its
+ register set and thread selector entries via the getcontext and
+ selectorentry commands, below; such use implies that the target
+ program has its own notion of the thread list, and further, that
+ the debugger has a way of locating that thread list.
+
+closehandle ::=
+
+ Closes a handle retrieved via the duphandle command, above.
+
+getcontext ::= []
+
+ Returns the context for the given thread. The handle must either
+ be one of the handles returned from the threadlist command or the
+ result of duplicating a thread handle out of the target process
+ via the duphandle command. The target process must be suspended.
+
+ The context is returned as a series of hex values which represent
+ the following x86 registers in the following order:
+ EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, DS, ES, FS, GS,
+ CS, SS, EFLAGS, DR0, DR1, DR2, DR3, DR6, DR7
+
+ FIXME: needs to be generalized and/or specified for other
+ architectures.
+
+setcontext ::=
+
+ Sets the context of the given thread. The target process must be
+ suspended. See the getcontext command for the ordering of the
+ registers in the context.
+
+ Even if the setcontext command succeeds, some of the bits in some
+ of the registers (like the global enable bits in the debug
+ registers) may be overridden by the operating system. To ensure
+ the debugger's notion of the register set is up to date, it is
+ recommended to follow up a setcontext with a getcontext.
+
+selectorentry ::=
+
+ [
+
+ ]
+
+ Retrieves a descriptor table entry for the given thread and
+ selector. This data structure allows conversion of a
+ segment-relative address to a linear virtual address. It is most
+ useful for locating the Thread Information Block for a given
+ thread handle to be able to find that thread's ID, to be able to
+ understand whether two different thread handles in fact refer to
+ the same underlying thread.
+
+ This command will only work on the X86 architecture and will
+ return false for the success flag (with no additional information
+ sent) on other architectures.
+
+suspend ::=
+
+ Suspends the target process. Must be attached to a target process.
+ A process is suspended when attached to via the attach command. If
+ the target process is already suspended then this command has no
+ effect.
+
+resume ::=
+
+ Resumes the target process without detaching from it. Must be
+ attached to a target process. After resuming a target process, the
+ debugger client must be prepared to poll for events from the
+ target process fairly frequently in order for execution in the
+ target process to proceed normally. If the target process is
+ already resumed then this command has no effect.
+
+pollevent ::=
+ [ ]
+
+ Additional entries in result for given eventCode:
+
+ LOAD/UNLOAD_DLL_DEBUG_EVENT:
+ EXCEPTION_DEBUG_EVENT:
+
+ Additional entries for given exceptionCode:
+
+ EXCEPTION_ACCESS_VIOLATION:
+
+
+
+ Polls once to see whether a debug event has been generated by the
+ target process. If none is present, returns 0 immediately.
+ Otherwise, returns 1 along with a series of textual information
+ about the event. The event is not cleared, and the thread resumed,
+ until the continueevent command is sent, or the debugger client
+ detaches from the target process.
+
+ Typically a debugger client will suspend the target process upon
+ reception of a debug event. Otherwise, it is not guaranteed that
+ all threads will be suspended upon reception of a debug event, and
+ any operations requiring that threads be suspended (including
+ fetching the context for the thread which generated the event)
+ will fail.
+
+continueevent ::=
+
+ Indicates that the current debug event has been used by the
+ debugger client and that the target process should be resumed. The
+ passEventToClient flag indicates whether the event should be
+ propagated to the target process. Breakpoint and single-step
+ events should not be propagated to the target. Returns false if
+ there was no pending event, true otherwise.
+
+exit
+
+ Exits this debugger session.
+
+Format specifications:
+
+// Data formats and example values:
+ ::= end of line (typically \n on Unix platforms, or \n\r on Windows)
+ ::= 0x12345678[9ABCDEF0] /* up to 64-bit hex value */
+ ::= 5 /* up to 32-bit integer number; no leading sign */
+ ::= 1 /* ASCII '0' or '1' */
+ ::= ...
diff --git a/hotspot/agent/src/os/win32/README.txt b/hotspot/agent/src/os/win32/README.txt
new file mode 100644
index 00000000000..e470b471bef
--- /dev/null
+++ b/hotspot/agent/src/os/win32/README.txt
@@ -0,0 +1,64 @@
+This is a "Simple Windows Debug Server" written for the purpose of
+enabling the Serviceability Agent on Win32. It has backends both for
+Windows NT 4.0 (using internal Windows APIs for a few routines) as
+well as for 95/98/ME/2000 via the Tool Help APIs.
+
+The reason this debug server is necessary is that the Win32 debug APIs
+by design tear down the target process when the debugger exits (see
+knowledge base article Q164205 on msdn.microsoft.com). On Solaris, one
+can attach to and detach from a process with no effect; this is key to
+allowing dbx and gcore to work.
+
+The Simple Windows Debug Server effectively implements attach/detach
+functionality for arbitrary debug clients. This allows the SA to
+attach non-destructively to a process, and will enable gcore for Win32
+to be written shortly. While the debugger (the "client" in all of the
+source code) is attached, the target process is suspended. (Note that
+the debug server could be extended to support resumption of the target
+process and transmission of debug events over to the debugger, but
+this has been left for the future.)
+
+The makefile (type "nmake") builds two executables: SwDbgSrv.exe,
+which is the server process, and SwDbgSub.exe, which is forked by the
+server and should not be directly invoked by the user.
+
+The intent is that these two executables can be installed into
+C:\WINNT\SYSTEM32 and SwDbgSrv installed to run as a service (on NT),
+for example using ServiceInstaller (http://www.kcmultimedia.com/smaster/).
+However, SwDbgSrv can also be run from the command line. It generates
+no text output unless the source code is changed to enable debugging
+printouts. As long as any processes which have been attached to by the
+SA are alive, the SwDbgSrv and any forked SwDbgSub processes must be
+left running. Terminating them will cause termination of the target
+processes.
+
+The debug server opens port 27000 and accepts incoming connections
+from localhost only. The security model assumes that if one can run a
+process on the given machine then one basically has access to most or
+all of the machine's facilities; this seems to be in line with the
+standard Windows security model. The protocol used is text-based, so
+one can debug the debug server using telnet. See README-commands.txt
+for documentation on the supported commands.
+
+Testing indicates that the performance impact of attaching to a
+process (and therefore permanently attaching a debugger) is minimal.
+Some serious performance problems had been seen which ultimately
+appeared to be a lack of physical memory on the machine running the
+system.
+
+Bugs:
+
+This debug server is fundamentally incompatible with the Visual C++
+debugger. Once the debug server is used to attach to a process, the
+Visual C++ IDE will not be able to attach to the same process (even if
+the debug server is "detached" from that process). Note that this
+system is designed to work with the same primitives that C and C++
+debuggers use (like "symbol lookup" and "read from process memory")
+and exposes these primitives to Java, so in the long term we could
+solve this problem by implementing platform-specific debug symbol
+parsing and a platform-independent C++ debugger in Java.
+
+Note:
+
+The files IOBuf.cpp and IOBuf.hpp are also used in
+building src/os/solaris/agent.
diff --git a/hotspot/agent/src/os/win32/Reaper.cpp b/hotspot/agent/src/os/win32/Reaper.cpp
new file mode 100644
index 00000000000..565aa9d675b
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Reaper.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include
+#include "Reaper.hpp"
+
+using namespace std;
+
+Reaper::Reaper(ReaperCB* cb) {
+ InitializeCriticalSection(&crit);
+ event = CreateEvent(NULL, TRUE, FALSE, NULL);
+ this->cb = cb;
+
+ active = false;
+ shouldShutDown = false;
+}
+
+bool
+Reaper::start() {
+ bool result = false;
+
+ EnterCriticalSection(&crit);
+
+ if (!active) {
+ DWORD id;
+ HANDLE reaper = CreateThread(NULL, 0, &Reaper::reaperThreadEntry,
+ this, 0, &id);
+ if (reaper != NULL) {
+ result = true;
+ }
+ }
+
+ LeaveCriticalSection(&crit);
+
+ return result;
+}
+
+bool
+Reaper::stop() {
+ bool result = false;
+
+ EnterCriticalSection(&crit);
+
+ if (active) {
+ shouldShutDown = true;
+ SetEvent(event);
+ while (active) {
+ Sleep(1);
+ }
+ shouldShutDown = false;
+ result = true;
+ }
+
+ LeaveCriticalSection(&crit);
+
+ return result;
+}
+
+void
+Reaper::registerProcess(HANDLE processHandle, void* userData) {
+ ProcessInfo info;
+
+ info.handle = processHandle;
+ info.userData = userData;
+
+ EnterCriticalSection(&crit);
+
+ procInfo.push_back(info);
+ SetEvent(event);
+
+ LeaveCriticalSection(&crit);
+}
+
+void
+Reaper::reaperThread() {
+ while (!shouldShutDown) {
+ // Take atomic snapshot of the current process list and user data
+ EnterCriticalSection(&crit);
+
+ int num = procInfo.size();
+ HANDLE* handleList = new HANDLE[1 + num];
+ void** dataList = new void*[num];
+ for (int i = 0; i < num; i++) {
+ handleList[i] = procInfo[i].handle;
+ dataList[i] = procInfo[i].userData;
+ }
+
+ LeaveCriticalSection(&crit);
+
+ // Topmost handle becomes the event object, so other threads can
+ // signal this one to notice differences in the above list (or
+ // shut down)
+ handleList[num] = event;
+
+ // Wait for these objects
+ DWORD idx = WaitForMultipleObjects(1 + num, handleList,
+ FALSE, INFINITE);
+ if ((idx >= WAIT_OBJECT_0) && (idx <= WAIT_OBJECT_0 + num)) {
+ idx -= WAIT_OBJECT_0;
+ if (idx < num) {
+ // A process exited (i.e., it wasn't that we were woken up
+ // just because the event went off)
+ (*cb)(dataList[idx]);
+ // Remove this process from the list (NOTE: requires that
+ // ordering does not change, i.e., that all additions are to
+ // the back of the process list)
+ EnterCriticalSection(&crit);
+
+ std::vector::iterator iter = procInfo.begin();
+ iter += idx;
+ procInfo.erase(iter);
+
+ LeaveCriticalSection(&crit);
+ } else {
+ // Notification from other thread
+ ResetEvent(event);
+ }
+ } else {
+ // Unexpected return value. For now, warn.
+ cerr << "Reaper::reaperThread(): unexpected return value "
+ << idx << " from WaitForMultipleObjects" << endl;
+ }
+
+ // Clean up these lists
+ delete[] handleList;
+ delete[] dataList;
+ }
+
+ // Time to shut down
+ active = false;
+}
+
+DWORD WINAPI
+Reaper::reaperThreadEntry(LPVOID data) {
+ Reaper* reaper = (Reaper*) data;
+ reaper->reaperThread();
+ return 0;
+}
diff --git a/hotspot/agent/src/os/win32/Reaper.hpp b/hotspot/agent/src/os/win32/Reaper.hpp
new file mode 100644
index 00000000000..047e3e112fa
--- /dev/null
+++ b/hotspot/agent/src/os/win32/Reaper.hpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#ifndef _REAPER_
+#define _REAPER_
+
+#include
+#include
+
+typedef void ReaperCB(void* userData);
+
+/** A Reaper maintains a thread which waits for child processes to
+ terminate; upon termination it calls a user-specified ReaperCB to
+ clean up resources associated with those child processes. */
+
+class Reaper {
+private:
+ Reaper& operator=(const Reaper&);
+ Reaper(const Reaper&);
+
+public:
+ Reaper(ReaperCB*);
+ ~Reaper();
+
+ // Start the reaper thread.
+ bool start();
+
+ // Stop the reaper thread. This is called automatically in the
+ // reaper's destructor. It is not thread safe and should be called
+ // by at most one thread at a time.
+ bool stop();
+
+ // Register a given child process with the reaper. This should be
+ // called by the application's main thread. When that process
+ // terminates, the cleanup callback will be called with the
+ // specified userData in the context of the reaper thread. Callbacks
+ // are guaranteed to be called serially, so they can safely refer to
+ // static data as well as the given user data.
+ void registerProcess(HANDLE processHandle, void* userData);
+
+private:
+ // For thread safety of register()
+ CRITICAL_SECTION crit;
+
+ ReaperCB* cb;
+
+ // State variables
+ volatile bool active;
+ volatile bool shouldShutDown;
+
+ struct ProcessInfo {
+ HANDLE handle;
+ void* userData;
+ };
+
+ // Bookkeeping
+ std::vector procInfo;
+
+ // Synchronization between application thread and reaper thread
+ HANDLE event;
+
+ // Entry point for reaper thread
+ void reaperThread();
+
+ // Static function which is actual thread entry point
+ static DWORD WINAPI reaperThreadEntry(LPVOID data);
+};
+
+#endif // #defined _REAPER_
diff --git a/hotspot/agent/src/os/win32/SwDbgSrv.cpp b/hotspot/agent/src/os/win32/SwDbgSrv.cpp
new file mode 100644
index 00000000000..b17cc66a9a2
--- /dev/null
+++ b/hotspot/agent/src/os/win32/SwDbgSrv.cpp
@@ -0,0 +1,1266 @@
+/*
+ * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// A Simple Windows Debug Server.
+//
+// This software provides a socket-based debug server which uses
+// mostly ASCII protocols to communicate with its clients. Since the
+// Windows security model is largely based around being able to run
+// programs on the machine, this server only accepts connections
+// coming from localhost.
+//
+// When run as a service (under Windows NT), this software provides
+// clients the ability to attach to and detach from processes without
+// killing those processes. Ordinarily this is forbidden by the
+// Windows debugging APIs (although more recent debugging environments
+// from Microsoft seem to have circumvented this restriction, perhaps
+// in a different way). This is achieved by forking a persistent
+// subprocess for each debugging session which remains alive as long
+// as the target process is.
+//
+// At this point the client can read information out of the target
+// process's address space. Future work includes exposing more
+// functionality like writing to the remote address space and
+// suspending and resuming threads.
+
+#include
+#include
+#include
+// Must come before everything else
+#include
+#include
+#include "Dispatcher.hpp"
+#include "Handler.hpp"
+#include "initWinsock.hpp"
+#include "ioUtils.hpp"
+#include "isNT4.hpp"
+#include "Message.hpp"
+#include "nt4internals.hpp"
+#include "ports.h"
+#include "procList.hpp"
+#include "serverLists.hpp"
+#include "Reaper.hpp"
+
+// Uncomment the #define below to get messages on stderr
+// #define DEBUGGING
+
+using namespace std;
+
+static ChildList childList;
+static ClientList clientList;
+static Reaper* reaper = NULL;
+
+// Needed prototypes
+void shutdownChild(ChildInfo* childInfo);
+void detachClient(ClientInfo* clientInfo);
+void shutdownClient(ClientInfo* clientInfo);
+
+char *
+longToDotFormat(long addr)
+{
+ char *temp_s = new char[20];
+
+ sprintf(temp_s, "%d.%d.%d.%d", ((addr & 0xff000000) >> 24),
+ ((addr & 0x00ff0000) >> 16), ((addr & 0x0000ff00) >> 8),
+ (addr & 0x000000ff));
+
+ return temp_s;
+}
+
+// NOTE that we do this query every time. It is a bad idea to cache IP
+// addresses. For example, we might be hosted on a machine using DHCP
+// and the connection addresses might change over time. (Yes, this
+// actually happened.)
+bool
+isConnectionOkay(ULONG connAddr) {
+ if (connAddr == INADDR_LOOPBACK) {
+ return true;
+ }
+
+ const int MAXNAME = 1024;
+ char myname[MAXNAME];
+ gethostname(myname, MAXNAME);
+ struct hostent* myInfo = gethostbyname(myname);
+ if (myInfo == NULL) {
+#ifdef DEBUGGING
+ cerr << "My host information was null" << endl;
+#endif
+ } else {
+ // Run down the list of IP addresses for myself
+ assert(myInfo->h_length == sizeof(ULONG));
+#ifdef DEBUGGING
+ cerr << "My known IP addresses: " << endl;
+#endif
+ for (char** pp = myInfo->h_addr_list; *pp != NULL; pp++) {
+ char* p = *pp;
+ ULONG altAddr = ntohl(*((ULONG*) p));
+#ifdef DEBUGGING
+ char* name = longToDotFormat(altAddr);
+ cerr << name << endl;
+ delete[] name;
+#endif
+ if (altAddr == connAddr) {
+#ifdef DEBUGGING
+ cerr << "FOUND" << endl;
+#endif
+ return true;
+ }
+ }
+#ifdef DEBUGGING
+ cerr << "Done." << endl;
+#endif
+ }
+
+ return false;
+}
+
+SOCKET
+setupListeningSocket(short port) {
+ SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
+ if (listening == INVALID_SOCKET) {
+ cerr << "Error creating listening socket" << endl;
+ exit(1);
+ }
+
+ int reuseAddress = 1;
+ if (setsockopt(listening, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&reuseAddress, sizeof(reuseAddress)) == -1) {
+ cerr << "Error reusing address" << endl;
+ exit(1);
+ }
+
+ struct sockaddr_in serverInfo;
+
+ memset((char *)&serverInfo, 0, sizeof(serverInfo));
+ serverInfo.sin_addr.s_addr = INADDR_ANY;
+ serverInfo.sin_family = AF_INET;
+ serverInfo.sin_port = htons(port);
+
+ if (bind(listening, (struct sockaddr *) &serverInfo, sizeof(serverInfo)) < 0) {
+ cerr << "Error binding socket" << endl;
+ exit(1);
+ }
+
+ if (listen(listening, 5) < 0) {
+ cerr << "Error listening" << endl;
+ exit(1);
+ }
+
+ return listening;
+}
+
+/** Accepts a connection from the given listening socket, but only if
+ the connection came from localhost. Returns INVALID_SOCKET if the
+ connection came from any other IP address or if an error occurred
+ during the call to accept(). */
+SOCKET
+acceptFromLocalhost(SOCKET listening) {
+ struct sockaddr_in peerAddr;
+ int peerAddrLen = sizeof(peerAddr);
+ SOCKET fd = accept(listening, (sockaddr*) &peerAddr, &peerAddrLen);
+ if (fd == INVALID_SOCKET) {
+ return fd;
+ }
+
+ if (!isConnectionOkay(ntohl(peerAddr.sin_addr.s_addr))) {
+ // Reject connections from other machines for security purposes.
+ // The Windows security model seems to assume one user per
+ // machine, and that security is compromised if another user is
+ // able to run executables on the given host. (If these
+ // assumptions are not strict enough, we will have to change
+ // this.)
+ shutdown(fd, SD_BOTH);
+ closesocket(fd);
+ return INVALID_SOCKET;
+ }
+
+ // Disable TCP buffering on all sockets. We send small amounts of
+ // data back and forth and don't want buffering.
+ int buffer_val = 1;
+ if (setsockopt(fd, IPPROTO_IP, TCP_NODELAY,
+ (char *) &buffer_val, sizeof(buffer_val)) < 0) {
+ shutdown(fd, SD_BOTH);
+ closesocket(fd);
+ }
+
+ return fd;
+}
+
+void
+reapCB(void* arg) {
+ ChildInfo* info = (ChildInfo*) arg;
+ ListsLocker ll;
+ DWORD pid = info->getPid();
+ shutdownChild(info);
+#ifdef DEBUGGING
+ cerr << "Reaped child for process " << pid << endl;
+#endif
+}
+
+/** Starts a child process with stdin and stdout redirected to pipes,
+ handles to which are returned. auxHandle1 and auxHandle2 should be
+ closed as well when the child process exits. Returns false if
+ process creation failed. */
+bool
+startChildProcess(DWORD pidToDebug,
+ DWORD childStdinBufSize,
+ DWORD childStdoutBufSize,
+ LPHANDLE childProcessHandle,
+ LPHANDLE writeToStdinHandle,
+ LPHANDLE readFromStdoutHandle,
+ LPHANDLE auxHandle1,
+ LPHANDLE auxHandle2) {
+ // Code adapted from Microsoft example
+ // "Creating a Child Process with Redirected Input and Output"
+
+ SECURITY_ATTRIBUTES saAttr;
+ BOOL fSuccess;
+
+ HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
+ hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
+ hSaveStdin, hSaveStdout;
+
+ // Set the bInheritHandle flag so pipe handles are inherited.
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
+
+ // The steps for redirecting child process's STDOUT:
+ // 1. Save current STDOUT, to be restored later.
+ // 2. Create anonymous pipe to be STDOUT for child process.
+ // 3. Set STDOUT of the parent process to be write handle to
+ // the pipe, so it is inherited by the child process.
+ // 4. Create a noninheritable duplicate of the read handle and
+ // close the inheritable read handle.
+
+ // Save the handle to the current STDOUT.
+ hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+ // Create a pipe for the child process's STDOUT.
+ if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, childStdoutBufSize)) {
+ return false;
+ }
+ // Set a write handle to the pipe to be STDOUT.
+ if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) {
+ return false;
+ }
+ // Create noninheritable read handle and close the inheritable read
+ // handle.
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
+ GetCurrentProcess(), &hChildStdoutRdDup,
+ 0, FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if( !fSuccess ) {
+ return false;
+ }
+ CloseHandle(hChildStdoutRd);
+
+ // The steps for redirecting child process's STDIN:
+ // 1. Save current STDIN, to be restored later.
+ // 2. Create anonymous pipe to be STDIN for child process.
+ // 3. Set STDIN of the parent to be the read handle to the
+ // pipe, so it is inherited by the child process.
+ // 4. Create a noninheritable duplicate of the write handle,
+ // and close the inheritable write handle.
+ // Save the handle to the current STDIN.
+ hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
+ // Create a pipe for the child process's STDIN.
+ if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, childStdinBufSize)) {
+ return false;
+ }
+ // Set a read handle to the pipe to be STDIN.
+ if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd)) {
+ return false;
+ }
+ // Duplicate the write handle to the pipe so it is not inherited.
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
+ GetCurrentProcess(), &hChildStdinWrDup, 0,
+ FALSE, // not inherited
+ DUPLICATE_SAME_ACCESS);
+ if (! fSuccess) {
+ return false;
+ }
+ CloseHandle(hChildStdinWr);
+
+ // Create the child process
+ char cmdLine[256];
+ sprintf(cmdLine, "SwDbgSub.exe %u", pidToDebug);
+ PROCESS_INFORMATION procInfo;
+ STARTUPINFO startInfo;
+ memset((char*) &startInfo, 0, sizeof(startInfo));
+ startInfo.cb = sizeof(startInfo);
+ BOOL res = CreateProcess(NULL,
+ cmdLine,
+ NULL,
+ NULL,
+ TRUE, // inherit handles: important
+ 0,
+ NULL,
+ NULL,
+ &startInfo,
+ &procInfo);
+ if (!res) {
+ return false;
+ }
+ // After process creation, restore the saved STDIN and STDOUT.
+ if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin)) {
+ return false;
+ }
+ if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
+ return false;
+ }
+
+ // hChildStdinWrDup can be used to write to the child's stdin
+ // hChildStdoutRdDup can be used to read from the child's stdout
+
+ // NOTE: example code closes hChildStdoutWr before reading from
+ // hChildStdoutRdDup. "Close the write end of the pipe before
+ // reading from the read end of the pipe"??? Looks like this is
+ // example-specific.
+
+ // Set up return arguments
+ // hChildStdoutRd and hChildStdinWr are already closed at this point
+ *childProcessHandle = procInfo.hProcess;
+ *writeToStdinHandle = hChildStdinWrDup;
+ *readFromStdoutHandle = hChildStdoutRdDup;
+ *auxHandle1 = hChildStdinRd;
+ *auxHandle2 = hChildStdoutWr;
+ return true;
+}
+
+/** Clears the event and writes the message to the child process */
+bool
+sendMessage(ChildInfo* child, Message* message) {
+ DWORD numBytesWritten;
+ if (!WriteFile(child->getWriteToStdinHandle(),
+ message, sizeof(Message), &numBytesWritten, NULL)) {
+ return false;
+ }
+ if (numBytesWritten != sizeof(Message)) {
+ return false;
+ }
+ // Follow up "poke" messages with the raw data
+ if (message->type == Message::POKE) {
+ if (!WriteFile(child->getWriteToStdinHandle(),
+ message->pokeArg.data, message->pokeArg.numBytes, &numBytesWritten, NULL)) {
+ return false;
+ }
+ if (numBytesWritten != message->pokeArg.numBytes) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/** Copies data from child's stdout to the client's IOBuf and sends it
+ along */
+bool
+forwardReplyToClient(ChildInfo* child, ClientInfo* client) {
+ DWORD total = 0;
+ IOBuf::FillState ret;
+
+ do {
+ DWORD temp;
+ ret = client->getIOBuf()->fillFromFileHandle(child->getReadFromStdoutHandle(),
+ &temp);
+ if (ret == IOBuf::DONE || ret == IOBuf::MORE_DATA_PENDING) {
+ if (!client->getIOBuf()->flush()) {
+#ifdef DEBUGGING
+ cerr << "Forward failed because flush failed" << endl;
+#endif
+ return false;
+ }
+ total += temp;
+ }
+ } while (ret == IOBuf::MORE_DATA_PENDING);
+
+ return (ret == IOBuf::FAILED) ? false : true;
+}
+
+//----------------------------------------------------------------------
+// Server Handler
+//
+
+class ServerHandler : public Handler {
+public:
+ ServerHandler();
+
+ // Starts up in Unicode mode by default
+ bool getASCII();
+
+ void setIOBuf(IOBuf* ioBuf);
+
+ void procList(char* arg);
+
+ // Must be called before calling one of the routines below
+ void setClientInfo(ClientInfo* info);
+
+ // Indicates to outer loop that exit was called or that an error
+ // occurred and that the client exited.
+ bool exited();
+ // Clears this state
+ void clearExited();
+
+ void ascii(char* arg);
+ void unicode(char* arg);
+ void attach(char* arg);
+ void detach(char* arg);
+ void libInfo(char* arg);
+ void peek(char* arg);
+ void poke(char* arg);
+ void threadList(char* arg);
+ void dupHandle(char* arg);
+ void closeHandle(char* arg);
+ void getContext(char* arg);
+ void setContext(char* arg);
+ void selectorEntry(char* arg);
+ void suspend(char* arg);
+ void resume(char* arg);
+ void pollEvent(char* arg);
+ void continueEvent(char* arg);
+ void exit(char* arg);
+
+ // This is pretty gross. Needed to make the target process know
+ // about clients that have disconnected unexpectedly while attached.
+ friend void shutdownClient(ClientInfo*);
+private:
+ // Writes: charSize numChars
+ // Handles both ASCII and UNICODE modes
+ void writeString(USHORT len, WCHAR* str);
+
+ // Handles only ASCII mode
+ void writeString(USHORT len, char* str);
+
+ ClientInfo* clientInfo;
+ IOBuf* ioBuf;
+ bool _exited;
+ bool _ascii;
+};
+
+static ServerHandler* handler;
+
+ServerHandler::ServerHandler() {
+ _exited = false;
+ _ascii = false;
+ ioBuf = NULL;
+}
+
+bool
+ServerHandler::getASCII() {
+ return _ascii;
+}
+
+void
+ServerHandler::setIOBuf(IOBuf* buf) {
+ ioBuf = buf;
+}
+
+void
+ServerHandler::setClientInfo(ClientInfo* info) {
+ clientInfo = info;
+}
+
+bool
+ServerHandler::exited() {
+ return _exited;
+}
+
+void
+ServerHandler::clearExited() {
+ _exited = false;
+}
+
+void
+ServerHandler::ascii(char* arg) {
+ _ascii = true;
+}
+
+void
+ServerHandler::unicode(char* arg) {
+ _ascii = false;
+}
+
+void
+ServerHandler::procList(char* arg) {
+#ifdef DEBUGGING
+ cerr << "proclist" << endl;
+#endif
+
+ ProcEntryList processes;
+ ::procList(processes);
+
+ ioBuf->writeInt(processes.size());
+
+ for (ProcEntryList::iterator iter = processes.begin();
+ iter != processes.end(); iter++) {
+ ProcEntry& entry = *iter;
+ ioBuf->writeSpace();
+ ioBuf->writeUnsignedInt(entry.getPid());
+ ioBuf->writeSpace();
+ writeString(entry.getNameLength(), entry.getName());
+ }
+
+ ioBuf->writeEOL();
+ ioBuf->flush();
+}
+
+void
+ServerHandler::attach(char* arg) {
+ // If the client is already attached to a process, fail.
+ if (clientInfo->getTarget() != NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get pid
+ DWORD pid;
+ if (!scanUnsignedLong(&arg, &pid)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ // See whether this pid is already forked
+ ListsLocker ll;
+ ChildInfo* childInfo = childList.getChildByPid(pid);
+ if (childInfo != NULL) {
+ // If this child already has a client, return false
+ if (childInfo->getClient() != NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ // Otherwise, can associate this client with this child process
+ childInfo->setClient(clientInfo);
+ clientInfo->setTarget(childInfo);
+
+ // Tell the child we are attaching so it can suspend the target
+ // process
+ Message msg;
+ msg.type = Message::ATTACH;
+ sendMessage(childInfo, &msg);
+
+ ioBuf->writeBoolAsInt(true);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ } else {
+ // Have to fork a new child subprocess
+ HANDLE childProcessHandle;
+ HANDLE writeToStdinHandle;
+ HANDLE readFromStdoutHandle;
+ HANDLE auxHandle1;
+ HANDLE auxHandle2;
+ if (!startChildProcess(pid,
+ 32768,
+ 131072,
+ &childProcessHandle,
+ &writeToStdinHandle,
+ &readFromStdoutHandle,
+ &auxHandle1,
+ &auxHandle2)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ // See whether the child succeeded in attaching to the process
+ char res;
+ DWORD numRead;
+ if (!ReadFile(readFromStdoutHandle,
+ &res,
+ sizeof(char),
+ &numRead,
+ NULL)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ if (!res) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ // OK, success.
+ childInfo = new ChildInfo(pid, childProcessHandle,
+ writeToStdinHandle, readFromStdoutHandle,
+ auxHandle1, auxHandle2);
+ childList.addChild(childInfo);
+ reaper->registerProcess(childProcessHandle, childInfo);
+ // Associate this client with this child process
+ childInfo->setClient(clientInfo);
+ clientInfo->setTarget(childInfo);
+
+ // Tell the child process to actually suspend the target process
+ Message msg;
+ msg.type = Message::ATTACH;
+ sendMessage(childInfo, &msg);
+
+ // Write result to client
+ ioBuf->writeBoolAsInt(true);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+}
+
+void
+ServerHandler::detach(char* arg) {
+ // If the client is not attached, fail.
+ if (clientInfo->getTarget() == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ detachClient(clientInfo);
+
+ ioBuf->writeBoolAsInt(true);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+}
+
+void
+ServerHandler::libInfo(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeInt(0);
+ ioBuf->writeEOL();
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::LIBINFO;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::peek(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeString("B");
+ ioBuf->writeBinChar(0);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get address
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ ioBuf->writeString("B");
+ ioBuf->writeBinChar(0);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get number of bytes
+ DWORD numBytes;
+ if (!scanUnsignedLong(&arg, &numBytes)) {
+ ioBuf->writeString("B");
+ ioBuf->writeBinChar(0);
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::PEEK;
+ msg.peekArg.address = address;
+ msg.peekArg.numBytes = numBytes;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::poke(char* arg) {
+#ifdef DEBUGGING
+ cerr << "ServerHandler::poke" << endl;
+#endif
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get address
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get number of bytes
+ if (!scanAndSkipBinEscapeChar(&arg)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+ DWORD numBytes;
+ if (!scanBinUnsignedLong(&arg, &numBytes)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Raw data is now in "arg"
+ // Send message to child
+ Message msg;
+ msg.type = Message::POKE;
+ msg.pokeArg.address = address;
+ msg.pokeArg.numBytes = numBytes;
+ msg.pokeArg.data = arg;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::threadList(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::THREADLIST;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::dupHandle(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get handle
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::DUPHANDLE;
+ msg.handleArg.handle = (HANDLE) address;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::closeHandle(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ return;
+ }
+
+ // Try to get handle
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::CLOSEHANDLE;
+ msg.handleArg.handle = (HANDLE) address;
+ sendMessage(child, &msg);
+
+ // No reply
+}
+
+void
+ServerHandler::getContext(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get handle
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::GETCONTEXT;
+ msg.handleArg.handle = (HANDLE) address;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::setContext(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get handle
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get context
+ DWORD regs[NUM_REGS_IN_CONTEXT];
+ for (int i = 0; i < NUM_REGS_IN_CONTEXT; i++) {
+ if (!scanAddress(&arg, ®s[i])) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::SETCONTEXT;
+ msg.setContextArg.handle = (HANDLE) address;
+ msg.setContextArg.Eax = regs[0];
+ msg.setContextArg.Ebx = regs[1];
+ msg.setContextArg.Ecx = regs[2];
+ msg.setContextArg.Edx = regs[3];
+ msg.setContextArg.Esi = regs[4];
+ msg.setContextArg.Edi = regs[5];
+ msg.setContextArg.Ebp = regs[6];
+ msg.setContextArg.Esp = regs[7];
+ msg.setContextArg.Eip = regs[8];
+ msg.setContextArg.Ds = regs[9];
+ msg.setContextArg.Es = regs[10];
+ msg.setContextArg.Fs = regs[11];
+ msg.setContextArg.Gs = regs[12];
+ msg.setContextArg.Cs = regs[13];
+ msg.setContextArg.Ss = regs[14];
+ msg.setContextArg.EFlags = regs[15];
+ msg.setContextArg.Dr0 = regs[16];
+ msg.setContextArg.Dr1 = regs[17];
+ msg.setContextArg.Dr2 = regs[18];
+ msg.setContextArg.Dr3 = regs[19];
+ msg.setContextArg.Dr6 = regs[20];
+ msg.setContextArg.Dr7 = regs[21];
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::selectorEntry(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get thread handle
+ DWORD address;
+ if (!scanAddress(&arg, &address)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get selector
+ DWORD selector;
+ if (!scanUnsignedLong(&arg, &selector)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::SELECTORENTRY;
+ msg.selectorArg.handle = (HANDLE) address;
+ msg.selectorArg.selector = selector;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::suspend(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::SUSPEND;
+ sendMessage(child, &msg);
+
+ // No reply
+}
+
+void
+ServerHandler::resume(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::RESUME;
+ sendMessage(child, &msg);
+
+ // No reply
+}
+
+void
+ServerHandler::pollEvent(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::POLLEVENT;
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::continueEvent(char* arg) {
+ ListsLocker ll;
+ ChildInfo* child = clientInfo->getTarget();
+ if (child == NULL) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Try to get bool arg
+ int passEventToClient;
+ if (!scanInt(&arg, &passEventToClient)) {
+ ioBuf->writeBoolAsInt(false);
+ ioBuf->flush();
+ return;
+ }
+
+ // Send message to child
+ Message msg;
+ msg.type = Message::CONTINUEEVENT;
+ msg.boolArg.val = ((passEventToClient != 0) ? true : false);
+ sendMessage(child, &msg);
+
+ // Forward reply to client
+ forwardReplyToClient(child, clientInfo);
+}
+
+void
+ServerHandler::exit(char* arg) {
+ shutdownClient(clientInfo);
+ _exited = true;
+}
+
+void
+ServerHandler::writeString(USHORT len, WCHAR* str) {
+ if (_ascii) {
+ char* cStr = new char[len + 1];
+ sprintf(cStr, "%.*ls", len, str);
+ writeString(len, cStr);
+ delete[] cStr;
+ } else {
+ ioBuf->writeInt(sizeof(unsigned short));
+ ioBuf->writeSpace();
+ ioBuf->writeInt(len);
+ ioBuf->writeSpace();
+ for (int i = 0; i < len; i++) {
+ ioBuf->writeBinUnsignedShort(str[i]);
+ }
+ }
+}
+
+void
+ServerHandler::writeString(USHORT len, char* str) {
+ ioBuf->writeInt(1);
+ ioBuf->writeSpace();
+ ioBuf->writeInt(len);
+ ioBuf->writeSpace();
+ ioBuf->writeString(str);
+}
+
+//
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// Shutdown routines
+//
+
+void
+shutdownChild(ChildInfo* childInfo) {
+ childList.removeChild(childInfo);
+ childInfo->closeAll();
+ if (childInfo->getClient() != NULL) {
+ shutdownClient(childInfo->getClient());
+ }
+ delete childInfo;
+}
+
+void
+detachClient(ClientInfo* info) {
+ ListsLocker ll;
+ // May have been dissociated while not under cover of lock
+ if (info->getTarget() == NULL) {
+ return;
+ }
+
+ // Tell the child that we have detached to let the target process
+ // continue running
+ Message msg;
+ msg.type = Message::DETACH;
+ sendMessage(info->getTarget(), &msg);
+
+ // Dissociate the client and the target
+ info->getTarget()->setClient(NULL);
+ info->setTarget(NULL);
+}
+
+void
+shutdownClient(ClientInfo* clientInfo) {
+#ifdef DEBUGGING
+ cerr << "Shutting down client" << endl;
+#endif
+
+ // If we're connected, inform the target process that we're
+ // disconnecting
+ detachClient(clientInfo);
+
+ // Remove this client from the list and delete it
+ clientList.removeClient(clientInfo);
+ if (clientInfo->getTarget() != NULL) {
+ clientInfo->getTarget()->setClient(NULL);
+ }
+ clientInfo->closeAll();
+ delete clientInfo;
+}
+
+//
+//----------------------------------------------------------------------
+
+
+/** Main dispatcher for client commands. NOTE: do not refer to this
+ clientInfo data structure after calling this routine, as it may be
+ deleted internally. */
+void
+readAndDispatch(ClientInfo* clientInfo) {
+ IOBuf::ReadLineResult res;
+ IOBuf* ioBuf = clientInfo->getIOBuf();
+ unsigned long howMany;
+ ioctlsocket(clientInfo->getDataSocket(), FIONREAD, &howMany);
+ if (howMany == 0) {
+ // Client closed down.
+ shutdownClient(clientInfo);
+ return;
+ }
+ // Read and process as much data as possible
+ do {
+ res = ioBuf->tryReadLine();
+ if (res == IOBuf::RL_ERROR) {
+#ifdef DEBUGGING
+ cerr << "Error while reading line" << endl;
+#endif
+ shutdownClient(clientInfo);
+ return;
+ } else if (res == IOBuf::RL_GOT_DATA) {
+#ifdef DEBUGGING
+ cerr << "Got data: \"" << ioBuf->getLine() << "\"" << endl;
+#endif
+ handler->setIOBuf(ioBuf);
+ handler->setClientInfo(clientInfo);
+ handler->clearExited();
+ Dispatcher::dispatch(ioBuf->getLine(), handler);
+ }
+ } while (res == IOBuf::RL_GOT_DATA && (!handler->exited()));
+#ifdef DEBUGGING
+ cerr << "Exiting readAndDispatch" << endl;
+#endif
+}
+
+int
+main(int argc, char **argv)
+{
+ initWinsock();
+
+ if (isNT4()) {
+ loadPSAPIDLL(); // Will exit if not present
+ }
+
+ SOCKET clientListeningSock = setupListeningSocket(CLIENT_PORT);
+
+ handler = new ServerHandler();
+ Lists::init();
+
+ reaper = new Reaper(&reapCB);
+ if (!reaper->start()) {
+ exit(1);
+ }
+
+ while (true) {
+ // Select on all sockets:
+ // - client listening socket
+ // - sockets for all client connections
+
+ // When one of the client connections closes, close its socket
+ // handles.
+
+ fd_set set;
+ SOCKET maxSock = 0;
+
+ // Set up fd_set
+ {
+ int i;
+ FD_ZERO(&set);
+ FD_SET(clientListeningSock, &set);
+ if (clientListeningSock > maxSock) {
+ maxSock = clientListeningSock;
+ }
+ for (i = 0; i < clientList.size(); i++) {
+ ClientInfo* info = clientList.get(i);
+ if (info->getDataSocket() > maxSock) {
+ maxSock = info->getDataSocket();
+ }
+ FD_SET(info->getDataSocket(), &set);
+ }
+ }
+ struct timeval timeout;
+ timeout.tv_sec = 300; // 5 minutes
+ timeout.tv_usec = 0;
+ int res = select(maxSock, &set, NULL, NULL, &timeout);
+ if (res > 0) {
+
+ ////////////////
+ // New client //
+ ////////////////
+ if (FD_ISSET(clientListeningSock, &set)) {
+ SOCKET fd = acceptFromLocalhost(clientListeningSock);
+ if (fd != INVALID_SOCKET) {
+ // Create new client information object
+ ClientInfo* info = new ClientInfo(fd);
+ // Add to list of clients
+ clientList.addClient(info);
+#ifdef DEBUGGING
+ cerr << "New client" << endl;
+#endif
+ }
+ }
+
+ ///////////////////////////
+ // Commands from clients //
+ ///////////////////////////
+ ClientInfo* clientInfo;
+ if (clientList.isAnyDataSocketSet(&set, &clientInfo)) {
+ readAndDispatch(clientInfo);
+ }
+ } else if (res < 0) {
+ // Looks like one of the clients was killed. Try to figure out which one.
+ bool found = false;
+ fd_set set;
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ for (int i = 0; i < clientList.size(); i++) {
+ ClientInfo* info = clientList.get(i);
+ FD_ZERO(&set);
+ FD_SET(info->getDataSocket(), &set);
+ if (select(1 + info->getDataSocket(), &set, NULL, NULL, &timeout) < 0) {
+ found = true;
+ clientList.removeClient(info);
+ info->closeAll();
+ delete info;
+ break;
+ }
+ }
+ if (!found) {
+ // This indicates trouble -- one of our listening sockets died.
+ exit(1);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/hotspot/agent/src/os/win32/SwDbgSrv.dsp b/hotspot/agent/src/os/win32/SwDbgSrv.dsp
new file mode 100644
index 00000000000..4257278704c
--- /dev/null
+++ b/hotspot/agent/src/os/win32/SwDbgSrv.dsp
@@ -0,0 +1,146 @@
+# Microsoft Developer Studio Project File - Name="SwDbgSrv" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=SwDbgSrv - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "SwDbgSrv.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "SwDbgSrv.mak" CFG="SwDbgSrv - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "SwDbgSrv - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "SwDbgSrv - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "SwDbgSrv - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "SwDbgSrv - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "SwDbgSrv___Win32_Debug"
+# PROP BASE Intermediate_Dir "SwDbgSrv___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "SwDbgSrv - Win32 Release"
+# Name "SwDbgSrv - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Buffer.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Dispatcher.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\initWinsock.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IOBuf.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ioUtils.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\isNT4.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\nt4internals.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\procList.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Reaper.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\serverLists.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\SwDbgSrv.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\toolHelp.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/hotspot/agent/src/os/win32/SwDbgSrv.dsw b/hotspot/agent/src/os/win32/SwDbgSrv.dsw
new file mode 100644
index 00000000000..a1570e459c3
--- /dev/null
+++ b/hotspot/agent/src/os/win32/SwDbgSrv.dsw
@@ -0,0 +1,41 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "SwDbgSrv"=.\SwDbgSrv.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "SwDbgSub"=.\SwDbgSub.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/hotspot/agent/src/os/win32/SwDbgSub.cpp b/hotspot/agent/src/os/win32/SwDbgSub.cpp
new file mode 100644
index 00000000000..c8ef813e368
--- /dev/null
+++ b/hotspot/agent/src/os/win32/SwDbgSub.cpp
@@ -0,0 +1,883 @@
+/*
+ * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+// This is the source code for the subprocess forked by the Simple
+// Windows Debug Server. It assumes most of the responsibility for the
+// debug session, and processes all of the commands sent by clients.
+
+// Disable too-long symbol warnings
+#pragma warning ( disable : 4786 )
+
+#include
+#include
+#include
+#include
+// Must come before windows.h
+#include