8275128: Build hsdis using normal build system
Reviewed-by: erikj
This commit is contained in:
parent
124f82377b
commit
03c2b73e21
118
make/Hsdis.gmk
Normal file
118
make/Hsdis.gmk
Normal file
@ -0,0 +1,118 @@
|
||||
#
|
||||
# Copyright (c) 2020, 2021, Oracle and/or its affiliates. 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. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
default: all
|
||||
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
include JdkNativeCompilation.gmk
|
||||
|
||||
################################################################################
|
||||
# This makefile compiles and installs the hsdis library
|
||||
#
|
||||
################################################################################
|
||||
|
||||
HSDIS_OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/hsdis
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
INSTALLED_HSDIS_DIR := $(JDK_OUTPUTDIR)/bin
|
||||
|
||||
# On windows, we need to "fake" a completely different toolchain using gcc
|
||||
# instead of the normal microsoft toolchain. This is quite hacky...
|
||||
|
||||
MINGW_BASE := x86_64-w64-mingw32
|
||||
|
||||
$(eval $(call DefineNativeToolchain, TOOLCHAIN_MINGW, \
|
||||
CC := $(MINGW_BASE)-gcc, \
|
||||
LD := $(MINGW_BASE)-ld, \
|
||||
OBJCOPY := $(MINGW_BASE)-objcopy, \
|
||||
RC := $(RC), \
|
||||
SYSROOT_CFLAGS := --sysroot=/usr/$(MINGW_BASE)/sys-root, \
|
||||
SYSROOT_LDFLAGS := --sysroot=/usr/$(MINGW_BASE)/sys-root, \
|
||||
))
|
||||
|
||||
TOOLCHAIN_TYPE := gcc
|
||||
OPENJDK_TARGET_OS := linux
|
||||
CC_OUT_OPTION := -o$(SPACE)
|
||||
LD_OUT_OPTION := -o$(SPACE)
|
||||
GENDEPS_FLAGS := -MMD -MF
|
||||
CFLAGS_DEBUG_SYMBOLS := -g
|
||||
DISABLED_WARNINGS :=
|
||||
DISABLE_WARNING_PREFIX := -Wno-
|
||||
CFLAGS_WARNINGS_ARE_ERRORS := -Werror
|
||||
SHARED_LIBRARY_FLAGS := -shared
|
||||
|
||||
HSDIS_TOOLCHAIN := TOOLCHAIN_MINGW
|
||||
HSDIS_TOOLCHAIN_CFLAGS :=
|
||||
HSDIS_TOOLCHAIN_LDFLAGS := -L/usr/lib/gcc/$(MINGW_BASE)/9.2.0 \
|
||||
-L/usr/$(MINGW_BASE)/sys-root/mingw/lib
|
||||
MINGW_DLLCRT := /usr/$(MINGW_BASE)/sys-root/mingw/lib/dllcrt2.o
|
||||
HSDIS_TOOLCHAIN_LIBS := $(MINGW_DLLCRT) -lmingw32 -lgcc -lgcc_eh -lmoldname \
|
||||
-lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32
|
||||
else
|
||||
INSTALLED_HSDIS_DIR := $(JDK_OUTPUTDIR)/lib
|
||||
|
||||
HSDIS_TOOLCHAIN := TOOLCHAIN_DEFAULT
|
||||
HSDIS_TOOLCHAIN_CFLAGS := $(CFLAGS_JDKLIB)
|
||||
HSDIS_TOOLCHAIN_LDFLAGS := $(LDFLAGS_JDKLIB)
|
||||
HSDIS_TOOLCHAIN_LIBS := -ldl
|
||||
endif
|
||||
|
||||
|
||||
$(eval $(call SetupJdkLibrary, BUILD_HSDIS, \
|
||||
NAME := hsdis, \
|
||||
SRC := $(TOPDIR)/src/utils/hsdis, \
|
||||
TOOLCHAIN := $(HSDIS_TOOLCHAIN), \
|
||||
OUTPUT_DIR := $(HSDIS_OUTPUT_DIR), \
|
||||
OBJECT_DIR := $(HSDIS_OUTPUT_DIR), \
|
||||
DISABLED_WARNINGS_gcc := undef format-nonliteral sign-compare, \
|
||||
DISABLED_WARNINGS_clang := undef format-nonliteral, \
|
||||
CFLAGS := $(HSDIS_TOOLCHAIN_CFLAGS) $(HSDIS_CFLAGS), \
|
||||
LDFLAGS := $(HSDIS_TOOLCHAIN_LDFLAGS) $(SHARED_LIBRARY_FLAGS), \
|
||||
LIBS := $(HSDIS_LIBS) $(HSDIS_TOOLCHAIN_LIBS), \
|
||||
))
|
||||
|
||||
build: $(BUILD_HSDIS)
|
||||
|
||||
TARGETS += build
|
||||
|
||||
INSTALLED_HSDIS_NAME := hsdis-$(OPENJDK_TARGET_CPU_LEGACY_LIB)$(SHARED_LIBRARY_SUFFIX)
|
||||
|
||||
INSTALLED_HSDIS := $(INSTALLED_HSDIS_DIR)/$(INSTALLED_HSDIS_NAME)
|
||||
|
||||
$(INSTALLED_HSDIS): $(BUILD_HSDIS_TARGET)
|
||||
$(call LogWarn, NOTE: The resulting build might not be redistributable. Seek legal advice before distibuting.)
|
||||
$(install-file)
|
||||
|
||||
|
||||
install: $(INSTALLED_HSDIS)
|
||||
|
||||
TARGETS += install
|
||||
|
||||
################################################################################
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
.PHONY: all default build install
|
@ -526,6 +526,18 @@ $(eval $(call SetupTarget, update-x11wrappers, \
|
||||
DEPS := java.base-copy buildtools-jdk, \
|
||||
))
|
||||
|
||||
ifneq ($(HSDIS_BACKEND), none)
|
||||
$(eval $(call SetupTarget, build-hsdis, \
|
||||
MAKEFILE := Hsdis, \
|
||||
TARGET := build, \
|
||||
))
|
||||
|
||||
$(eval $(call SetupTarget, install-hsdis, \
|
||||
MAKEFILE := Hsdis, \
|
||||
TARGET := install, \
|
||||
))
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Cross compilation support
|
||||
|
||||
|
@ -249,6 +249,7 @@ JDKOPT_EXCLUDE_TRANSLATIONS
|
||||
JDKOPT_ENABLE_DISABLE_MANPAGES
|
||||
JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE
|
||||
JDKOPT_ENABLE_DISABLE_COMPATIBLE_CDS_ALIGNMENT
|
||||
JDKOPT_SETUP_HSDIS
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
|
@ -80,6 +80,14 @@ cygwin_help() {
|
||||
PKGHANDLER_COMMAND="( cd <location of cygwin setup.exe> && cmd /c setup -q -P make )"
|
||||
HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
|
||||
;;
|
||||
i686-w64-mingw32-gcc)
|
||||
PKGHANDLER_COMMAND="( cd <location of cygwin setup.exe> && cmd /c setup -q -P gcc-core i686-w64-mingw32-gcc-core mingw64-i686-glib2.0 )"
|
||||
HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
|
||||
;;
|
||||
x86_64-w64-mingw32-gcc)
|
||||
PKGHANDLER_COMMAND="( cd <location of cygwin setup.exe> && cmd /c setup -q -P gcc-core x86_64-w64-mingw32-gcc-core mingw64-x86_64-glib2.0 )"
|
||||
HELP_MSG="You might be able to fix this by running '$PKGHANDLER_COMMAND'."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
@ -704,3 +704,145 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_REPRODUCIBLE_BUILD],
|
||||
AC_SUBST(SOURCE_DATE)
|
||||
AC_SUBST(ENABLE_REPRODUCIBLE_BUILD)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Helper function to build binutils from source.
|
||||
#
|
||||
AC_DEFUN([JDKOPT_BUILD_BINUTILS],
|
||||
[
|
||||
BINUTILS_SRC="$with_binutils_src"
|
||||
UTIL_FIXUP_PATH(BINUTILS_SRC)
|
||||
|
||||
if ! test -d $BINUTILS_SRC; then
|
||||
AC_MSG_ERROR([--with-binutils-src is not pointing to a directory])
|
||||
fi
|
||||
if ! test -x $BINUTILS_SRC/configure; then
|
||||
AC_MSG_ERROR([--with-binutils-src does not look like a binutils source directory])
|
||||
fi
|
||||
|
||||
if test -e $BINUTILS_SRC/bfd/libbfd.a && \
|
||||
test -e $BINUTILS_SRC/opcodes/libopcodes.a && \
|
||||
test -e $BINUTILS_SRC/libiberty/libiberty.a && \
|
||||
test -e $BINUTILS_SRC/zlib/libz.a; then
|
||||
AC_MSG_NOTICE([Found binutils binaries in binutils source directory -- not building])
|
||||
else
|
||||
# On Windows, we cannot build with the normal Microsoft CL, but must instead use
|
||||
# a separate mingw toolchain.
|
||||
if test "x$OPENJDK_BUILD_OS" = xwindows; then
|
||||
if test "x$OPENJDK_TARGET_CPU" = "xx86"; then
|
||||
target_base="i686-w64-mingw32"
|
||||
else
|
||||
target_base="$OPENJDK_TARGET_CPU-w64-mingw32"
|
||||
fi
|
||||
binutils_cc="$target_base-gcc"
|
||||
binutils_target="--host=$target_base --target=$target_base"
|
||||
# Somehow the uint typedef is not included when building with mingw
|
||||
binutils_cflags="-Duint=unsigned"
|
||||
compiler_version=`$binutils_cc --version 2>&1`
|
||||
if ! [ [[ "$compiler_version" =~ GCC ]] ]; then
|
||||
AC_MSG_NOTICE([Could not find correct mingw compiler $binutils_cc.])
|
||||
HELP_MSG_MISSING_DEPENDENCY([$binutils_cc])
|
||||
AC_MSG_ERROR([Cannot continue. $HELP_MSG])
|
||||
else
|
||||
AC_MSG_NOTICE([Using compiler $binutils_cc with version $compiler_version])
|
||||
fi
|
||||
elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
|
||||
if test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then
|
||||
binutils_target="--enable-targets=aarch64-darwin"
|
||||
else
|
||||
binutils_target=""
|
||||
fi
|
||||
else
|
||||
binutils_cc="$CC $SYSROOT_CFLAGS"
|
||||
binutils_target=""
|
||||
fi
|
||||
binutils_cflags="$binutils_cflags $MACHINE_FLAG $JVM_PICFLAG $C_O_FLAG_NORM"
|
||||
|
||||
AC_MSG_NOTICE([Running binutils configure])
|
||||
AC_MSG_NOTICE([configure command line: ./configure --disable-nls CFLAGS="$binutils_cflags" CC="$binutils_cc" $binutils_target])
|
||||
saved_dir=`pwd`
|
||||
cd "$BINUTILS_SRC"
|
||||
./configure --disable-nls CFLAGS="$binutils_cflags" CC="$binutils_cc" $binutils_target
|
||||
if test $? -ne 0 || ! test -e $BINUTILS_SRC/Makefile; then
|
||||
AC_MSG_NOTICE([Automatic building of binutils failed on configure. Try building it manually])
|
||||
AC_MSG_ERROR([Cannot continue])
|
||||
fi
|
||||
AC_MSG_NOTICE([Running binutils make])
|
||||
$MAKE all-opcodes
|
||||
if test $? -ne 0; then
|
||||
AC_MSG_NOTICE([Automatic building of binutils failed on make. Try building it manually])
|
||||
AC_MSG_ERROR([Cannot continue])
|
||||
fi
|
||||
cd $saved_dir
|
||||
AC_MSG_NOTICE([Building of binutils done])
|
||||
fi
|
||||
|
||||
BINUTILS_DIR="$BINUTILS_SRC"
|
||||
])
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Determine if hsdis should be built, and if so, with which backend.
|
||||
#
|
||||
AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS],
|
||||
[
|
||||
AC_ARG_WITH([hsdis], [AS_HELP_STRING([--with-hsdis],
|
||||
[what hsdis backend to use ('none', 'binutils') @<:@none@:>@])])
|
||||
|
||||
AC_ARG_WITH([binutils], [AS_HELP_STRING([--with-binutils],
|
||||
[where to find the binutils files needed for hsdis/binutils])])
|
||||
|
||||
AC_ARG_WITH([binutils-src], [AS_HELP_STRING([--with-binutils-src],
|
||||
[where to find the binutils source for building])])
|
||||
|
||||
AC_MSG_CHECKING([what hsdis backend to use])
|
||||
|
||||
if test "x$with_hsdis" = xyes; then
|
||||
AC_MSG_ERROR([--with-hsdis must have a value])
|
||||
elif test "x$with_hsdis" = xnone || test "x$with_hsdis" = xno || test "x$with_hsdis" = x; then
|
||||
HSDIS_BACKEND=none
|
||||
AC_MSG_RESULT(['none', hsdis will not be built])
|
||||
elif test "x$with_hsdis" = xbinutils; then
|
||||
HSDIS_BACKEND=binutils
|
||||
AC_MSG_RESULT(['binutils'])
|
||||
|
||||
# We need the binutils static libs and includes.
|
||||
if test "x$with_binutils_src" != x; then
|
||||
# Try building the source first. If it succeeds, it sets $BINUTILS_DIR.
|
||||
JDKOPT_BUILD_BINUTILS
|
||||
fi
|
||||
|
||||
if test "x$with_binutils" != x; then
|
||||
BINUTILS_DIR="$with_binutils"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for binutils to use with hsdis])
|
||||
if test "x$BINUTILS_DIR" != x; then
|
||||
if test -e $BINUTILS_DIR/bfd/libbfd.a && \
|
||||
test -e $BINUTILS_DIR/opcodes/libopcodes.a && \
|
||||
test -e $BINUTILS_DIR/libiberty/libiberty.a; then
|
||||
AC_MSG_RESULT([$BINUTILS_DIR])
|
||||
HSDIS_CFLAGS="-I$BINUTILS_DIR/include -I$BINUTILS_DIR/bfd -DLIBARCH_$OPENJDK_TARGET_CPU_LEGACY_LIB"
|
||||
HSDIS_LIBS="$BINUTILS_DIR/bfd/libbfd.a $BINUTILS_DIR/opcodes/libopcodes.a $BINUTILS_DIR/libiberty/libiberty.a $BINUTILS_DIR/zlib/libz.a"
|
||||
else
|
||||
AC_MSG_RESULT([invalid])
|
||||
AC_MSG_ERROR([$BINUTILS_DIR does not contain a proper binutils installation])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([missing])
|
||||
AC_MSG_NOTICE([--with-hsdis=binutils requires specifying a binutils installation.])
|
||||
AC_MSG_NOTICE([Download binutils from https://www.gnu.org/software/binutils and unpack it,])
|
||||
AC_MSG_NOTICE([and point --with-binutils-src to the resulting directory, or use])
|
||||
AC_MSG_NOTICE([--with-binutils to point to a pre-built binutils installation.])
|
||||
AC_MSG_ERROR([Cannot continue])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([invalid])
|
||||
AC_MSG_ERROR([Incorrect hsdis backend "$with_hsdis"])
|
||||
fi
|
||||
|
||||
AC_SUBST(HSDIS_BACKEND)
|
||||
AC_SUBST(HSDIS_CFLAGS)
|
||||
AC_SUBST(HSDIS_LIBS)
|
||||
])
|
||||
|
@ -359,6 +359,10 @@ ENABLE_COMPATIBLE_CDS_ALIGNMENT := @ENABLE_COMPATIBLE_CDS_ALIGNMENT@
|
||||
|
||||
ALLOW_ABSOLUTE_PATHS_IN_OUTPUT := @ALLOW_ABSOLUTE_PATHS_IN_OUTPUT@
|
||||
|
||||
HSDIS_BACKEND := @HSDIS_BACKEND@
|
||||
HSDIS_CFLAGS := @HSDIS_CFLAGS@
|
||||
HSDIS_LIBS := @HSDIS_LIBS@
|
||||
|
||||
# The boot jdk to use. This is overridden in bootcycle-spec.gmk. Make sure to keep
|
||||
# it in sync.
|
||||
BOOT_JDK:=@BOOT_JDK@
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
|
||||
The Universal Permissive License (UPL), Version 1.0
|
||||
@ -43,102 +43,56 @@ questions.
|
||||
|
||||
________________________________________________________________________
|
||||
|
||||
'hsdis': A HotSpot plugin for disassembling dynamically generated code.
|
||||
'hsdis': A HotSpot plugin for disassembling dynamically generated code.
|
||||
|
||||
The files in this directory (Makefile, hsdis.[ch], hsdis-demo.c)
|
||||
are built independently of the HotSpot JVM.
|
||||
|
||||
To use the plugin with a JVM, you need a new version that can load it.
|
||||
If the product mode of your JVM does not accept -XX:+PrintAssembly,
|
||||
you do not have a version that is new enough.
|
||||
The files in this directory are built independently of the HotSpot JVM.
|
||||
|
||||
* Building
|
||||
|
||||
To build this project you need a copy of GNU binutils to build against.
|
||||
It is known to work with binutils 2.29.1, 2.30, and 2.31.1. Building
|
||||
against versions older than 2.29 is no longer supported. Download a
|
||||
copy of the software from http://directory.fsf.org/project/binutils or
|
||||
one of its mirrors. Builds targetting windows currently require the
|
||||
use of a cross compiler.
|
||||
To build this project you need a copy of GNU binutils to build against. It is
|
||||
known to work with binutils 2.37. Building against versions older than 2.29 is
|
||||
not supported. Download a copy of the software from
|
||||
http://directory.fsf.org/project/binutils or one of its mirrors.
|
||||
|
||||
Binutils should be configured with the '--disable-nls' flag to disable
|
||||
Native Language Support, otherwise you might get an "undefined
|
||||
reference to `libintl_gettext'" if you try to load hsdis.so on systems
|
||||
which don't have NLS by default. It also avoids build problems on
|
||||
other configurations that don't include the full NLS support.
|
||||
To build this library, you must enable building in configure by "bash configure
|
||||
--with-hsdis=binutils".
|
||||
|
||||
The makefile looks for the sources in build/binutils or you can
|
||||
specify its location to the makefile using BINUTILS=path. It will
|
||||
configure binutils and build it first and then build and link the
|
||||
disassembly adapter. Make all will build the default target for your
|
||||
platform. If your platform supports both 32 and 64 simultaneously then
|
||||
"make both" will build them both at once. "make all64" will
|
||||
explicitly build the 64 bit version. By default this will build the
|
||||
disassembler library only. If you build demo it will build a demo
|
||||
program that attempts to exercise the library.
|
||||
You must also specify where binutils is located. To facilitate building, you can
|
||||
point to a place where the (unpacked) binutils sources are located using
|
||||
"--with-binutils-src=<location>", and configure will build binutils for you. On
|
||||
repeated runs, you can keep this command line option, since configure will
|
||||
figure out that the binutils binaries are already present and skip building, or
|
||||
you can replace it with "--with-binutils=<location>".
|
||||
|
||||
With recent version of binutils (i.e. binutils-2.23.2) you may get the
|
||||
following build error:
|
||||
If you have pre-built binutils binaries, you can point to them directly using
|
||||
"--with-binutils=<location>".
|
||||
|
||||
WARNING: `makeinfo' is missing on your system. You should only need it if
|
||||
you modified a `.texi' or `.texinfo' file, or any other file
|
||||
...
|
||||
When you have created a proper configuration, you can then build the hsdis
|
||||
library using "make build-hsdis".
|
||||
|
||||
This is because of "Bug 15345 - binutils-2.23.2 tarball doesn't build
|
||||
without makeinfo" [2]. The easiest way to work around this problem is
|
||||
by doing a "touch $BINUTILS/bfd/doc/bfd.info".
|
||||
* Building on Windows
|
||||
|
||||
Windows
|
||||
|
||||
In theory this should be buildable on Windows but getting a working
|
||||
GNU build environment on Windows has proven difficult. MINGW should
|
||||
be able to do it but at the time of this writing I was unable to get
|
||||
this working. Instead you can use the mingw cross compiler on linux
|
||||
to produce the windows binaries. For 32-bit windows you can install
|
||||
mingw32 using your package manager and it will be added to your path
|
||||
automatically. For 64-bit you need to download the 64 bit mingw from
|
||||
http://sourceforge.net/projects/mingw-w64. Grab a copy of the
|
||||
complete toolchain and unpack it somewhere. Put the bin directory of
|
||||
the toolchain in your path. The mingw installs contain cross compile
|
||||
versions of gcc that are named with a prefix to indicate what they are
|
||||
targeting and you must tell the Makefile which one to use. This
|
||||
should either be i586-mingw32msvc or x86_64-pc-mingw32 depending on
|
||||
which one you are targeting and there should be a version of gcc in
|
||||
your path named i586-mingw32msvc-gcc or x86_64-pc-mingw32-gcc. Tell
|
||||
the makefile what prefix to use to find the mingw tools by using
|
||||
MINGW=. For example:
|
||||
|
||||
make MINGW=i586-mingw32msvc BINUTILS=build/binutils-2.31.1
|
||||
|
||||
will build the Win32 cross compiled version of hsdis based on 2.31.1.
|
||||
On Windows, the normal Microsoft Visual Studio toolchain cannot build binutils.
|
||||
Instead we need to use the mingw compiler. This is available as a cygwin
|
||||
package. You need to install the "gcc-core" and "mingw64-x86_64-gcc-core"
|
||||
packages (or "mingw64-i686-gcc-core", if you want the 32-bit version) and
|
||||
"mingw64-x86_64-glib2.0".
|
||||
|
||||
* Installing
|
||||
|
||||
Products are named like build/$OS-$LIBARCH/hsdis-$LIBARCH.so. You can
|
||||
install them next to your libjvm.so inside your JRE/JDK or alternatively
|
||||
put it anywhere on your LD_LIBRARY_PATH. The search path in the JVM is:
|
||||
To build the hsdis library, run "make build-hsdis". This will build the library
|
||||
in a separate directory, but not make it available to the JDK in the
|
||||
configuration. To actually install it in the JDK, run "make install-hsdis".
|
||||
|
||||
1. <home>/lib/<vm>/libhsdis-<arch>.so
|
||||
2. <home>/lib/<vm>/hsdis-<arch>.so
|
||||
3. <home>/lib/hsdis-<arch>.so
|
||||
4. hsdis-<arch>.so (using LD_LIBRARY_PATH)
|
||||
Note: The resulting build may not be distributable. Please get legal advice if
|
||||
you intend to distribute the result of your build.
|
||||
|
||||
Now test:
|
||||
* Using the library
|
||||
|
||||
export LD_LIBRARY_PATH .../hsdis/build/$OS-$LIBARCH:$LD_LIBRARY_PATH
|
||||
dargs='-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly'
|
||||
dargs=$dargs' -XX:PrintAssemblyOptions=hsdis-print-bytes'
|
||||
java $dargs -Xbatch CompileCommand=print,*String.hashCode HelloWorld
|
||||
The hsdis library will be automatically loaded by Hotspot when you use the
|
||||
diagnostic option "-XX:+PrintAssembly". Note that since this is a diagnostic
|
||||
option, you need to unlock these first, so in practice you activate it using
|
||||
"-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly".
|
||||
|
||||
If the product mode of the JVM does not accept -XX:+PrintAssembly,
|
||||
you do not have a version new enough to use the hsdis plugin.
|
||||
|
||||
* Wiki
|
||||
|
||||
More information can be found in the OpenJDK HotSpot Wiki [1].
|
||||
|
||||
|
||||
Resources:
|
||||
|
||||
[1] https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly
|
||||
[2] http://sourceware.org/bugzilla/show_bug.cgi?id=15345
|
||||
More information is available at the wiki
|
||||
[https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly].
|
||||
|
@ -1,281 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* The Universal Permissive License (UPL), Version 1.0
|
||||
*
|
||||
* Subject to the condition set forth below, permission is hereby granted to
|
||||
* any person obtaining a copy of this software, associated documentation
|
||||
* and/or data (collectively the "Software"), free of charge and under any
|
||||
* and all copyright rights in the Software, and any and all patent rights
|
||||
* owned or freely licensable by each licensor hereunder covering either (i)
|
||||
* the unmodified Software as contributed to or provided by such licensor,
|
||||
* or (ii) the Larger Works (as defined below), to deal in both
|
||||
*
|
||||
* (a) the Software, and
|
||||
*
|
||||
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file
|
||||
* if one is included with the Software (each a "Larger Work" to which the
|
||||
* Software is contributed by such licensors),
|
||||
*
|
||||
* without restriction, including without limitation the rights to copy,
|
||||
* create derivative works of, display, perform, and distribute the Software
|
||||
* and make, use, sell, offer for sale, import, export, have made, and have
|
||||
* sold the Software and the Larger Work(s), and to sublicense the foregoing
|
||||
* rights on either these or other terms.
|
||||
*
|
||||
* This license is subject to the following condition:
|
||||
*
|
||||
* The above copyright notice and either this complete permission notice or
|
||||
* at a minimum a reference to the UPL must 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.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/* hsdis-demo.c -- dump a range of addresses as native instructions
|
||||
This demonstrates the protocol required by the HotSpot PrintAssembly option.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "hsdis.h"
|
||||
|
||||
|
||||
void greet(const char*);
|
||||
void disassemble(uintptr_t, uintptr_t);
|
||||
void end_of_file();
|
||||
|
||||
const char* options = NULL;
|
||||
int raw = 0;
|
||||
int xml = 0;
|
||||
|
||||
int main(int ac, char** av) {
|
||||
int greeted = 0;
|
||||
int i;
|
||||
for (i = 1; i < ac; i++) {
|
||||
const char* arg = av[i];
|
||||
if (arg[0] == '-') {
|
||||
if (!strcmp(arg, "-xml"))
|
||||
xml ^= 1;
|
||||
else if (!strcmp(arg, "-raw"))
|
||||
raw ^= 1;
|
||||
else if (!strncmp(arg, "-options=", 9))
|
||||
options = arg+9;
|
||||
else
|
||||
{ printf("Usage: %s [-xml] [name...]\n", av[0]); exit(2); }
|
||||
continue;
|
||||
}
|
||||
greet(arg);
|
||||
greeted = 1;
|
||||
}
|
||||
if (!greeted)
|
||||
greet("world");
|
||||
printf("...And now for something completely different:\n");
|
||||
void *start = (void*) &main;
|
||||
void *end = (void*) &end_of_file;
|
||||
#if defined(__ia64) || (defined(__powerpc__) && !defined(ABI_ELFv2))
|
||||
/* On IA64 and PPC function pointers are pointers to function descriptors */
|
||||
start = *((void**)start);
|
||||
end = *((void**)end);
|
||||
#endif
|
||||
disassemble(start, (end > start) ? end : start + 64);
|
||||
printf("Cheers!\n");
|
||||
}
|
||||
|
||||
void greet(const char* whom) {
|
||||
printf("Hello, %s!\n", whom);
|
||||
}
|
||||
|
||||
void end_of_file() { }
|
||||
|
||||
/* don't disassemble after this point... */
|
||||
|
||||
#include "dlfcn.h"
|
||||
|
||||
#define DECODE_INSTRUCTIONS_VIRTUAL_NAME "decode_instructions_virtual"
|
||||
#define DECODE_INSTRUCTIONS_NAME "decode_instructions"
|
||||
#define HSDIS_NAME "hsdis"
|
||||
static void* decode_instructions_pv = 0;
|
||||
static void* decode_instructions_sv = 0;
|
||||
static const char* hsdis_path[] = {
|
||||
HSDIS_NAME"-"LIBARCH LIB_EXT,
|
||||
"./" HSDIS_NAME"-"LIBARCH LIB_EXT,
|
||||
#ifdef TARGET_DIR
|
||||
TARGET_DIR"/"HSDIS_NAME"-"LIBARCH LIB_EXT,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char* load_decode_instructions() {
|
||||
void* dllib = NULL;
|
||||
const char* *next_in_path = hsdis_path;
|
||||
while (1) {
|
||||
decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
|
||||
decode_instructions_sv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
|
||||
if (decode_instructions_pv != NULL || decode_instructions_sv != NULL)
|
||||
return NULL;
|
||||
if (dllib != NULL)
|
||||
return "plugin does not defined "DECODE_INSTRUCTIONS_VIRTUAL_NAME" and "DECODE_INSTRUCTIONS_NAME;
|
||||
for (dllib = NULL; dllib == NULL; ) {
|
||||
const char* next_lib = (*next_in_path++);
|
||||
if (next_lib == NULL)
|
||||
return "cannot find plugin "HSDIS_NAME LIB_EXT;
|
||||
dllib = dlopen(next_lib, RTLD_LAZY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char* lookup(void* addr) {
|
||||
#if defined(__ia64) || defined(__powerpc__)
|
||||
/* On IA64 and PPC function pointers are pointers to function descriptors */
|
||||
#define CHECK_NAME(fn) \
|
||||
if (addr == *((void**) &fn)) return #fn;
|
||||
#else
|
||||
#define CHECK_NAME(fn) \
|
||||
if (addr == (void*) &fn) return #fn;
|
||||
#endif
|
||||
|
||||
CHECK_NAME(main);
|
||||
CHECK_NAME(greet);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* does the event match the tag, followed by a null, space, or slash? */
|
||||
#define MATCH(event, tag) \
|
||||
(!strncmp(event, tag, sizeof(tag)-1) && \
|
||||
(!event[sizeof(tag)-1] || strchr(" /", event[sizeof(tag)-1])))
|
||||
|
||||
|
||||
static const char event_cookie[] = "event_cookie"; /* demo placeholder */
|
||||
static void* simple_handle_event(void* cookie, const char* event, void* arg) {
|
||||
if (MATCH(event, "/insn")) {
|
||||
// follow each complete insn by a nice newline
|
||||
printf("\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* handle_event(void* cookie, const char* event, void* arg) {
|
||||
#define NS_DEMO "demo:"
|
||||
if (cookie != event_cookie)
|
||||
printf("*** bad event cookie %p != %p\n", cookie, event_cookie);
|
||||
|
||||
if (xml) {
|
||||
/* We could almost do a printf(event, arg),
|
||||
but for the sake of a better demo,
|
||||
we dress the result up as valid XML.
|
||||
*/
|
||||
const char* fmt = strchr(event, ' ');
|
||||
int evlen = (fmt ? fmt - event : strlen(event));
|
||||
if (!fmt) {
|
||||
if (event[0] != '/') {
|
||||
printf("<"NS_DEMO"%.*s>", evlen, event);
|
||||
} else {
|
||||
printf("</"NS_DEMO"%.*s>", evlen-1, event+1);
|
||||
}
|
||||
} else {
|
||||
if (event[0] != '/') {
|
||||
printf("<"NS_DEMO"%.*s", evlen, event);
|
||||
printf(fmt, arg);
|
||||
printf(">");
|
||||
} else {
|
||||
printf("<"NS_DEMO"%.*s_done", evlen-1, event+1);
|
||||
printf(fmt, arg);
|
||||
printf("/></"NS_DEMO"%.*s>", evlen-1, event+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MATCH(event, "insn")) {
|
||||
const char* name = lookup(arg);
|
||||
if (name) printf("%s:\n", name);
|
||||
|
||||
/* basic action for <insn>: */
|
||||
printf(" %p\t", arg);
|
||||
|
||||
} else if (MATCH(event, "/insn")) {
|
||||
// follow each complete insn by a nice newline
|
||||
printf("\n");
|
||||
} else if (MATCH(event, "mach")) {
|
||||
printf("Decoding for CPU '%s'\n", (char*) arg);
|
||||
|
||||
} else if (MATCH(event, "addr")) {
|
||||
/* basic action for <addr/>: */
|
||||
const char* name = lookup(arg);
|
||||
if (name) {
|
||||
printf("&%s (%p)", name, arg);
|
||||
/* return non-null to notify hsdis not to print the addr */
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
/* null return is always safe; can mean "I ignored it" */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define fprintf_callback \
|
||||
(decode_instructions_printf_callback_ftype)&fprintf
|
||||
|
||||
void disassemble(uintptr_t from, uintptr_t to) {
|
||||
const char* err = load_decode_instructions();
|
||||
if (err != NULL) {
|
||||
printf("%s: %s\n", err, dlerror());
|
||||
exit(1);
|
||||
}
|
||||
decode_func_vtype decode_instructions_v
|
||||
= (decode_func_vtype) decode_instructions_pv;
|
||||
decode_func_stype decode_instructions_s
|
||||
= (decode_func_stype) decode_instructions_sv;
|
||||
void* res;
|
||||
if (decode_instructions_pv != NULL) {
|
||||
printf("\nDecoding from %p to %p...with %s\n", from, to, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
|
||||
if (raw) {
|
||||
res = (*decode_instructions_v)(from, to,
|
||||
(unsigned char*)from, to - from,
|
||||
simple_handle_event, stdout,
|
||||
NULL, stdout,
|
||||
options, 0);
|
||||
} else {
|
||||
res = (*decode_instructions_v)(from, to,
|
||||
(unsigned char*)from, to - from,
|
||||
handle_event, (void*) event_cookie,
|
||||
fprintf_callback, stdout,
|
||||
options, 0);
|
||||
}
|
||||
if (res != (void*)to)
|
||||
printf("*** Result was %p!\n", res);
|
||||
}
|
||||
void* sres;
|
||||
if (decode_instructions_sv != NULL) {
|
||||
printf("\nDecoding from %p to %p...with old decode_instructions\n", from, to, DECODE_INSTRUCTIONS_NAME);
|
||||
if (raw) {
|
||||
sres = (*decode_instructions_s)(from, to,
|
||||
simple_handle_event, stdout,
|
||||
NULL, stdout,
|
||||
options);
|
||||
} else {
|
||||
sres = (*decode_instructions_s)(from, to,
|
||||
handle_event, (void*) event_cookie,
|
||||
fprintf_callback, stdout,
|
||||
options);
|
||||
}
|
||||
if (sres != (void *)to)
|
||||
printf("*** Result of decode_instructions %p!\n", sres);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user