提交 61bf249c 编写于 作者: Y ysr

Merge

上级 89810581 e0146080
master
Tags不可用
无相关合并请求
#!/bin/sh
# If we're cross compiling use that path for nm
if [ "$ALT_COMPILER_PATH" != "" ]; then
if [ "$CROSS_COMPILE_ARCH" != "" ]; then
NM=$ALT_COMPILER_PATH/nm
else
NM=nm
......
......@@ -124,7 +124,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
env.sh env.csh .dbxrc test_gamma
env.sh env.csh jdkpath.sh .dbxrc test_gamma
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
......@@ -318,6 +318,13 @@ env.csh: env.sh
sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
) > $@
jdkpath.sh: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo "JDK=${JAVA_HOME}"; \
) > $@
.dbxrc: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
......
......@@ -25,7 +25,9 @@
#------------------------------------------------------------------------
# CC, CPP & AS
ifdef ALT_COMPILER_PATH
# When cross-compiling the ALT_COMPILER_PATH points
# to the cross-compilation toolset
ifdef CROSS_COMPILE_ARCH
CPP = $(ALT_COMPILER_PATH)/g++
CC = $(ALT_COMPILER_PATH)/gcc
else
......
......@@ -168,7 +168,9 @@ endif
# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
define findsrc
$(notdir $(shell find $(1) \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \) ))
$(notdir $(shell find $(1)/. ! -name . -prune \
-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
endef
Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
......
......@@ -117,7 +117,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make \
env.ksh env.csh .dbxrc test_gamma
env.ksh env.csh jdkpath.sh .dbxrc test_gamma
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
......@@ -314,6 +314,13 @@ env.csh: env.ksh
sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=/setenv \1 /p' $?; \
) > $@
jdkpath.sh: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
$(BUILDTREE_COMMENT); \
echo "JDK=${JAVA_HOME}"; \
) > $@
.dbxrc: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
......
......@@ -106,17 +106,17 @@ ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
# Not sure what the 'designed for' comment is referring too above.
# The order may not be too significant anymore, but I have placed this
# older libm before libCrun, just to make sure it's found and used first.
LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc
LIBS += -lsocket -lsched -ldl $(LIBM) -lCrun -lthread -ldoor -lc -ldemangle
else
ifeq ($(COMPILER_REV_NUMERIC), 502)
# SC6.1 has it's own libm.so: specifying anything else provokes a name conflict.
LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor
LIBS += -ldl -lthread -lsocket -lm -lsched -ldoor -ldemangle
else
LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor
LIBS += -ldl -lthread -lsocket $(LIBM) -lsched -ldoor -ldemangle
endif # 502
endif # 505
else
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
endif # sparcWorks
# By default, link the *.o into the library, not the executable.
......@@ -184,7 +184,9 @@ endif
# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
define findsrc
$(notdir $(shell find $(1) \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \) ))
$(notdir $(shell find $(1)/. ! -name . -prune \
-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
endef
Src_Files := $(foreach e,$(Src_Dirs),$(call findsrc,$(e)))
......
#
# Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2000, 2010, 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
......@@ -45,6 +45,9 @@ fi
echo "EXPORTS" > vm1.def
AWK="$MKS_HOME/awk.exe"
if [ ! -e $AWK ]; then
AWK="$MKS_HOME/gawk.exe"
fi
GREP="$MKS_HOME/grep.exe"
SORT="$MKS_HOME/sort.exe"
UNIQ="$MKS_HOME/uniq.exe"
......@@ -57,7 +60,7 @@ if [ "x$1" != "x" ]; then
LINK_VER="$1"
fi
if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" ]; then
if [ "x$LINK_VER" != "x800" -a "x$LINK_VER" != "x900" -a "x$LINK_VER" != "x1000" ]; then
$DUMPBIN /symbols *.obj | "$GREP" "??_7.*@@6B@" | "$GREP" -v "type_info" | "$AWK" '{print $7}' | "$SORT" | "$UNIQ" > vm2.def
else
# Can't use pipes when calling cl.exe or link.exe from IDE. Using transit file vm3.def
......
......@@ -36,6 +36,20 @@ REM
REM Note: Running this batch file from the Windows command shell requires
REM that "grep" be accessible on the PATH. An MKS install does this.
REM
cl 2>NUL >NUL
if %errorlevel% == 0 goto nexttest
echo Make sure cl.exe is in your PATH before running this script.
goto end
:nexttest
grep -V 2>NUL >NUL
if %errorlevel% == 0 goto testit
echo Make sure grep.exe is in your PATH before running this script. Either cygwin or MKS should work.
goto end
:testit
cl 2>&1 | grep "IA-64" >NUL
if %errorlevel% == 0 goto isia64
cl 2>&1 | grep "AMD64" >NUL
......@@ -44,37 +58,40 @@ set ARCH=x86
set BUILDARCH=i486
set Platform_arch=x86
set Platform_arch_model=x86_32
goto end
goto done
:amd64
set ARCH=x86
set BUILDARCH=amd64
set Platform_arch=x86
set Platform_arch_model=x86_64
goto end
goto done
:isia64
set ARCH=ia64
set BUILDARCH=ia64
set Platform_arch=ia64
set Platform_arch_model=ia64
:end
:done
setlocal
if "%1" == "" goto usage
if not "%4" == "" goto usage
if not "%2" == "" goto usage
REM Set HotSpotWorkSpace to the directy two steps above this script
for %%i in ("%~dp0..") do ( set HotSpotWorkSpace=%%~dpi)
set HotSpotBuildRoot=%HotSpotWorkSpace%build
set HotSpotBuildSpace=%HotSpotBuildRoot%\vs
set HotSpotJDKDist=%1
set HotSpotWorkSpace=%1
set HotSpotBuildSpace=%2
set HotSpotJDKDist=%3
REM figure out MSC version
for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
echo **************************************************************
set ProjectFile=vm.vcproj
set ProjectFile=jvm.vcproj
if "%MSC_VER%" == "1200" (
set ProjectFile=vm.dsp
set ProjectFile=jvm.dsp
echo Will generate VC6 project {unsupported}
) else (
if "%MSC_VER%" == "1400" (
......@@ -83,10 +100,16 @@ echo Will generate VC8 {Visual Studio 2005}
if "%MSC_VER%" == "1500" (
echo Will generate VC9 {Visual Studio 2008}
) else (
if "%MSC_VER%" == "1600" (
echo Detected Visual Studio 2010, but
echo will generate VC9 {Visual Studio 2008}
echo Use conversion wizard in VS 2010.
) else (
echo Will generate VC7 project {Visual Studio 2003 .NET}
)
)
)
)
echo %ProjectFile%
echo **************************************************************
......@@ -118,6 +141,8 @@ goto usage
:test3
if not "%HOTSPOTMKSHOME%" == "" goto makedir
if exist c:\cygwin\bin set HOTSPOTMKSHOME=c:\cygwin\bin
if not "%HOTSPOTMKSHOME%" == "" goto makedir
echo Warning: please set variable HOTSPOTMKSHOME to place where
echo your MKS/Cygwin installation is
echo.
......@@ -133,21 +158,24 @@ echo HotSpotJDKDist=%HotSpotJDKDist%
REM This is now safe to do.
:copyfiles
for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
if NOT EXIST %HotSpotBuildSpace%\%%i mkdir %HotSpotBuildSpace%\%%i
copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\ > NUL
if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated
copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL
)
REM force regneration of ProjectFile
if exist %HotSpotBuildSpace%\%ProjectFile% del %HotSpotBuildSpace%\%ProjectFile%
for /D %%i in (compiler1, compiler2, tiered, core, kernel) do (
echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make
echo -- %%i --
echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make
echo # Changing a variable below and then deleting %ProjectFile% will cause >> %HotSpotBuildSpace%\%%i\local.make
echo # %ProjectFile% to be regenerated with the new values. Changing the >> %HotSpotBuildSpace%\%%i\local.make
echo # version requires rerunning create.bat. >> %HotSpotBuildSpace%\%%i\local.make
echo # version requires rerunning create.bat. >> %HotSpotBuildSpace%\%%i\local.make
echo. >> %HotSpotBuildSpace%\%%i\local.make
echo Variant=%%i >> %HotSpotBuildSpace%\%%i\local.make
echo WorkSpace=%HotSpotWorkSpace% >> %HotSpotBuildSpace%\%%i\local.make
echo HOTSPOTWORKSPACE=%HotSpotWorkSpace% >> %HotSpotBuildSpace%\%%i\local.make
echo HOTSPOTBUILDROOT=%HotSpotBuildRoot% >> %HotSpotBuildSpace%\%%i\local.make
echo HOTSPOTBUILDSPACE=%HotSpotBuildSpace% >> %HotSpotBuildSpace%\%%i\local.make
echo HOTSPOTJDKDIST=%HotSpotJDKDist% >> %HotSpotBuildSpace%\%%i\local.make
echo ARCH=%ARCH% >> %HotSpotBuildSpace%\%%i\local.make
......@@ -155,42 +183,35 @@ echo BUILDARCH=%BUILDARCH% >> %HotSpotBuildSpace%\%%i\local.m
echo Platform_arch=%Platform_arch% >> %HotSpotBuildSpace%\%%i\local.make
echo Platform_arch_model=%Platform_arch_model% >> %HotSpotBuildSpace%\%%i\local.make
pushd %HotSpotBuildSpace%\%%i
for /D %%j in (debug, fastdebug, product) do (
if NOT EXIST %HotSpotBuildSpace%\%%i\%%j mkdir %HotSpotBuildSpace%\%%i\%%j
)
pushd %HotSpotBuildSpace%\%%i\generated
nmake /nologo
popd
)
pushd %HotSpotBuildSpace%
pushd %HotSpotBuildRoot%
echo # Generated file! > local.make
echo # Changing a variable below and then deleting %ProjectFile% will cause >> local.make
echo # %ProjectFile% to be regenerated with the new values. Changing the >> local.make
echo # version requires rerunning create.bat. >> local.make
echo. >> local.make
echo HOTSPOTWORKSPACE=%HotSpotWorkSpace% >> local.make
echo HOTSPOTBUILDSPACE=%HotSpotBuildSpace% >> local.make
echo HOTSPOTJDKDIST=%HotSpotJDKDist% >> local.make
echo ARCH=%ARCH% >> local.make
echo BUILDARCH=%BUILDARCH% >> local.make
echo Platform_arch=%Platform_arch% >> local.make
echo Platform_arch_model=%Platform_arch_model% >> local.make
nmake /nologo /F %HotSpotWorkSpace%/make/windows/projectfiles/common/Makefile %HotSpotBuildSpace%/%ProjectFile%
REM It doesn't matter which variant we use here, "compiler1" is as good as any of the others - we need the common variables
nmake /nologo /F %HotSpotWorkSpace%/make/windows/projectfiles/common/Makefile LOCAL_MAKE=%HotSpotBuildSpace%\compiler1\local.make %HotSpotBuildRoot%/%ProjectFile%
popd
goto end
:usage
echo Usage: create HotSpotWorkSpace HotSpotBuildSpace HotSpotJDKDist
echo Usage: create HotSpotJDKDist
echo.
echo This is the interactive build setup script (as opposed to the batch
echo build execution script). It creates HotSpotBuildSpace if necessary,
echo copies the appropriate files out of HotSpotWorkSpace into it, and
echo This is the VS build setup script (as opposed to the batch
echo build execution script). It creates a build directory if necessary,
echo copies the appropriate files out of the workspace into it, and
echo builds and runs ProjectCreator in it. This has the side-effect of creating
echo the %ProjectFile% file in the build space, which is then used in Visual C++.
echo The HotSpotJDKDist defines place where JVM binaries should be placed.
echo.
echo The HotSpotJDKDist defines the JDK that should be used when running the JVM.
echo Environment variable FORCE_MSC_VER allows to override MSVC version autodetection.
echo.
echo NOTE that it is now NOT safe to modify any of the files in the build
......
......@@ -107,8 +107,12 @@ case "${Platform_arch_model}" in
"x86_64") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} *x86_32*" ;;
esac
# Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
function findsrc {
$FIND ${1} \( -name \*.c -o -name \*.cpp -o -name \*.s \) -a \! \( -name ${Src_Files_EXCLUDE// / -o -name } \) | sed 's/.*\/\(.*\)/\1/';
$FIND ${1}/. ! -name . -prune \
-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
-a \! \( -name ${Src_Files_EXCLUDE// / -o -name } \) \
| sed 's/.*\/\(.*\)/\1/';
}
Src_Files=
......
......@@ -22,7 +22,6 @@
#
#
!include $(WorkSpace)/make/windows/makefiles/compile.make
# Rules for building adlc.exe
......@@ -46,15 +45,7 @@ ADLCFLAGS=-q -T -D_LP64
ADLCFLAGS=-q -T -U_LP64
!endif
CPP_FLAGS=$(CPP_FLAGS) \
/D TARGET_OS_FAMILY_windows \
/D TARGET_ARCH_$(Platform_arch) \
/D TARGET_ARCH_MODEL_$(Platform_arch_model) \
/D TARGET_OS_ARCH_windows_$(Platform_arch) \
/D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model) \
/D TARGET_COMPILER_visCPP
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
ADLC_CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
CPP_INCLUDE_DIRS=\
/I "..\generated" \
......@@ -92,10 +83,10 @@ GENERATED_NAMES_IN_DIR=\
$(AdlcOutDir)\dfa_$(Platform_arch_model).cpp
{$(WorkSpace)\src\share\vm\adlc}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
$(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
{$(WorkSpace)\src\share\vm\opto}.cpp.obj::
$(CPP) $(CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
$(CPP) $(ADLC_CPP_FLAGS) $(EXH_FLAGS) $(CPP_INCLUDE_DIRS) /c $<
adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \
forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj
......
#
# Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1997, 2010, 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
......@@ -80,6 +80,20 @@ CPP_FLAGS=$(CPP_FLAGS) /D "IA32"
CPP=ARCH_ERROR
!endif
CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS"
# Must specify this for sharedRuntimeTrig.cpp
CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN"
# Used for platform dispatching
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP
# MSC_VER is a 4 digit number that tells us what compiler is being used
# and is generated when the local.make file is created by build.make
# via the script get_msc_ver.sh
......
......@@ -26,7 +26,6 @@ HS_INTERNAL_NAME=jvm
HS_FNAME=$(HS_INTERNAL_NAME).dll
AOUT=$(HS_FNAME)
SAWINDBG=sawindbg.dll
LAUNCHER_NAME=hotspot.exe
GENERATED=../generated
# Allow the user to turn off precompiled headers from the command line.
......@@ -34,7 +33,7 @@ GENERATED=../generated
BUILD_PCH_FILE=_build_pch_file.obj
!endif
default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
......@@ -49,8 +48,10 @@ HS_BUILD_ID=$(HS_BUILD_VER)-debug
# Force resources to be rebuilt every time
$(Res_Files): FORCE
$(AOUT): $(Res_Files) $(Obj_Files)
vm.def: $(Obj_Files)
sh $(WorkSpace)/make/windows/build_vm_def.sh
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
......
......@@ -26,7 +26,6 @@ HS_INTERNAL_NAME=jvm
HS_FNAME=$(HS_INTERNAL_NAME).dll
AOUT=$(HS_FNAME)
SAWINDBG=sawindbg.dll
LAUNCHER_NAME=hotspot.exe
GENERATED=../generated
# Allow the user to turn off precompiled headers from the command line.
......@@ -34,7 +33,7 @@ GENERATED=../generated
BUILD_PCH_FILE=_build_pch_file.obj
!endif
default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
......@@ -49,8 +48,10 @@ HS_BUILD_ID=$(HS_BUILD_VER)-fastdebug
# Force resources to be rebuilt every time
$(Res_Files): FORCE
$(AOUT): $(Res_Files) $(Obj_Files)
vm.def: $(Obj_Files)
sh $(WorkSpace)/make/windows/build_vm_def.sh
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
......
......@@ -51,6 +51,7 @@ classes/ProjectCreator.class: $(ProjectCreatorSources)
!if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
!include $(WorkSpace)/make/windows/makefiles/compile.make
!include $(WorkSpace)/make/windows/makefiles/adlc.make
!endif
......
......@@ -22,7 +22,8 @@
#
#
LAUNCHER_FLAGS=$(ARCHFLAG) \
LAUNCHER_FLAGS=$(CPP_FLAGS) $(ARCHFLAG) \
/D FULL_VERSION=\"$(HOTSPOT_RELEASE_VERSION)\" \
/D JDK_MAJOR_VERSION=\"$(JDK_MAJOR_VERSION)\" \
/D JDK_MINOR_VERSION=\"$(JDK_MINOR_VERSION)\" \
......@@ -32,9 +33,11 @@ LAUNCHER_FLAGS=$(ARCHFLAG) \
/D _CRT_SECURE_NO_DEPRECATE \
/D LINK_INTO_LIBJVM \
/I $(WorkSpace)\src\os\windows\launcher \
/I $(WorkSpace)\src\share\tools\launcher
CPP_FLAGS=$(CPP_FLAGS) $(LAUNCHER_FLAGS)
/I $(WorkSpace)\src\share\tools\launcher \
/I $(WorkSpace)\src\share\vm\prims \
/I $(WorkSpace)\src\share\vm \
/I $(WorkSpace)\src\cpu\$(Platform_arch)\vm \
/I $(WorkSpace)\src\os\windows\vm
LINK_FLAGS=/manifest $(HS_INTERNAL_NAME).lib kernel32.lib user32.lib /nologo /machine:$(MACHINE) /map /debug /subsystem:console
......@@ -46,22 +49,23 @@ BUFFEROVERFLOWLIB = bufferoverflowU.lib
LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
!endif
LAUNCHERDIR = $(GAMMADIR)/src/os/windows/launcher
LAUNCHERDIR_SHARE = $(GAMMADIR)/src/share/tools/launcher
LAUNCHERDIR = $(WorkSpace)/src/os/windows/launcher
LAUNCHERDIR_SHARE = $(WorkSpace)/src/share/tools/launcher
OUTDIR = launcher
{$(LAUNCHERDIR)}.c{$(OUTDIR)}.obj:
-mkdir $(OUTDIR)
$(CPP) $(CPP_FLAGS) /c /Fo$@ $<
-mkdir $(OUTDIR) 2>NUL >NUL
$(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
{$(LAUNCHERDIR_SHARE)}.c{$(OUTDIR)}.obj:
-mkdir $(OUTDIR)
$(CPP) $(CPP_FLAGS) /c /Fo$@ $<
-mkdir $(OUTDIR) 2>NUL >NUL
$(CPP) $(LAUNCHER_FLAGS) /c /Fo$@ $<
$(OUTDIR)\*.obj: $(LAUNCHERDIR)\*.c $(LAUNCHERDIR)\*.h $(LAUNCHERDIR_SHARE)\*.c $(LAUNCHERDIR_SHARE)\*.h
$(LAUNCHER_NAME): $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
$(LINK) $(LINK_FLAGS) /out:$@ $**
launcher: $(OUTDIR)\java.obj $(OUTDIR)\java_md.obj $(OUTDIR)\jli_util.obj
echo $(JAVA_HOME) > jdkpath.txt
$(LINK) $(LINK_FLAGS) /out:hotspot.exe $**
......@@ -25,7 +25,6 @@
HS_INTERNAL_NAME=jvm
HS_FNAME=$(HS_INTERNAL_NAME).dll
AOUT=$(HS_FNAME)
LAUNCHER_NAME=hotspot.exe
GENERATED=../generated
# Allow the user to turn off precompiled headers from the command line.
......@@ -33,7 +32,7 @@ GENERATED=../generated
BUILD_PCH_FILE=_build_pch_file.obj
!endif
default:: $(BUILD_PCH_FILE) $(AOUT) $(LAUNCHER_NAME) checkAndBuildSA
default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
......@@ -59,8 +58,10 @@ $(AOUT): $(Res_Files) $(Obj_Files)
$(LINK_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files)
<<
!else
$(AOUT): $(Res_Files) $(Obj_Files)
vm.def: $(Obj_Files)
sh $(WorkSpace)/make/windows/build_vm_def.sh
$(AOUT): $(Res_Files) $(Obj_Files) vm.def
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
......
......@@ -84,11 +84,12 @@ ProjectCreatorIDEOptions=\
-buildBase $(HOTSPOTBUILDSPACE)\%f\%b \
-startAt src \
-compiler $(VcVersion) \
-projectFileName $(HOTSPOTBUILDSPACE)\$(ProjectFile) \
-projectFileName $(HOTSPOTBUILDROOT)\$(ProjectFile) \
-jdkTargetRoot $(HOTSPOTJDKDIST) \
-define ALIGN_STACK_FRAMES \
-define VM_LITTLE_ENDIAN \
-prelink "" "Generating vm.def..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) $(HOTSPOTMKSHOME)\sh $(HOTSPOTWORKSPACE)\make\windows\build_vm_def.sh $(LINK_VER)" \
-postbuild "" "Building hotspot.exe..." "cd $(HOTSPOTBUILDSPACE)\%f\%b set HOTSPOTMKSHOME=$(HOTSPOTMKSHOME) nmake -f $(HOTSPOTWORKSPACE)\make\windows\projectfiles\common\Makefile LOCAL_MAKE=$(HOTSPOTBUILDSPACE)\%f\local.make JAVA_HOME=$(HOTSPOTJDKDIST) launcher" \
-ignoreFile jsig.c \
-ignoreFile jvmtiEnvRecommended.cpp \
-ignoreFile jvmtiEnvStub.cpp \
......
#
# Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2010, 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
......@@ -48,7 +48,7 @@ BOOT_TARGET_CLASS_VERSION=6
JAVAC_FLAGS=-g -encoding ascii
BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
ProjectFile=vm.vcproj
ProjectFile=jvm.vcproj
!if "$(MSC_VER)" == "1200"
......@@ -63,6 +63,11 @@ VcVersion=VC8
VcVersion=VC9
!elseif "$(MSC_VER)" == "1600"
# for compatibility - we don't yet have a ProjectCreator for VC10
VcVersion=VC9
!else
VcVersion=VC7
......
......@@ -71,22 +71,11 @@ CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\""
CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
CPP_FLAGS=$(CPP_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
CPP_FLAGS=$(CPP_FLAGS) /D "WIN32" /D "_WINDOWS" $(CPP_INCLUDE_DIRS)
# Must specify this for sharedRuntimeTrig.cpp
CPP_FLAGS=$(CPP_FLAGS) /D "VM_LITTLE_ENDIAN"
CPP_FLAGS=$(CPP_FLAGS) $(CPP_INCLUDE_DIRS)
# Define that so jni.h is on correct side
CPP_FLAGS=$(CPP_FLAGS) /D "_JNI_IMPLEMENTATION_"
# Used for platform dispatching
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_FAMILY_windows
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_$(Platform_arch)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_ARCH_MODEL_$(Platform_arch_model)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_windows_$(Platform_arch)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_OS_ARCH_MODEL_windows_$(Platform_arch_model)
CPP_FLAGS=$(CPP_FLAGS) /D TARGET_COMPILER_visCPP
!if "$(BUILDARCH)" == "ia64"
STACK_SIZE="/STACK:1048576,262144"
!else
......@@ -104,6 +93,8 @@ AGCT_EXPORT=/export:AsyncGetCallTrace
!endif
!endif
# If you modify exports below please do the corresponding changes in
# src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
/export:JNI_GetDefaultJavaVMInitArgs \
/export:JNI_CreateJavaVM \
......
......@@ -22,7 +22,10 @@
#
#
!include local.make
!ifdef LOCAL_MAKE
!include $(LOCAL_MAKE)
!endif
WorkSpace=$(HOTSPOTWORKSPACE)
......@@ -34,11 +37,18 @@ BootStrapDir=$(BOOTDIR)
!else
!ifdef JAVA_HOME
BootStrapDir=$(JAVA_HOME)
!else
!ifdef HOTSPOTJDKDIST
BootStrapDir=$(HOTSPOTJDKDIST)
!endif
!endif
!endif
!endif
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/projectcreator.make
!include $(WorkSpace)/make/windows/makefiles/compile.make
# Pick up rules for building JVMTI (JSR-163)
JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
......@@ -56,6 +66,9 @@ Platform=$(HOTSPOTWORKSPACE)/make/windows/platform_$(BUILDARCH)
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/adlc.make
!endif
HS_INTERNAL_NAME=jvm
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/launcher.make
default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
!include $(HOTSPOTWORKSPACE)/make/hotspot_version
......@@ -97,7 +110,7 @@ ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) \
-define JRE_RELEASE_VERSION=\\\"$(JRE_RELEASE_VERSION)\\\" \
-define HOTSPOT_VM_DISTRO=\\\"$(HOTSPOT_VM_DISTRO)\\\"
$(HOTSPOTBUILDSPACE)/$(ProjectFile): local.make $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
$(HOTSPOTBUILDROOT)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
@$(RUN_JAVA) -Djava.class.path=$(HOTSPOTBUILDSPACE)/classes ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
clean:
......
#
# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1999, 2010, 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
......@@ -22,7 +22,6 @@
#
#
Variant=compiler1
!include local.make
!include ../local.make
!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
......@@ -2,6 +2,6 @@
; This .DEF file is a placeholder for one which is automatically
; generated during the build process. See
; make\windows\build_vm_def.sh and
; make\windows\makefiles\makedeps.make (esp. the "-prelink"
; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
; options).
;
......@@ -22,8 +22,7 @@
#
#
Variant=compiler2
!include local.make
!include ../local.make
AdlcOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\adfiles
AdditionalTargets=$(AdlcOutDir)\ad_$(Platform_arch_model).cpp $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp
......
......@@ -2,6 +2,6 @@
; This .DEF file is a placeholder for one which is automatically
; generated during the build process. See
; make\windows\build_vm_def.sh and
; make\windows\makefiles\makedeps.make (esp. the "-prelink"
; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
; options).
;
#
# Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1998, 2010, 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
......@@ -22,7 +22,6 @@
#
#
Variant=core
!include local.make
!include ../local.make
!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
......@@ -2,6 +2,6 @@
; This .DEF file is a placeholder for one which is automatically
; generated during the build process. See
; make\windows\build_vm_def.sh and
; make\windows\makefiles\makedeps.make (esp. the "-prelink"
; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
; options).
;
#
# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2007, 2010 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
......@@ -22,7 +22,6 @@
#
#
Variant=kernel
!include local.make
!include ../local.make
!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
......@@ -2,6 +2,6 @@
; This .DEF file is a placeholder for one which is automatically
; generated during the build process. See
; make\windows\build_vm_def.sh and
; make\windows\makefiles\makedeps.make (esp. the "-prelink"
; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
; options).
;
......@@ -22,8 +22,7 @@
#
#
Variant=tiered
!include local.make
!include ../local.make
AdlcOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\adfiles
AdditionalTargets=$(AdlcOutDir)\ad_$(Platform_arch_model).cpp $(AdlcOutDir)\dfa_$(Platform_arch_model).cpp
......
......@@ -2,6 +2,6 @@
; This .DEF file is a placeholder for one which is automatically
; generated during the build process. See
; make\windows\build_vm_def.sh and
; make\windows\makefiles\makedeps.make (esp. the "-prelink"
; make\windows\makefiles\projectcreator.make (esp. the "-prelink"
; options).
;
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "prims/jvm.h"
#include "utilities/decoder.hpp"
#include <cxxabi.h>
bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
int status;
char* result;
size_t size = (size_t)buflen;
// Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
// __cxa_demangle will call system "realloc" for additional memory, which
// may use different malloc/realloc mechanism that allocates 'buf'.
if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
jio_snprintf(buf, buflen, "%s", result);
// call c library's free
::free(result);
return true;
}
return false;
}
......@@ -59,6 +59,7 @@
#include "services/attachListener.hpp"
#include "services/runtimeService.hpp"
#include "thread_linux.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
......@@ -1688,14 +1689,23 @@ bool os::dll_address_to_function_name(address addr, char *buf,
Dl_info dlinfo;
if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
if (offset) *offset = addr - (address)dlinfo.dli_saddr;
if (buf != NULL) {
if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
}
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
return true;
} else {
if (buf) buf[0] = '\0';
if (offset) *offset = -1;
return false;
} else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
return true;
}
}
if (buf != NULL) buf[0] = '\0';
if (offset != NULL) *offset = -1;
return false;
}
struct _address_to_library_name {
......
......@@ -28,6 +28,7 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
......@@ -812,13 +813,10 @@ GetApplicationHome(char *buf, jint bufsize)
#ifdef GAMMA
{
/* gamma launcher uses JAVA_HOME or ALT_JAVA_HOME environment variable to find JDK/JRE */
char* java_home_var = getenv("ALT_JAVA_HOME");
/* gamma launcher uses JAVA_HOME environment variable to find JDK/JRE */
char* java_home_var = getenv("JAVA_HOME");
if (java_home_var == NULL) {
java_home_var = getenv("JAVA_HOME");
}
if (java_home_var == NULL) {
printf("JAVA_HOME or ALT_JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
printf("JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
return JNI_FALSE;
}
snprintf(buf, bufsize, "%s", java_home_var);
......@@ -1837,7 +1835,7 @@ ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void
if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
void * tmp;
pthread_join(tid, &tmp);
rslt = (int)tmp;
rslt = (int)(intptr_t)tmp;
} else {
/*
* Continue execution in current thread if for some reason (e.g. out of
......@@ -1855,7 +1853,7 @@ ContinueInNewThread(int (JNICALL *continuation)(void *), jlong stack_size, void
if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
void * tmp;
thr_join(tid, NULL, &tmp);
rslt = (int)tmp;
rslt = (int)(intptr_t)tmp;
} else {
/* See above. Continue in current thread if thr_create() failed */
rslt = continuation(args);
......
......@@ -95,17 +95,21 @@ case "$1" in
;;
esac
# Find out the absolute path to this script
MYDIR=$(cd $(dirname $SCRIPT) && pwd)
JDK=
if [ "${ALT_JAVA_HOME}" = "" ]; then
if [ "${JAVA_HOME}" = "" ]; then
echo "Neither ALT_JAVA_HOME nor JAVA_HOME is set. Aborting.";
exit 1;
else
JDK=${JAVA_HOME%%/jre};
fi
source ${MYDIR}/jdkpath.sh
else
JDK=${ALT_JAVA_HOME%%/jre};
fi
if [ "${JDK}" = "" ]; then
echo Failed to find JDK. ALT_JAVA_HOME is not set or ./jdkpath.sh is empty or not found.
exit 1
fi
# We will set the LD_LIBRARY_PATH as follows:
# o $JVMPATH (directory portion only)
# o $JRE/lib/$ARCH
......
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "utilities/decoder.hpp"
#include <demangle.h>
bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
return !cplus_demangle(symbol, buf, (size_t)buflen);
}
......@@ -57,6 +57,7 @@
#include "services/attachListener.hpp"
#include "services/runtimeService.hpp"
#include "thread_solaris.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
......@@ -1969,27 +1970,42 @@ bool os::dll_address_to_function_name(address addr, char *buf,
Sym * info;
if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
RTLD_DL_SYMENT)) {
if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
if (offset) *offset = addr - (address)dlinfo.dli_saddr;
// check if the returned symbol really covers addr
return ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr);
} else {
if (buf) buf[0] = '\0';
if (offset) *offset = -1;
return false;
if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
if (buf != NULL) {
if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
return true;
}
}
if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
return true;
}
}
if (buf != NULL) buf[0] = '\0';
if (offset != NULL) *offset = -1;
return false;
} else {
// no, only dladdr is available
if(dladdr((void *)addr, &dlinfo)) {
if (buf) jio_snprintf(buf, buflen, dlinfo.dli_sname);
if (offset) *offset = addr - (address)dlinfo.dli_saddr;
if (dladdr((void *)addr, &dlinfo)) {
if (buf != NULL) {
if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
jio_snprintf(buf, buflen, dlinfo.dli_sname);
}
if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
return true;
} else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
return true;
} else {
if (buf) buf[0] = '\0';
if (offset) *offset = -1;
return false;
}
}
if (buf != NULL) buf[0] = '\0';
if (offset != NULL) *offset = -1;
return false;
}
}
......
......@@ -22,6 +22,7 @@
*
*/
#include <ctype.h>
#include <windows.h>
#include <io.h>
#include <process.h>
......@@ -486,16 +487,62 @@ GetApplicationHome(char *buf, jint bufsize)
#else /* ifndef GAMMA */
/* gamma launcher uses JAVA_HOME or ALT_JAVA_HOME environment variable to find JDK/JRE */
char* java_home_var = getenv("ALT_JAVA_HOME");
if (java_home_var == NULL) {
java_home_var = getenv("JAVA_HOME");
char env[MAXPATHLEN + 1];
/* gamma launcher uses ALT_JAVA_HOME environment variable or jdkpath.txt file to find JDK/JRE */
if (getenv("ALT_JAVA_HOME") != NULL) {
snprintf(buf, bufsize, "%s", getenv("ALT_JAVA_HOME"));
}
if (java_home_var == NULL) {
printf("JAVA_HOME or ALT_JAVA_HOME must point to a valid JDK/JRE to run gamma\n");
return JNI_FALSE;
else {
char path[MAXPATHLEN + 1];
char* p;
int len;
FILE* fp;
// find the path to the currect executable
len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
if (len == 0 || len > MAXPATHLEN) {
printf("Could not get directory of current executable.");
return JNI_FALSE;
}
// remove last path component ("hotspot.exe")
p = strrchr(path, '\\');
if (p == NULL) {
printf("Could not parse directory of current executable.\n");
return JNI_FALSE;
}
*p = '\0';
// open jdkpath.txt and read JAVA_HOME from it
if (strlen(path) + strlen("\\jdkpath.txt") + 1 >= MAXPATHLEN) {
printf("Path too long: %s\n", path);
return JNI_FALSE;
}
strcat(path, "\\jdkpath.txt");
fp = fopen(path, "r");
if (fp == NULL) {
printf("Could not open file %s to get path to JDK.\n", path);
return JNI_FALSE;
}
if (fgets(buf, bufsize, fp) == NULL) {
printf("Could not read from file %s to get path to JDK.\n", path);
fclose(fp);
return JNI_FALSE;
}
// trim the buffer
p = buf + strlen(buf) - 1;
while(isspace(*p)) {
*p = '\0';
p--;
}
fclose(fp);
}
snprintf(buf, bufsize, "%s", java_home_var);
_snprintf(env, MAXPATHLEN, "JAVA_HOME=%s", buf);
_putenv(env);
return JNI_TRUE;
#endif /* ifndef GAMMA */
}
......
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "precompiled.hpp"
#include "prims/jvm.h"
#include "utilities/decoder.hpp"
HMODULE Decoder::_dbghelp_handle = NULL;
bool Decoder::_can_decode_in_vm = false;
pfn_SymGetSymFromAddr64 Decoder::_pfnSymGetSymFromAddr64 = NULL;
pfn_UndecorateSymbolName Decoder::_pfnUndecorateSymbolName = NULL;
void Decoder::initialize() {
if (!_initialized) {
_initialized = true;
HMODULE handle = ::LoadLibrary("dbghelp.dll");
if (!handle) {
_decoder_status = helper_not_found;
return;
}
_dbghelp_handle = handle;
pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
_pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
_pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName");
if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
::FreeLibrary(handle);
_dbghelp_handle = NULL;
_decoder_status = helper_func_error;
return;
}
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) {
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
::FreeLibrary(handle);
_dbghelp_handle = NULL;
_decoder_status = helper_init_error;
return;
}
// find out if jvm.dll contains private symbols, by decoding
// current function and comparing the result
address addr = (address)Decoder::initialize;
char buf[MAX_PATH];
if (decode(addr, buf, sizeof(buf), NULL) == no_error) {
_can_decode_in_vm = !strcmp(buf, "Decoder::initialize");
}
}
}
void Decoder::uninitialize() {
assert(_initialized, "Decoder not yet initialized");
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
if (_dbghelp_handle != NULL) {
::FreeLibrary(_dbghelp_handle);
}
_initialized = false;
}
bool Decoder::can_decode_C_frame_in_vm() {
initialize();
return _can_decode_in_vm;
}
Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) {
assert(_initialized, "Decoder not yet initialized");
if (_pfnSymGetSymFromAddr64 != NULL) {
PIMAGEHLP_SYMBOL64 pSymbol;
char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
pSymbol = (PIMAGEHLP_SYMBOL64)symbolInfo;
pSymbol->MaxNameLength = MAX_PATH;
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
DWORD64 displacement;
if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
if (buf != NULL) {
if (!demangle(pSymbol->Name, buf, buflen)) {
jio_snprintf(buf, buflen, "%s", pSymbol->Name);
}
}
if (offset != NULL) *offset = (int)displacement;
return no_error;
}
}
return helper_not_found;
}
bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
assert(_initialized, "Decoder not yet initialized");
return _pfnUndecorateSymbolName != NULL &&
_pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
}
......@@ -62,6 +62,7 @@
#include "services/attachListener.hpp"
#include "services/runtimeService.hpp"
#include "thread_windows.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/growableArray.hpp"
......@@ -1365,12 +1366,11 @@ bool os::dll_address_to_library_name(address addr, char* buf,
bool os::dll_address_to_function_name(address addr, char *buf,
int buflen, int *offset) {
// Unimplemented on Windows - in order to use SymGetSymFromAddr(),
// we need to initialize imagehlp/dbghelp, then load symbol table
// for every module. That's too much work to do after a fatal error.
// For an example on how to implement this function, see 1.4.2.
if (offset) *offset = -1;
if (buf) buf[0] = '\0';
if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
return true;
}
if (offset != NULL) *offset = -1;
if (buf != NULL) buf[0] = '\0';
return false;
}
......@@ -1711,14 +1711,11 @@ void os::jvm_path(char *buf, jint buflen) {
buf[0] = '\0';
if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
// Support for the gamma launcher. Check for an
// ALT_JAVA_HOME or JAVA_HOME environment variable
// JAVA_HOME environment variable
// and fix up the path so it looks like
// libjvm.so is installed there (append a fake suffix
// hotspot/libjvm.so).
char* java_home_var = ::getenv("ALT_JAVA_HOME");
if (java_home_var == NULL) {
java_home_var = ::getenv("JAVA_HOME");
}
char* java_home_var = ::getenv("JAVA_HOME");
if (java_home_var != NULL && java_home_var[0] != 0) {
strncpy(buf, java_home_var, buflen);
......
......@@ -22,8 +22,11 @@
*
*/
import java.util.*;
import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
class BuildConfig {
Hashtable vars;
......@@ -57,7 +60,6 @@ class BuildConfig {
// ones mentioned above were needed to expand format
String buildBase = expandFormat(getFieldString(null, "BuildBase"));
String jdkDir = getFieldString(null, "JdkTargetRoot");
String sourceBase = getFieldString(null, "SourceBase");
String outDir = buildBase;
......@@ -65,7 +67,7 @@ class BuildConfig {
put("OutputDir", outDir);
put("SourceBase", sourceBase);
put("BuildBase", buildBase);
put("OutputDll", jdkDir + Util.sep + outDll);
put("OutputDll", outDir + Util.sep + outDll);
context = new String [] {flavourBuild, flavour, build, null};
}
......@@ -537,68 +539,75 @@ abstract class GenericDebugConfig extends BuildConfig {
}
}
class C1DebugConfig extends GenericDebugConfig {
abstract class GenericDebugNonKernelConfig extends GenericDebugConfig {
protected void init(Vector includes, Vector defines) {
super.init(includes, defines);
getCI().getAdditionalNonKernelLinkerFlags(getV("LinkerFlags"));
}
}
class C1DebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getNoOptFlag();
}
C1DebugConfig() {
initNames("compiler1", "debug", "fastdebug\\jre\\bin\\client\\jvm.dll");
initNames("compiler1", "debug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class C1FastDebugConfig extends GenericDebugConfig {
class C1FastDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getOptFlag();
}
C1FastDebugConfig() {
initNames("compiler1", "fastdebug", "fastdebug\\jre\\bin\\client\\jvm.dll");
initNames("compiler1", "fastdebug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class C2DebugConfig extends GenericDebugConfig {
class C2DebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getNoOptFlag();
}
C2DebugConfig() {
initNames("compiler2", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll");
initNames("compiler2", "debug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class C2FastDebugConfig extends GenericDebugConfig {
class C2FastDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getOptFlag();
}
C2FastDebugConfig() {
initNames("compiler2", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll");
initNames("compiler2", "fastdebug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class TieredDebugConfig extends GenericDebugConfig {
class TieredDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getNoOptFlag();
}
TieredDebugConfig() {
initNames("tiered", "debug", "fastdebug\\jre\\bin\\server\\jvm.dll");
initNames("tiered", "debug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class TieredFastDebugConfig extends GenericDebugConfig {
class TieredFastDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getOptFlag();
}
TieredFastDebugConfig() {
initNames("tiered", "fastdebug", "fastdebug\\jre\\bin\\server\\jvm.dll");
initNames("tiered", "fastdebug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
......@@ -618,45 +627,45 @@ abstract class ProductConfig extends BuildConfig {
class C1ProductConfig extends ProductConfig {
C1ProductConfig() {
initNames("compiler1", "product", "jre\\bin\\client\\jvm.dll");
initNames("compiler1", "product", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class C2ProductConfig extends ProductConfig {
C2ProductConfig() {
initNames("compiler2", "product", "jre\\bin\\server\\jvm.dll");
initNames("compiler2", "product", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class TieredProductConfig extends ProductConfig {
TieredProductConfig() {
initNames("tiered", "product", "jre\\bin\\server\\jvm.dll");
initNames("tiered", "product", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class CoreDebugConfig extends GenericDebugConfig {
class CoreDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getNoOptFlag();
}
CoreDebugConfig() {
initNames("core", "debug", "fastdebug\\jre\\bin\\core\\jvm.dll");
initNames("core", "debug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
class CoreFastDebugConfig extends GenericDebugConfig {
class CoreFastDebugConfig extends GenericDebugNonKernelConfig {
String getOptFlag() {
return getCI().getOptFlag();
}
CoreFastDebugConfig() {
initNames("core", "fastdebug", "fastdebug\\jre\\bin\\core\\jvm.dll");
initNames("core", "fastdebug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
......@@ -664,7 +673,7 @@ class CoreFastDebugConfig extends GenericDebugConfig {
class CoreProductConfig extends ProductConfig {
CoreProductConfig() {
initNames("core", "product", "jre\\bin\\core\\jvm.dll");
initNames("core", "product", "jvm.dll");
init(getIncludes(), getDefines());
}
}
......@@ -675,7 +684,7 @@ class KernelDebugConfig extends GenericDebugConfig {
}
KernelDebugConfig() {
initNames("kernel", "debug", "fastdebug\\jre\\bin\\kernel\\jvm.dll");
initNames("kernel", "debug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
......@@ -687,7 +696,7 @@ class KernelFastDebugConfig extends GenericDebugConfig {
}
KernelFastDebugConfig() {
initNames("kernel", "fastdebug", "fastdebug\\jre\\bin\\kernel\\jvm.dll");
initNames("kernel", "fastdebug", "jvm.dll");
init(getIncludes(), getDefines());
}
}
......@@ -695,7 +704,7 @@ class KernelFastDebugConfig extends GenericDebugConfig {
class KernelProductConfig extends ProductConfig {
KernelProductConfig() {
initNames("kernel", "product", "jre\\bin\\kernel\\jvm.dll");
initNames("kernel", "product", "jvm.dll");
init(getIncludes(), getDefines());
}
}
......@@ -704,6 +713,7 @@ abstract class CompilerInterface {
abstract Vector getBaseLinkerFlags(String outDir, String outDll);
abstract Vector getDebugCompilerFlags(String opt);
abstract Vector getDebugLinkerFlags();
abstract void getAdditionalNonKernelLinkerFlags(Vector rv);
abstract Vector getProductCompilerFlags();
abstract Vector getProductLinkerFlags();
abstract String getOptFlag();
......@@ -713,4 +723,14 @@ abstract class CompilerInterface {
void addAttr(Vector receiver, String attr, String value) {
receiver.add(attr); receiver.add(value);
}
void extAttr(Vector receiver, String attr, String value) {
int attr_pos=receiver.indexOf(attr) ;
if ( attr_pos == -1) {
// If attr IS NOT present in the Vector - add it
receiver.add(attr); receiver.add(value);
} else {
// If attr IS present in the Vector - append value to it
receiver.set(attr_pos+1,receiver.get(attr_pos+1)+value);
}
}
}
......@@ -22,8 +22,15 @@
*
*/
import java.io.*;
import java.util.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
import java.util.Vector;
abstract class HsArgHandler extends ArgHandler {
static final int STRING = 1;
......@@ -345,11 +352,23 @@ public abstract class WinGammaPlatform {
new ArgsParser(args,
new ArgRule[]
{
new HsArgRule("-sourceBase",
"SourceBase",
" (Did you set the HotSpotWorkSpace environment variable?)",
HsArgHandler.STRING
),
new ArgRule("-sourceBase",
new HsArgHandler() {
public void handle(ArgIterator it) {
String cfg = getCfg(it.get());
if (nextNotKey(it)) {
String sb = (String) it.get();
if (sb.endsWith(Util.sep)) {
sb = sb.substring(0, sb.length() - 1);
}
BuildConfig.putField(cfg, "SourceBase", sb);
it.next();
} else {
empty("-sourceBase", null);
}
}
}
),
new HsArgRule("-buildBase",
"BuildBase",
......@@ -512,7 +531,6 @@ public abstract class WinGammaPlatform {
new HsArgHandler() {
public void handle(ArgIterator it) {
if (nextNotKey(it)) {
String build = it.get();
if (nextNotKey(it)) {
String description = it.get();
if (nextNotKey(it)) {
......@@ -528,7 +546,28 @@ public abstract class WinGammaPlatform {
empty(null, "** Error: wrong number of args to -prelink");
}
}
)
),
new ArgRule("-postbuild",
new HsArgHandler() {
public void handle(ArgIterator it) {
if (nextNotKey(it)) {
if (nextNotKey(it)) {
String description = it.get();
if (nextNotKey(it)) {
String command = it.get();
BuildConfig.putField(null, "PostbuildDescription", description);
BuildConfig.putField(null, "PostbuildCommand", command);
it.next();
return;
}
}
}
empty(null, "** Error: wrong number of args to -postbuild");
}
}
),
},
new ArgHandler() {
public void handle(ArgIterator it) {
......@@ -618,10 +657,6 @@ public abstract class WinGammaPlatform {
public int compareTo(Object o) {
FileInfo oo = (FileInfo)o;
// Don't squelch identical short file names where the full
// paths are different
if (!attr.shortName.equals(oo.attr.shortName))
return attr.shortName.compareTo(oo.attr.shortName);
return full.compareTo(oo.full);
}
......
......@@ -260,6 +260,8 @@ class CompilerInterfaceVC6 extends CompilerInterface {
return rv;
}
void getAdditionalNonKernelLinkerFlags(Vector rv) {}
Vector getProductCompilerFlags() {
Vector rv = new Vector();
......
......@@ -22,8 +22,13 @@
*
*/
import java.io.*;
import java.util.*;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Vector;
public class WinGammaPlatformVC7 extends WinGammaPlatform {
......@@ -104,7 +109,9 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
boolean match(FileInfo fi) {
return fi.full.regionMatches(true, baseLen, dir, 0, dirLen);
int lastSlashIndex = fi.full.lastIndexOf('/');
String fullDir = fi.full.substring(0, lastSlashIndex);
return fullDir.endsWith(dir);
}
}
......@@ -217,65 +224,41 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
// - container filter just provides a container to group together real filters
// - real filter can select elements from the set according to some rule, put it into XML
// and remove from the list
Vector makeFilters(TreeSet files) {
Vector makeFilters(TreeSet<FileInfo> files) {
Vector rv = new Vector();
String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/");
ContainerFilter rt = new ContainerFilter("Runtime");
rt.add(new DirectoryFilter("share/vm/prims", sbase));
rt.add(new DirectoryFilter("share/vm/runtime", sbase));
rt.add(new DirectoryFilter("share/vm/oops", sbase));
rv.add(rt);
ContainerFilter gc = new ContainerFilter("GC");
gc.add(new DirectoryFilter("share/vm/memory", sbase));
gc.add(new DirectoryFilter("share/vm/gc_interface", sbase));
ContainerFilter gc_impl = new ContainerFilter("Implementations");
gc_impl.add(new DirectoryFilter("CMS",
"share/vm/gc_implementation/concurrentMarkSweep",
sbase));
gc_impl.add(new DirectoryFilter("Parallel Scavenge",
"share/vm/gc_implementation/parallelScavenge",
sbase));
gc_impl.add(new DirectoryFilter("Shared",
"share/vm/gc_implementation/shared",
sbase));
// for all leftovers
gc_impl.add(new DirectoryFilter("Misc",
"share/vm/gc_implementation",
sbase));
gc.add(gc_impl);
rv.add(gc);
rv.add(new DirectoryFilter("C1", "share/vm/c1", sbase));
rv.add(new DirectoryFilter("C2", "share/vm/opto", sbase));
ContainerFilter comp = new ContainerFilter("Compiler Common");
comp.add(new DirectoryFilter("share/vm/asm", sbase));
comp.add(new DirectoryFilter("share/vm/ci", sbase));
comp.add(new DirectoryFilter("share/vm/code", sbase));
comp.add(new DirectoryFilter("share/vm/compiler", sbase));
rv.add(comp);
rv.add(new DirectoryFilter("Interpreter",
"share/vm/interpreter",
sbase));
ContainerFilter misc = new ContainerFilter("Misc");
misc.add(new DirectoryFilter("share/vm/libadt", sbase));
misc.add(new DirectoryFilter("share/vm/services", sbase));
misc.add(new DirectoryFilter("share/vm/utilities", sbase));
misc.add(new DirectoryFilter("share/vm/classfile", sbase));
rv.add(misc);
rv.add(new DirectoryFilter("os_cpu", sbase));
rv.add(new DirectoryFilter("cpu", sbase));
rv.add(new DirectoryFilter("os", sbase));
String currentDir = "";
DirectoryFilter container = null;
for(FileInfo fileInfo : files) {
if (!fileInfo.full.startsWith(sbase)) {
continue;
}
int lastSlash = fileInfo.full.lastIndexOf('/');
String dir = fileInfo.full.substring(sbase.length(), lastSlash);
if(dir.equals("share/vm")) {
// skip files directly in share/vm - should only be precompiled.hpp which is handled below
continue;
}
if (!dir.equals(currentDir)) {
currentDir = dir;
if (container != null) {
rv.add(container);
}
// remove "share/vm/" from names
String name = dir;
if (dir.startsWith("share/vm/")) {
name = dir.substring("share/vm/".length(), dir.length());
}
container = new DirectoryFilter(name, dir, sbase);
}
}
if (container != null) {
rv.add(container);
}
ContainerFilter generated = new ContainerFilter("Generated");
ContainerFilter c1Generated = new ContainerFilter("C1");
......@@ -397,7 +380,6 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
"Name", cfg,
"ExcludedFromBuild", "TRUE"
});
tag("Tool", new String[] {"Name", "VCCLCompilerTool"});
endTag("FileConfiguration");
}
......@@ -441,7 +423,11 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
tag("Tool",
new String[] {
"Name", "VCPostBuildEventTool"
"Name", "VCPostBuildEventTool",
"Description", BuildConfig.getFieldString(null, "PostbuildDescription"),
//Caution: String.replace(String,String) is available from JDK5 onwards only
"CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace
("\t", "&#x0D;&#x0A;"))
}
);
......@@ -469,33 +455,6 @@ public class WinGammaPlatformVC7 extends WinGammaPlatform {
"Culture", "1033"
}
);
tag("Tool",
new String[] {
"Name", "VCWebServiceProxyGeneratorTool"
}
);
tag ("Tool",
new String[] {
"Name", "VCXMLDataGeneratorTool"
}
);
tag("Tool",
new String[] {
"Name", "VCWebDeploymentTool"
}
);
tag("Tool",
new String[] {
"Name", "VCManagedWrapperGeneratorTool"
}
);
tag("Tool",
new String[] {
"Name", "VCAuxiliaryManagedWrapperGeneratorTool"
}
);
tag("Tool",
new String[] {
......@@ -597,7 +556,7 @@ class CompilerInterfaceVC7 extends CompilerInterface {
addAttr(rv, "PrecompiledHeaderFile", outDir+Util.sep+"vm.pch");
addAttr(rv, "AssemblerListingLocation", outDir);
addAttr(rv, "ObjectFile", outDir+Util.sep);
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"vm.pdb");
addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
// Set /nologo optin
addAttr(rv, "SuppressStartupBanner", "TRUE");
// Surpass the default /Tc or /Tp. 0 is compileAsDefault
......@@ -631,17 +590,22 @@ class CompilerInterfaceVC7 extends CompilerInterface {
addAttr(rv, "AdditionalOptions",
"/export:JNI_GetDefaultJavaVMInitArgs " +
"/export:JNI_CreateJavaVM " +
"/export:JVM_FindClassFromBootLoader "+
"/export:JNI_GetCreatedJavaVMs "+
"/export:jio_snprintf /export:jio_printf "+
"/export:jio_fprintf /export:jio_vfprintf "+
"/export:jio_vsnprintf ");
"/export:jio_vsnprintf "+
"/export:JVM_GetVersionInfo "+
"/export:JVM_GetThreadStateNames "+
"/export:JVM_GetThreadStateValues "+
"/export:JVM_InitAgentProperties ");
addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
addAttr(rv, "OutputFile", outDll);
// Set /INCREMENTAL option. 1 is linkIncrementalNo
addAttr(rv, "LinkIncremental", "1");
addAttr(rv, "SuppressStartupBanner", "TRUE");
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"vm.pdb");
addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
// Set /SUBSYSTEM option. 2 is subSystemWindows
addAttr(rv, "SubSystem", "2");
addAttr(rv, "BaseAddress", "0x8000000");
......@@ -682,6 +646,11 @@ class CompilerInterfaceVC7 extends CompilerInterface {
return rv;
}
void getAdditionalNonKernelLinkerFlags(Vector rv) {
extAttr(rv, "AdditionalOptions",
"/export:AsyncGetCallTrace ");
}
void getProductCompilerFlags_common(Vector rv) {
// Set /O2 option. 2 is optimizeMaxSpeed
addAttr(rv, "Optimization", "2");
......
......@@ -22,7 +22,7 @@
*
*/
import java.util.*;
import java.util.Vector;
public class WinGammaPlatformVC8 extends WinGammaPlatformVC7 {
......@@ -41,6 +41,9 @@ class CompilerInterfaceVC8 extends CompilerInterfaceVC7 {
// Set /EHsc- option. 0 is cppExceptionHandlingNo
addAttr(rv, "ExceptionHandling", "0");
// enable multi process builds
extAttr(rv, "AdditionalOptions", "/MP");
return rv;
}
......
......@@ -275,6 +275,8 @@ main(int argc, char ** argv)
jvmpath, sizeof(jvmpath),
original_argv);
printf("Using java runtime at: %s\n", jrepath);
ifn.CreateJavaVM = 0;
ifn.GetDefaultJavaVMInitArgs = 0;
......
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
......@@ -27,7 +28,7 @@
#include "jli_util.h"
#ifdef GAMMA
#ifdef _WINDOWS
#ifdef TARGET_OS_FAMILY_windows
#define strdup _strdup
#endif
#endif
......
......@@ -619,8 +619,8 @@ nmethod::nmethod(
OopMapSet* oop_maps )
: CodeBlob("native nmethod", code_buffer, sizeof(nmethod),
nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
_compiled_synchronized_native_basic_lock_owner_sp_offset(basic_lock_owner_sp_offset),
_compiled_synchronized_native_basic_lock_sp_offset(basic_lock_sp_offset)
_native_receiver_sp_offset(basic_lock_owner_sp_offset),
_native_basic_lock_sp_offset(basic_lock_sp_offset)
{
{
debug_only(No_Safepoint_Verifier nsv;)
......@@ -696,8 +696,8 @@ nmethod::nmethod(
int frame_size)
: CodeBlob("dtrace nmethod", code_buffer, sizeof(nmethod),
nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, NULL),
_compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)),
_compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1))
_native_receiver_sp_offset(in_ByteSize(-1)),
_native_basic_lock_sp_offset(in_ByteSize(-1))
{
{
debug_only(No_Safepoint_Verifier nsv;)
......@@ -790,8 +790,8 @@ nmethod::nmethod(
)
: CodeBlob("nmethod", code_buffer, sizeof(nmethod),
nmethod_size, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps),
_compiled_synchronized_native_basic_lock_owner_sp_offset(in_ByteSize(-1)),
_compiled_synchronized_native_basic_lock_sp_offset(in_ByteSize(-1))
_native_receiver_sp_offset(in_ByteSize(-1)),
_native_basic_lock_sp_offset(in_ByteSize(-1))
{
assert(debug_info->oop_recorder() == code_buffer->oop_recorder(), "shared OR");
{
......
......@@ -210,7 +210,7 @@ class nmethod : public CodeBlob {
ExceptionCache *_exception_cache;
PcDescCache _pc_desc_cache;
// These are only used for compiled synchronized native methods to
// These are used for compiled synchronized native methods to
// locate the owner and stack slot for the BasicLock so that we can
// properly revoke the bias of the owner if necessary. They are
// needed because there is no debug information for compiled native
......@@ -220,8 +220,10 @@ class nmethod : public CodeBlob {
// sharing between platforms. Note that currently biased locking
// will never cause Class instances to be biased but this code
// handles the static synchronized case as well.
ByteSize _compiled_synchronized_native_basic_lock_owner_sp_offset;
ByteSize _compiled_synchronized_native_basic_lock_sp_offset;
// JVMTI's GetLocalInstance() also uses these offsets to find the receiver
// for non-static native wrapper frames.
ByteSize _native_receiver_sp_offset;
ByteSize _native_basic_lock_sp_offset;
friend class nmethodLocker;
......@@ -676,11 +678,11 @@ public:
bool is_patchable_at(address instr_address);
// UseBiasedLocking support
ByteSize compiled_synchronized_native_basic_lock_owner_sp_offset() {
return _compiled_synchronized_native_basic_lock_owner_sp_offset;
ByteSize native_receiver_sp_offset() {
return _native_receiver_sp_offset;
}
ByteSize compiled_synchronized_native_basic_lock_sp_offset() {
return _compiled_synchronized_native_basic_lock_sp_offset;
ByteSize native_basic_lock_sp_offset() {
return _native_basic_lock_sp_offset;
}
// support for code generation
......
......@@ -457,6 +457,12 @@ void instanceRefKlass::oop_verify_on(oop obj, outputStream* st) {
}
}
bool instanceRefKlass::owns_pending_list_lock(JavaThread* thread) {
if (java_lang_ref_Reference::pending_list_lock() == NULL) return false;
Handle h_lock(thread, java_lang_ref_Reference::pending_list_lock());
return ObjectSynchronizer::current_thread_holds_lock(thread, h_lock);
}
void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
// we may enter this with pending exception set
PRESERVE_EXCEPTION_MARK; // exceptions are never thrown, needed for TRAPS argument
......
......@@ -89,6 +89,7 @@ class instanceRefKlass: public instanceKlass {
static void release_and_notify_pending_list_lock(BasicLock *pending_list_basic_lock);
static void acquire_pending_list_lock(BasicLock *pending_list_basic_lock);
static bool owns_pending_list_lock(JavaThread* thread);
// Update non-static oop maps so 'referent', 'nextPending' and
// 'discovered' will look like non-oops
......
......@@ -518,18 +518,21 @@ bool klassVtable::is_miranda_entry_at(int i) {
bool klassVtable::is_miranda(methodOop m, objArrayOop class_methods, klassOop super) {
symbolOop name = m->name();
symbolOop signature = m->signature();
if (instanceKlass::find_method(class_methods, name, signature) == NULL) {
// did not find it in the method table of the current class
// did not find it in the method table of the current class
if (super == NULL) {
// super doesn't exist
return true;
} else {
if (instanceKlass::cast(super)->lookup_method(name, signature) == NULL) {
// super class hierarchy does not implement it
return true;
}
}
methodOop mo = instanceKlass::cast(super)->lookup_method(name, signature);
if (mo == NULL || mo->access_flags().is_private() ) {
// super class hierarchy does not implement it or protection is different
return true;
}
}
return false;
}
......
......@@ -309,6 +309,12 @@ void methodOopDesc::print_invocation_count() {
// Build a methodDataOop object to hold information about this method
// collected in the interpreter.
void methodOopDesc::build_interpreter_method_data(methodHandle method, TRAPS) {
// Do not profile method if current thread holds the pending list lock,
// which avoids deadlock for acquiring the MethodData_lock.
if (instanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
return;
}
// Grab a lock here to prevent multiple
// methodDataOops from being created.
MutexLocker ml(MethodData_lock, THREAD);
......
......@@ -5649,6 +5649,45 @@ class C2 extends C1 implements I2 {
</errors>
</function>
<function id="GetLocalInstance" num="155" since="1.2">
<synopsis>Get Local Instance</synopsis>
<description>
This function can be used to retrieve the value of the local object
variable at slot 0 (the "<code>this</code>" object) from non-static
frames. This function can retrieve the "<code>this</code>" object from
native method frames, whereas <code>GetLocalObject()</code> would
return <code>JVMTI_ERROR_OPAQUE_FRAME</code> in those cases.
</description>
<origin>new</origin>
<capabilities>
<required id="can_access_local_variables"></required>
</capabilities>
<parameters>
<param id="thread">
<jthread null="current" frame="frame"/>
<description>
The thread of the frame containing the variable's value.
</description>
</param>
<param id="depth">
<jframeID thread="thread"/>
<description>
The depth of the frame containing the variable's value.
</description>
</param>
<param id="value_ptr">
<outptr><jobject/></outptr>
<description>
On return, points to the variable's value.
</description>
</param>
</parameters>
<errors>
<error id="JVMTI_ERROR_INVALID_SLOT">
If the specified frame is a static method frame.
</error>
</errors>
</function>
<function id="GetLocalInt" num="22">
<synopsis>Get Local Variable - Int</synopsis>
<description>
......
......@@ -1796,6 +1796,29 @@ JvmtiEnv::GetLocalObject(JavaThread* java_thread, jint depth, jint slot, jobject
}
} /* end GetLocalObject */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
// java_thread - unchecked
// depth - pre-checked as non-negative
// value - pre-checked for NULL
jvmtiError
JvmtiEnv::GetLocalInstance(JavaThread* java_thread, jint depth, jobject* value){
JavaThread* current_thread = JavaThread::current();
// rm object is created to clean up the javaVFrame created in
// doit_prologue(), but after doit() is finished with it.
ResourceMark rm(current_thread);
VM_GetReceiver op(java_thread, current_thread, depth);
VMThread::execute(&op);
jvmtiError err = op.result();
if (err != JVMTI_ERROR_NONE) {
return err;
} else {
*value = op.value().l;
return JVMTI_ERROR_NONE;
}
} /* end GetLocalInstance */
// Threads_lock NOT held, java_thread not protected by lock
// java_thread - pre-checked
......
......@@ -586,7 +586,6 @@ VM_GetOrSetLocal::VM_GetOrSetLocal(JavaThread* thread, JavaThread* calling_threa
{
}
vframe *VM_GetOrSetLocal::get_vframe() {
if (!_thread->has_last_Java_frame()) {
return NULL;
......@@ -609,7 +608,7 @@ javaVFrame *VM_GetOrSetLocal::get_java_vframe() {
}
javaVFrame *jvf = (javaVFrame*)vf;
if (!vf->is_java_frame() || jvf->method()->is_native()) {
if (!vf->is_java_frame()) {
_result = JVMTI_ERROR_OPAQUE_FRAME;
return NULL;
}
......@@ -740,6 +739,15 @@ bool VM_GetOrSetLocal::doit_prologue() {
_jvf = get_java_vframe();
NULL_CHECK(_jvf, false);
if (_jvf->method()->is_native()) {
if (getting_receiver() && !_jvf->method()->is_static()) {
return true;
} else {
_result = JVMTI_ERROR_OPAQUE_FRAME;
return false;
}
}
if (!check_slot_type(_jvf)) {
return false;
}
......@@ -781,40 +789,46 @@ void VM_GetOrSetLocal::doit() {
HandleMark hm;
switch (_type) {
case T_INT: locals->set_int_at (_index, _value.i); break;
case T_LONG: locals->set_long_at (_index, _value.j); break;
case T_FLOAT: locals->set_float_at (_index, _value.f); break;
case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
case T_OBJECT: {
Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
locals->set_obj_at (_index, ob_h);
break;
}
default: ShouldNotReachHere();
case T_INT: locals->set_int_at (_index, _value.i); break;
case T_LONG: locals->set_long_at (_index, _value.j); break;
case T_FLOAT: locals->set_float_at (_index, _value.f); break;
case T_DOUBLE: locals->set_double_at(_index, _value.d); break;
case T_OBJECT: {
Handle ob_h(JNIHandles::resolve_external_guard(_value.l));
locals->set_obj_at (_index, ob_h);
break;
}
default: ShouldNotReachHere();
}
_jvf->set_locals(locals);
} else {
StackValueCollection *locals = _jvf->locals();
if (locals->at(_index)->type() == T_CONFLICT) {
memset(&_value, 0, sizeof(_value));
_value.l = NULL;
return;
}
if (_jvf->method()->is_native() && _jvf->is_compiled_frame()) {
assert(getting_receiver(), "Can only get here when getting receiver");
oop receiver = _jvf->fr().get_native_receiver();
_value.l = JNIHandles::make_local(_calling_thread, receiver);
} else {
StackValueCollection *locals = _jvf->locals();
if (locals->at(_index)->type() == T_CONFLICT) {
memset(&_value, 0, sizeof(_value));
_value.l = NULL;
return;
}
switch (_type) {
case T_INT: _value.i = locals->int_at (_index); break;
case T_LONG: _value.j = locals->long_at (_index); break;
case T_FLOAT: _value.f = locals->float_at (_index); break;
case T_DOUBLE: _value.d = locals->double_at(_index); break;
case T_OBJECT: {
// Wrap the oop to be returned in a local JNI handle since
// oops_do() no longer applies after doit() is finished.
oop obj = locals->obj_at(_index)();
_value.l = JNIHandles::make_local(_calling_thread, obj);
break;
}
default: ShouldNotReachHere();
switch (_type) {
case T_INT: _value.i = locals->int_at (_index); break;
case T_LONG: _value.j = locals->long_at (_index); break;
case T_FLOAT: _value.f = locals->float_at (_index); break;
case T_DOUBLE: _value.d = locals->double_at(_index); break;
case T_OBJECT: {
// Wrap the oop to be returned in a local JNI handle since
// oops_do() no longer applies after doit() is finished.
oop obj = locals->obj_at(_index)();
_value.l = JNIHandles::make_local(_calling_thread, obj);
break;
}
default: ShouldNotReachHere();
}
}
}
}
......@@ -825,6 +839,10 @@ bool VM_GetOrSetLocal::allow_nested_vm_operations() const {
}
VM_GetReceiver::VM_GetReceiver(
JavaThread* thread, JavaThread* caller_thread, jint depth)
: VM_GetOrSetLocal(thread, caller_thread, depth, 0) {}
/////////////////////////////////////////////////////////////////////////////////////////
//
......
......@@ -355,7 +355,7 @@ bool JvmtiCurrentBreakpoints::is_breakpoint(address bcp) {
// to the thread simultaneously.
//
class VM_GetOrSetLocal : public VM_Operation {
private:
protected:
JavaThread* _thread;
JavaThread* _calling_thread;
jint _depth;
......@@ -365,6 +365,10 @@ private:
javaVFrame* _jvf;
bool _set;
// It is possible to get the receiver out of a non-static native wrapper
// frame. Use VM_GetReceiver to do this.
virtual bool getting_receiver() const { return false; }
jvmtiError _result;
vframe* get_vframe();
......@@ -395,6 +399,15 @@ public:
static bool is_assignable(const char* ty_sign, Klass* klass, Thread* thread);
};
class VM_GetReceiver : public VM_GetOrSetLocal {
protected:
virtual bool getting_receiver() const { return true; }
public:
VM_GetReceiver(JavaThread* thread, JavaThread* calling_thread, jint depth);
const char* name() const { return "get receiver"; }
};
///////////////////////////////////////////////////////////////
//
......
......@@ -41,6 +41,8 @@
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "utilities/decoder.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
#endif
......@@ -652,7 +654,7 @@ static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) {
// names if pc is within jvm.dll or libjvm.so, because JVM only has
// JVM_xxxx and a few other symbols in the dynamic symbol table. Do this
// only for native libraries.
if (!in_vm) {
if (!in_vm || Decoder::can_decode_C_frame_in_vm()) {
found = os::dll_address_to_function_name(pc, buf, buflen, &offset);
if (found) {
......@@ -1071,28 +1073,20 @@ oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const {
}
}
BasicLock* frame::compiled_synchronized_native_monitor(nmethod* nm) {
if (nm == NULL) {
assert(_cb != NULL && _cb->is_nmethod() &&
nm->method()->is_native() &&
nm->method()->is_synchronized(),
"should not call this otherwise");
nm = (nmethod*) _cb;
}
int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_sp_offset());
BasicLock* frame::get_native_monitor() {
nmethod* nm = (nmethod*)_cb;
assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(),
"Should not call this unless it's a native nmethod");
int byte_offset = in_bytes(nm->native_basic_lock_sp_offset());
assert(byte_offset >= 0, "should not see invalid offset");
return (BasicLock*) &sp()[byte_offset / wordSize];
}
oop frame::compiled_synchronized_native_monitor_owner(nmethod* nm) {
if (nm == NULL) {
assert(_cb != NULL && _cb->is_nmethod() &&
nm->method()->is_native() &&
nm->method()->is_synchronized(),
"should not call this otherwise");
nm = (nmethod*) _cb;
}
int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_owner_sp_offset());
oop frame::get_native_receiver() {
nmethod* nm = (nmethod*)_cb;
assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(),
"Should not call this unless it's a native nmethod");
int byte_offset = in_bytes(nm->native_receiver_sp_offset());
assert(byte_offset >= 0, "should not see invalid offset");
oop owner = ((oop*) sp())[byte_offset / wordSize];
assert( Universe::heap()->is_in(owner), "bad receiver" );
......
......@@ -254,10 +254,10 @@ class frame VALUE_OBJ_CLASS_SPEC {
// Return the monitor owner and BasicLock for compiled synchronized
// native methods so that biased locking can revoke the receiver's
// bias if necessary. Takes optional nmethod for this frame as
// argument to avoid performing repeated lookups in code cache.
BasicLock* compiled_synchronized_native_monitor (nmethod* nm = NULL);
oop compiled_synchronized_native_monitor_owner(nmethod* nm = NULL);
// bias if necessary. This is also used by JVMTI's GetLocalInstance method
// (via VM_GetReceiver) to retrieve the receiver from a native wrapper frame.
BasicLock* get_native_monitor();
oop get_native_receiver();
// Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is
// not setup)
......
......@@ -207,8 +207,8 @@ GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
// Casting away const
frame& fr = (frame&) _fr;
MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm),
fr.compiled_synchronized_native_monitor(nm), false, false);
MonitorInfo* info = new MonitorInfo(
fr.get_native_receiver(), fr.get_native_monitor(), false, false);
monitors->push(info);
return monitors;
}
......
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "precompiled.hpp"
#include "prims/jvm.h"
#include "utilities/decoder.hpp"
Decoder::decoder_status Decoder::_decoder_status = Decoder::no_error;
bool Decoder::_initialized = false;
#ifndef _WINDOWS
// Implementation of common functionalities among Solaris and Linux
#include "utilities/elfFile.hpp"
ElfFile* Decoder::_opened_elf_files = NULL;
bool Decoder::can_decode_C_frame_in_vm() {
return true;
}
void Decoder::initialize() {
_initialized = true;
}
void Decoder::uninitialize() {
if (_opened_elf_files != NULL) {
delete _opened_elf_files;
_opened_elf_files = NULL;
}
_initialized = false;
}
Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
if (_decoder_status != no_error) {
return _decoder_status;
}
ElfFile* file = get_elf_file(filepath);
if (_decoder_status != no_error) {
return _decoder_status;
}
const char* symbol = file->decode(addr, offset);
if (file->get_status() == out_of_memory) {
_decoder_status = out_of_memory;
return _decoder_status;
} else if (symbol != NULL) {
if (!demangle(symbol, buf, buflen)) {
jio_snprintf(buf, buflen, "%s", symbol);
}
return no_error;
} else {
return symbol_not_found;
}
}
ElfFile* Decoder::get_elf_file(const char* filepath) {
if (_decoder_status != no_error) {
return NULL;
}
ElfFile* file = _opened_elf_files;
while (file != NULL) {
if (file->same_elf_file(filepath)) {
return file;
}
file = file->m_next;
}
file = new ElfFile(filepath);
if (file == NULL) {
_decoder_status = out_of_memory;
}
if (_opened_elf_files != NULL) {
file->m_next = _opened_elf_files;
}
_opened_elf_files = file;
return file;
}
#endif
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#ifndef __DECODER_HPP
#define __DECODER_HPP
#include "memory/allocation.hpp"
#ifdef _WINDOWS
#include <windows.h>
#include <imagehlp.h>
// functions needed for decoding symbols
typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
#else
class ElfFile;
#endif // _WINDOWS
class Decoder: public StackObj {
public:
// status code for decoding native C frame
enum decoder_status {
no_error, // successfully decoded frames
out_of_memory, // out of memory
file_invalid, // invalid elf file
file_not_found, // could not found symbol file (on windows), such as jvm.pdb or jvm.map
helper_not_found, // could not load dbghelp.dll (Windows only)
helper_func_error, // decoding functions not found (Windows only)
helper_init_error, // SymInitialize failed (Windows only)
symbol_not_found // could not find the symbol
};
public:
Decoder() { initialize(); };
~Decoder() { uninitialize(); };
static bool can_decode_C_frame_in_vm();
static void initialize();
static void uninitialize();
#ifdef _WINDOWS
static decoder_status decode(address addr, char *buf, int buflen, int *offset);
#else
static decoder_status decode(address addr, const char* filepath, char *buf, int buflen, int *offset);
#endif
static bool demangle(const char* symbol, char *buf, int buflen);
static decoder_status get_status() { return _decoder_status; };
#ifndef _WINDOWS
private:
static ElfFile* get_elf_file(const char* filepath);
#endif // _WINDOWS
private:
static decoder_status _decoder_status;
static bool _initialized;
#ifdef _WINDOWS
static HMODULE _dbghelp_handle;
static bool _can_decode_in_vm;
static pfn_SymGetSymFromAddr64 _pfnSymGetSymFromAddr64;
static pfn_UndecorateSymbolName _pfnUndecorateSymbolName;
#else
static ElfFile* _opened_elf_files;
#endif // _WINDOWS
};
#endif // __DECODER_HPP
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "precompiled.hpp"
#ifndef _WINDOWS
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include "memory/allocation.inline.hpp"
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
#include "utilities/elfStringTable.hpp"
#include "utilities/elfSymbolTable.hpp"
ElfFile::ElfFile(const char* filepath) {
assert(filepath, "null file path");
memset(&m_elfHdr, 0, sizeof(m_elfHdr));
m_string_tables = NULL;
m_symbol_tables = NULL;
m_next = NULL;
m_status = Decoder::no_error;
int len = strlen(filepath) + 1;
m_filepath = NEW_C_HEAP_ARRAY(char, len);
if (m_filepath != NULL) {
strcpy((char*)m_filepath, filepath);
m_file = fopen(filepath, "r");
if (m_file != NULL) {
load_tables();
} else {
m_status = Decoder::file_not_found;
}
} else {
m_status = Decoder::out_of_memory;
}
}
ElfFile::~ElfFile() {
if (m_string_tables != NULL) {
delete m_string_tables;
}
if (m_symbol_tables != NULL) {
delete m_symbol_tables;
}
if (m_file != NULL) {
fclose(m_file);
}
if (m_filepath != NULL) {
FREE_C_HEAP_ARRAY(char, m_filepath);
}
if (m_next != NULL) {
delete m_next;
}
};
//Check elf header to ensure the file is valid.
bool ElfFile::is_elf_file(Elf_Ehdr& hdr) {
return (ELFMAG0 == hdr.e_ident[EI_MAG0] &&
ELFMAG1 == hdr.e_ident[EI_MAG1] &&
ELFMAG2 == hdr.e_ident[EI_MAG2] &&
ELFMAG3 == hdr.e_ident[EI_MAG3] &&
ELFCLASSNONE != hdr.e_ident[EI_CLASS] &&
ELFDATANONE != hdr.e_ident[EI_DATA]);
}
bool ElfFile::load_tables() {
assert(m_file, "file not open");
assert(m_status == Decoder::no_error, "already in error");
// read elf file header
if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
m_status = Decoder::file_invalid;
return false;
}
if (!is_elf_file(m_elfHdr)) {
m_status = Decoder::file_invalid;
return false;
}
// walk elf file's section headers, and load string tables
Elf_Shdr shdr;
if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
if (m_status != Decoder::no_error) return false;
for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
m_status = Decoder::file_invalid;
return false;
}
// string table
if (shdr.sh_type == SHT_STRTAB) {
ElfStringTable* table = new ElfStringTable(m_file, shdr, index);
if (table == NULL) {
m_status = Decoder::out_of_memory;
return false;
}
add_string_table(table);
} else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
ElfSymbolTable* table = new ElfSymbolTable(m_file, shdr);
if (table == NULL) {
m_status = Decoder::out_of_memory;
return false;
}
add_symbol_table(table);
}
}
}
return true;
}
const char* ElfFile::decode(address addr, int* offset) {
// something already went wrong, just give up
if (m_status != Decoder::no_error) {
return NULL;
}
ElfSymbolTable* symbol_table = m_symbol_tables;
int string_table_index;
int pos_in_string_table;
int off = INT_MAX;
bool found_symbol = false;
while (symbol_table != NULL) {
if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
found_symbol = true;
}
symbol_table = symbol_table->m_next;
}
if (!found_symbol) return NULL;
ElfStringTable* string_table = get_string_table(string_table_index);
if (string_table == NULL) {
m_status = Decoder::file_invalid;
return NULL;
}
if (offset) *offset = off;
return string_table->string_at(pos_in_string_table);
}
void ElfFile::add_symbol_table(ElfSymbolTable* table) {
if (m_symbol_tables == NULL) {
m_symbol_tables = table;
} else {
table->m_next = m_symbol_tables;
m_symbol_tables = table;
}
}
void ElfFile::add_string_table(ElfStringTable* table) {
if (m_string_tables == NULL) {
m_string_tables = table;
} else {
table->m_next = m_string_tables;
m_string_tables = table;
}
}
ElfStringTable* ElfFile::get_string_table(int index) {
ElfStringTable* p = m_string_tables;
while (p != NULL) {
if (p->index() == index) return p;
p = p->m_next;
}
return NULL;
}
#endif // _WINDOWS
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#ifndef __ELF_FILE_HPP
#define __ELF_FILE_HPP
#ifndef _WINDOWS
#include <elf.h>
#include <stdio.h>
#ifdef _LP64
typedef Elf64_Half Elf_Half;
typedef Elf64_Word Elf_Word;
typedef Elf64_Off Elf_Off;
typedef Elf64_Addr Elf_Addr;
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Sym Elf_Sym;
#define ELF_ST_TYPE ELF64_ST_TYPE
#else
typedef Elf32_Half Elf_Half;
typedef Elf32_Word Elf_Word;
typedef Elf32_Off Elf_Off;
typedef Elf32_Addr Elf_Addr;
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Sym Elf_Sym;
#define ELF_ST_TYPE ELF32_ST_TYPE
#endif
#include "globalDefinitions.hpp"
#include "memory/allocation.hpp"
#include "utilities/decoder.hpp"
class ElfStringTable;
class ElfSymbolTable;
// On Solaris/Linux platforms, libjvm.so does contain all private symbols.
// ElfFile is basically an elf file parser, which can lookup the symbol
// that is the nearest to the given address.
// Beware, this code is called from vm error reporting code, when vm is already
// in "error" state, so there are scenarios, lookup will fail. We want this
// part of code to be very defensive, and bait out if anything went wrong.
class ElfFile: public CHeapObj {
friend class Decoder;
public:
ElfFile(const char* filepath);
~ElfFile();
const char* decode(address addr, int* offset);
const char* filepath() {
return m_filepath;
}
bool same_elf_file(const char* filepath) {
assert(filepath, "null file path");
assert(m_filepath, "already out of memory");
return (m_filepath && !strcmp(filepath, m_filepath));
}
Decoder::decoder_status get_status() {
return m_status;
}
private:
// sanity check, if the file is a real elf file
bool is_elf_file(Elf_Ehdr&);
// load string tables from the elf file
bool load_tables();
// string tables are stored in a linked list
void add_string_table(ElfStringTable* table);
// symbol tables are stored in a linked list
void add_symbol_table(ElfSymbolTable* table);
// return a string table at specified section index
ElfStringTable* get_string_table(int index);
// look up an address and return the nearest symbol
const char* look_up(Elf_Shdr shdr, address addr, int* offset);
protected:
ElfFile* m_next;
private:
// file
const char* m_filepath;
FILE* m_file;
// Elf header
Elf_Ehdr m_elfHdr;
// symbol tables
ElfSymbolTable* m_symbol_tables;
// string tables
ElfStringTable* m_string_tables;
Decoder::decoder_status m_status;
};
#endif // _WINDOWS
#endif // __ELF_FILE_HPP
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "precompiled.hpp"
#ifndef _WINDOWS
#include "memory/allocation.inline.hpp"
#include "utilities/elfStringTable.hpp"
// We will try to load whole string table into memory if we can.
// Otherwise, fallback to more expensive file operation.
ElfStringTable::ElfStringTable(FILE* file, Elf_Shdr shdr, int index) {
assert(file, "null file handle");
m_table = NULL;
m_index = index;
m_next = NULL;
m_file = file;
m_status = Decoder::no_error;
// try to load the string table
long cur_offset = ftell(file);
m_table = (char*)NEW_C_HEAP_ARRAY(char, shdr.sh_size);
if (m_table != NULL) {
// if there is an error, mark the error
if (fseek(file, shdr.sh_offset, SEEK_SET) ||
fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
fseek(file, cur_offset, SEEK_SET)) {
m_status = Decoder::file_invalid;
FREE_C_HEAP_ARRAY(char, m_table);
m_table = NULL;
}
} else {
memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
}
}
ElfStringTable::~ElfStringTable() {
if (m_table != NULL) {
FREE_C_HEAP_ARRAY(char, m_table);
}
if (m_next != NULL) {
delete m_next;
}
}
const char* ElfStringTable::string_at(int pos) {
if (m_status != Decoder::no_error) {
return NULL;
}
if (m_table != NULL) {
return (const char*)(m_table + pos);
} else {
long cur_pos = ftell(m_file);
if (cur_pos == -1 ||
fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 ||
fseek(m_file, cur_pos, SEEK_SET)) {
m_status = Decoder::file_invalid;
return NULL;
}
return (const char*)m_symbol;
}
}
#endif // _WINDOWS
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#ifndef __ELF_STRING_TABLE_HPP
#define __ELF_STRING_TABLE_HPP
#ifndef _WINDOWS
#include "memory/allocation.hpp"
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
// The string table represents a string table section in an elf file.
// Whenever there is enough memory, it will load whole string table as
// one blob. Otherwise, it will load string from file when requested.
#define MAX_SYMBOL_LEN 256
class ElfStringTable: CHeapObj {
friend class ElfFile;
public:
ElfStringTable(FILE* file, Elf_Shdr shdr, int index);
~ElfStringTable();
// section index
int index() { return m_index; };
// get string at specified offset
const char* string_at(int offset);
// get status code
Decoder::decoder_status get_status() { return m_status; };
protected:
ElfStringTable* m_next;
// section index
int m_index;
// holds complete string table if can
// allocate enough memory
const char* m_table;
// file contains string table
FILE* m_file;
// section header
Elf_Shdr m_shdr;
// buffer for reading individual string
char m_symbol[MAX_SYMBOL_LEN];
// error code
Decoder::decoder_status m_status;
};
#endif // _WINDOWS
#endif // __ELF_STRING_TABLE_HPP
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#include "precompiled.hpp"
#ifndef _WINDOWS
#include "memory/allocation.inline.hpp"
#include "utilities/elfSymbolTable.hpp"
ElfSymbolTable::ElfSymbolTable(FILE* file, Elf_Shdr shdr) {
assert(file, "null file handle");
m_symbols = NULL;
m_next = NULL;
m_file = file;
m_status = Decoder::no_error;
// try to load the string table
long cur_offset = ftell(file);
if (cur_offset != -1) {
m_symbols = (Elf_Sym*)NEW_C_HEAP_ARRAY(char, shdr.sh_size);
if (m_symbols) {
if (fseek(file, shdr.sh_offset, SEEK_SET) ||
fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
fseek(file, cur_offset, SEEK_SET)) {
m_status = Decoder::file_invalid;
FREE_C_HEAP_ARRAY(char, m_symbols);
m_symbols = NULL;
}
}
if (m_status == Decoder::no_error) {
memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
}
} else {
m_status = Decoder::file_invalid;
}
}
ElfSymbolTable::~ElfSymbolTable() {
if (m_symbols != NULL) {
FREE_C_HEAP_ARRAY(char, m_symbols);
}
if (m_next != NULL) {
delete m_next;
}
}
Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
assert(stringtableIndex, "null string table index pointer");
assert(posIndex, "null string table offset pointer");
assert(offset, "null offset pointer");
if (m_status != Decoder::no_error) {
return m_status;
}
address pc = 0;
size_t sym_size = sizeof(Elf_Sym);
assert((m_shdr.sh_size % sym_size) == 0, "check size");
int count = m_shdr.sh_size / sym_size;
if (m_symbols != NULL) {
for (int index = 0; index < count; index ++) {
if (STT_FUNC == ELF_ST_TYPE(m_symbols[index].st_info)) {
address sym_addr = (address)m_symbols[index].st_value;
if (sym_addr < addr && (addr - sym_addr) < *offset) {
pc = (address)m_symbols[index].st_value;
*offset = (int)(addr - pc);
*posIndex = m_symbols[index].st_name;
*stringtableIndex = m_shdr.sh_link;
}
}
}
} else {
long cur_pos;
if ((cur_pos = ftell(m_file)) == -1 ||
fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
m_status = Decoder::file_invalid;
return m_status;
}
Elf_Sym sym;
for (int index = 0; index < count; index ++) {
if (fread(&sym, sym_size, 1, m_file) == 1) {
if (STT_FUNC == ELF_ST_TYPE(sym.st_info)) {
address sym_addr = (address)sym.st_value;
if (sym_addr < addr && (addr - sym_addr) < *offset) {
pc = (address)sym.st_value;
*offset = (int)(addr - pc);
*posIndex = sym.st_name;
*stringtableIndex = m_shdr.sh_link;
}
}
} else {
m_status = Decoder::file_invalid;
return m_status;
}
}
fseek(m_file, cur_pos, SEEK_SET);
}
return m_status;
}
#endif // _WINDOWS
/*
* Copyright (c) 1997, 2010, 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.
*
* 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.
*
*/
#ifndef __ELF_SYMBOL_TABLE_HPP
#define __ELF_SYMBOL_TABLE_HPP
#ifndef _WINDOWS
#include "memory/allocation.hpp"
#include "utilities/decoder.hpp"
#include "utilities/elfFile.hpp"
/*
* symbol table object represents a symbol section in an elf file.
* Whenever possible, it will load all symbols from the corresponding section
* of the elf file into memory. Otherwise, it will walk the section in file
* to look up the symbol that nearest the given address.
*/
class ElfSymbolTable: public CHeapObj {
friend class ElfFile;
public:
ElfSymbolTable(FILE* file, Elf_Shdr shdr);
~ElfSymbolTable();
// search the symbol that is nearest to the specified address.
Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
Decoder::decoder_status get_status() { return m_status; };
protected:
ElfSymbolTable* m_next;
// holds a complete symbol table section if
// can allocate enough memory
Elf_Sym* m_symbols;
// file contains string table
FILE* m_file;
// section header
Elf_Shdr m_shdr;
Decoder::decoder_status m_status;
};
#endif // _WINDOWS
#endif // __ELF_SYMBOL_TABLE_HPP
......@@ -33,6 +33,7 @@
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "utilities/debug.hpp"
#include "utilities/decoder.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
......@@ -516,8 +517,10 @@ void VMError::report(outputStream* st) {
if (fr.pc()) {
st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
int count = 0;
// initialize decoder to decode C frames
Decoder decoder;
int count = 0;
while (count++ < StackPrintLimit) {
fr.print_on_error(st, buf, sizeof(buf));
st->cr();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部