Merge
This commit is contained in:
commit
52eca7d40b
@ -445,3 +445,4 @@ b803e6cff41e72a1e6d8782e1ef7c25a6e3e5ee3 jdk-10+19
|
||||
d2982a786f53814367698e63efe6349c9128e1db jdk-9+180
|
||||
b656dea9398ef601f7fc08d1a5157a560e0ccbe0 jdk-9+181
|
||||
682e2a6df836f4731f92eb2ddcd467075047f6ea jdk-10+20
|
||||
90cdfe56f1543267a8005e638bd1b44551fda189 jdk-10+21
|
||||
|
@ -1046,7 +1046,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
|
||||
# Set some additional per-CPU defines.
|
||||
if test "x$OPENJDK_$1_OS-$OPENJDK_$1_CPU" = xwindows-x86; then
|
||||
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -arch:IA32"
|
||||
elif test "x$OPENJDK_$1_CPU" = xsparcv9; then
|
||||
elif test "x$OPENJDK_$1_OS-$OPENJDK_$1_CPU" = xsolaris-sparcv9; then
|
||||
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -xarch=sparc"
|
||||
elif test "x$OPENJDK_$1_CPU" = xppc64; then
|
||||
if test "x$OPENJDK_$1_OS" = xlinux; then
|
||||
@ -1358,7 +1358,7 @@ $2LDFLAGS_JDKLIB="${$2LDFLAGS_JDKLIB} ${$2JAVA_BASE_LDFLAGS}"
|
||||
$2SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
|
||||
fi
|
||||
$2JVM_LIBS="[$]$2JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
|
||||
-lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
|
||||
-lthread -ldoor -lc -ldemangle -lnsl -lrt"
|
||||
elif test "x$OPENJDK_$1_OS" = xmacosx; then
|
||||
$2JVM_LIBS="[$]$2JVM_LIBS -lm"
|
||||
elif test "x$OPENJDK_$1_OS" = xaix; then
|
||||
|
@ -5151,7 +5151,7 @@ VS_SDK_PLATFORM_NAME_2013=
|
||||
#CUSTOM_AUTOCONF_INCLUDE
|
||||
|
||||
# Do not change or remove the following line, it is needed for consistency checks:
|
||||
DATE_WHEN_GENERATED=1503411624
|
||||
DATE_WHEN_GENERATED=1504187184
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -15719,6 +15719,12 @@ test -n "$target_alias" &&
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
alpha*)
|
||||
VAR_CPU=alpha
|
||||
VAR_CPU_ARCH=alpha
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
arm*)
|
||||
VAR_CPU=arm
|
||||
VAR_CPU_ARCH=arm
|
||||
@ -15731,6 +15737,36 @@ test -n "$target_alias" &&
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
m68k)
|
||||
VAR_CPU=m68k
|
||||
VAR_CPU_ARCH=m68k
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mips)
|
||||
VAR_CPU=mips
|
||||
VAR_CPU_ARCH=mips
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mipsel)
|
||||
VAR_CPU=mipsel
|
||||
VAR_CPU_ARCH=mipsel
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
mips64)
|
||||
VAR_CPU=mips64
|
||||
VAR_CPU_ARCH=mips64
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mips64el)
|
||||
VAR_CPU=mips64el
|
||||
VAR_CPU_ARCH=mips64el
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
powerpc)
|
||||
VAR_CPU=ppc
|
||||
VAR_CPU_ARCH=ppc
|
||||
@ -15761,6 +15797,18 @@ test -n "$target_alias" &&
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
sh*eb)
|
||||
VAR_CPU=sh
|
||||
VAR_CPU_ARCH=sh
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
sh*)
|
||||
VAR_CPU=sh
|
||||
VAR_CPU_ARCH=sh
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
sparc)
|
||||
VAR_CPU=sparc
|
||||
VAR_CPU_ARCH=sparc
|
||||
@ -15858,6 +15906,12 @@ $as_echo "$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" >&6; }
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
alpha*)
|
||||
VAR_CPU=alpha
|
||||
VAR_CPU_ARCH=alpha
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
arm*)
|
||||
VAR_CPU=arm
|
||||
VAR_CPU_ARCH=arm
|
||||
@ -15870,6 +15924,36 @@ $as_echo "$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" >&6; }
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
m68k)
|
||||
VAR_CPU=m68k
|
||||
VAR_CPU_ARCH=m68k
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mips)
|
||||
VAR_CPU=mips
|
||||
VAR_CPU_ARCH=mips
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mipsel)
|
||||
VAR_CPU=mipsel
|
||||
VAR_CPU_ARCH=mipsel
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
mips64)
|
||||
VAR_CPU=mips64
|
||||
VAR_CPU_ARCH=mips64
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mips64el)
|
||||
VAR_CPU=mips64el
|
||||
VAR_CPU_ARCH=mips64el
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
powerpc)
|
||||
VAR_CPU=ppc
|
||||
VAR_CPU_ARCH=ppc
|
||||
@ -15900,6 +15984,18 @@ $as_echo "$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" >&6; }
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
sh*eb)
|
||||
VAR_CPU=sh
|
||||
VAR_CPU_ARCH=sh
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
sh*)
|
||||
VAR_CPU=sh
|
||||
VAR_CPU_ARCH=sh
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
sparc)
|
||||
VAR_CPU=sparc
|
||||
VAR_CPU_ARCH=sparc
|
||||
@ -16045,6 +16141,12 @@ $as_echo "$COMPILE_TYPE" >&6; }
|
||||
elif test "x$OPENJDK_TARGET_OS" != xmacosx && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
|
||||
# On all platforms except MacOSX replace x86_64 with amd64.
|
||||
OPENJDK_TARGET_CPU_LEGACY="amd64"
|
||||
elif test "x$OPENJDK_TARGET_CPU" = xalpha; then
|
||||
# Avoid name collisions with variables named alpha
|
||||
OPENJDK_TARGET_CPU_LEGACY="_alpha_"
|
||||
elif test "x$OPENJDK_TARGET_CPU" = xsh; then
|
||||
# Avoid name collisions with variables named sh
|
||||
OPENJDK_TARGET_CPU_LEGACY="_sh_"
|
||||
fi
|
||||
|
||||
|
||||
@ -16197,6 +16299,12 @@ $as_echo "$COMPILE_TYPE" >&6; }
|
||||
elif test "x$OPENJDK_BUILD_OS" != xmacosx && test "x$OPENJDK_BUILD_CPU" = xx86_64; then
|
||||
# On all platforms except MacOSX replace x86_64 with amd64.
|
||||
OPENJDK_BUILD_CPU_LEGACY="amd64"
|
||||
elif test "x$OPENJDK_BUILD_CPU" = xalpha; then
|
||||
# Avoid name collisions with variables named alpha
|
||||
OPENJDK_BUILD_CPU_LEGACY="_alpha_"
|
||||
elif test "x$OPENJDK_BUILD_CPU" = xsh; then
|
||||
# Avoid name collisions with variables named sh
|
||||
OPENJDK_BUILD_CPU_LEGACY="_sh_"
|
||||
fi
|
||||
|
||||
|
||||
@ -51563,7 +51671,7 @@ $as_echo "$as_me: GCC >= 6 detected; adding ${NO_DELETE_NULL_POINTER_CHECKS_CFLA
|
||||
# Set some additional per-CPU defines.
|
||||
if test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = xwindows-x86; then
|
||||
JVM_CFLAGS="$JVM_CFLAGS -arch:IA32"
|
||||
elif test "x$OPENJDK_TARGET_CPU" = xsparcv9; then
|
||||
elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = xsolaris-sparcv9; then
|
||||
JVM_CFLAGS="$JVM_CFLAGS -xarch=sparc"
|
||||
elif test "x$OPENJDK_TARGET_CPU" = xppc64; then
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
@ -51968,7 +52076,7 @@ LDFLAGS_JDKLIB="${LDFLAGS_JDKLIB} ${JAVA_BASE_LDFLAGS}"
|
||||
SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
|
||||
fi
|
||||
JVM_LIBS="$JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
|
||||
-lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
|
||||
-lthread -ldoor -lc -ldemangle -lnsl -lrt"
|
||||
elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
JVM_LIBS="$JVM_LIBS -lm"
|
||||
elif test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
@ -52442,7 +52550,7 @@ $as_echo "$as_me: GCC >= 6 detected; adding ${NO_DELETE_NULL_POINTER_CHECKS_CFLA
|
||||
# Set some additional per-CPU defines.
|
||||
if test "x$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" = xwindows-x86; then
|
||||
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -arch:IA32"
|
||||
elif test "x$OPENJDK_BUILD_CPU" = xsparcv9; then
|
||||
elif test "x$OPENJDK_BUILD_OS-$OPENJDK_BUILD_CPU" = xsolaris-sparcv9; then
|
||||
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -xarch=sparc"
|
||||
elif test "x$OPENJDK_BUILD_CPU" = xppc64; then
|
||||
if test "x$OPENJDK_BUILD_OS" = xlinux; then
|
||||
@ -52847,7 +52955,7 @@ OPENJDK_BUILD_LDFLAGS_JDKLIB="${OPENJDK_BUILD_LDFLAGS_JDKLIB} ${OPENJDK_BUILD_JA
|
||||
OPENJDK_BUILD_SOLARIS_LIBM_LIBS="/usr/lib/sparcv9/libm.so.1"
|
||||
fi
|
||||
OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lsocket -lsched -ldl $SOLARIS_LIBM_LIBS -lCrun \
|
||||
-lthread -ldoor -lc -ldemangle -lnsl -lkstat -lrt"
|
||||
-lthread -ldoor -lc -ldemangle -lnsl -lrt"
|
||||
elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
|
||||
OPENJDK_BUILD_JVM_LIBS="$OPENJDK_BUILD_JVM_LIBS -lm"
|
||||
elif test "x$OPENJDK_BUILD_OS" = xaix; then
|
||||
|
@ -42,6 +42,12 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_CPU],
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
alpha*)
|
||||
VAR_CPU=alpha
|
||||
VAR_CPU_ARCH=alpha
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
arm*)
|
||||
VAR_CPU=arm
|
||||
VAR_CPU_ARCH=arm
|
||||
@ -54,6 +60,36 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_CPU],
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
m68k)
|
||||
VAR_CPU=m68k
|
||||
VAR_CPU_ARCH=m68k
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mips)
|
||||
VAR_CPU=mips
|
||||
VAR_CPU_ARCH=mips
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mipsel)
|
||||
VAR_CPU=mipsel
|
||||
VAR_CPU_ARCH=mipsel
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
mips64)
|
||||
VAR_CPU=mips64
|
||||
VAR_CPU_ARCH=mips64
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
mips64el)
|
||||
VAR_CPU=mips64el
|
||||
VAR_CPU_ARCH=mips64el
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
powerpc)
|
||||
VAR_CPU=ppc
|
||||
VAR_CPU_ARCH=ppc
|
||||
@ -84,6 +120,18 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_CPU],
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
sh*eb)
|
||||
VAR_CPU=sh
|
||||
VAR_CPU_ARCH=sh
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
sh*)
|
||||
VAR_CPU=sh
|
||||
VAR_CPU_ARCH=sh
|
||||
VAR_CPU_BITS=32
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
sparc)
|
||||
VAR_CPU=sparc
|
||||
VAR_CPU_ARCH=sparc
|
||||
@ -289,6 +337,12 @@ AC_DEFUN([PLATFORM_SETUP_LEGACY_VARS_HELPER],
|
||||
elif test "x$OPENJDK_$1_OS" != xmacosx && test "x$OPENJDK_$1_CPU" = xx86_64; then
|
||||
# On all platforms except MacOSX replace x86_64 with amd64.
|
||||
OPENJDK_$1_CPU_LEGACY="amd64"
|
||||
elif test "x$OPENJDK_$1_CPU" = xalpha; then
|
||||
# Avoid name collisions with variables named alpha
|
||||
OPENJDK_$1_CPU_LEGACY="_alpha_"
|
||||
elif test "x$OPENJDK_$1_CPU" = xsh; then
|
||||
# Avoid name collisions with variables named sh
|
||||
OPENJDK_$1_CPU_LEGACY="_sh_"
|
||||
fi
|
||||
AC_SUBST(OPENJDK_$1_CPU_LEGACY)
|
||||
|
||||
|
@ -200,7 +200,7 @@ var getJibProfiles = function (input) {
|
||||
data.configuration_make_arg = "CONF_NAME=";
|
||||
|
||||
// Exclude list to use when Jib creates a source bundle
|
||||
data.src_bundle_excludes = "./build webrev .hg */.hg */*/.hg */*/*/.hg";
|
||||
data.src_bundle_excludes = "./build webrev* */webrev* */*/webrev* */*/*/webrev* .hg */.hg */*/.hg */*/*/.hg";
|
||||
// Include list to use when creating a minimal jib source bundle which
|
||||
// contains just the jib configuration files.
|
||||
data.conf_bundle_includes = "*/conf/jib-profiles.* common/autoconf/version-numbers"
|
||||
|
@ -445,3 +445,4 @@ a923b3f30e7bddb4f960059ddfc7978fc63e2e6e jdk-10+18
|
||||
6ce6cb8ff41c71c49f23b15e0f0468aca5d52b17 jdk-9+180
|
||||
ba71941ad9dba53b8fffb30602ef673eee88696c jdk-9+181
|
||||
7a54ec280513a33e49e60546c0cf9ca573925a43 jdk-10+20
|
||||
68b5f8eeac3325c02aac2f4b452b8a37c20c970e jdk-10+21
|
||||
|
@ -605,3 +605,4 @@ c9d3317623d48da3327232c81e3f8cfc0d29d888 jdk-10+18
|
||||
d7baadc223e790c08bc69bf7e553bce65b4e7e40 jdk-9+180
|
||||
4a443796f6f57842d6a0434ac27ca3d1033ccc20 jdk-9+181
|
||||
e93ed1a092409351c90b3a76d80b9aa8b44d5e6a jdk-10+20
|
||||
bdb2dbc43ff065b74c2121bdfb0d6e1fa8684b73 jdk-10+21
|
||||
|
@ -3806,15 +3806,24 @@ void Compile::reshape_address(AddPNode* addp) {
|
||||
// Any use that can't embed the address computation?
|
||||
for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
|
||||
Node* u = addp->fast_out(i);
|
||||
if (!u->is_Mem() || u->is_LoadVector() || u->is_StoreVector() || u->Opcode() == Op_StoreCM) {
|
||||
if (!u->is_Mem()) {
|
||||
return;
|
||||
}
|
||||
if (u->is_LoadVector() || u->is_StoreVector() || u->Opcode() == Op_StoreCM) {
|
||||
return;
|
||||
}
|
||||
if (addp2->in(AddPNode::Offset)->Opcode() != Op_ConvI2L) {
|
||||
int scale = 1 << addp2->in(AddPNode::Offset)->in(2)->get_int();
|
||||
if (VM_Version::expensive_load(u->as_Mem()->memory_size(), scale)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Node* off = addp->in(AddPNode::Offset);
|
||||
Node* addr2 = addp2->in(AddPNode::Address);
|
||||
Node* base = addp->in(AddPNode::Base);
|
||||
|
||||
|
||||
Node* new_addr = NULL;
|
||||
// Check whether the graph already has the new AddP we need
|
||||
// before we create one (no GVN available here).
|
||||
@ -3828,7 +3837,7 @@ void Compile::reshape_address(AddPNode* addp) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (new_addr == NULL) {
|
||||
new_addr = new AddPNode(base, addr2, off);
|
||||
}
|
||||
@ -4415,6 +4424,22 @@ encode %{
|
||||
/*weak*/ false, noreg);
|
||||
%}
|
||||
|
||||
enc_class aarch64_enc_cmpxchgs(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
|
||||
Assembler::halfword, /*acquire*/ false, /*release*/ true,
|
||||
/*weak*/ false, noreg);
|
||||
%}
|
||||
|
||||
enc_class aarch64_enc_cmpxchgb(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
|
||||
Assembler::byte, /*acquire*/ false, /*release*/ true,
|
||||
/*weak*/ false, noreg);
|
||||
%}
|
||||
|
||||
|
||||
// The only difference between aarch64_enc_cmpxchg and
|
||||
// aarch64_enc_cmpxchg_acq is that we use load-acquire in the
|
||||
@ -9637,6 +9662,42 @@ instruct storeIConditional(indirect mem, iRegINoSp oldval, iRegINoSp newval, rFl
|
||||
// XXX No flag versions for CompareAndSwap{I,L,P,N} because matcher
|
||||
// can't match them
|
||||
|
||||
instruct compareAndSwapB(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
|
||||
|
||||
match(Set res (CompareAndSwapB mem (Binary oldval newval)));
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
effect(KILL cr);
|
||||
|
||||
format %{
|
||||
"cmpxchgb $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||
%}
|
||||
|
||||
ins_encode(aarch64_enc_cmpxchgb(mem, oldval, newval),
|
||||
aarch64_enc_cset_eq(res));
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct compareAndSwapS(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
|
||||
|
||||
match(Set res (CompareAndSwapS mem (Binary oldval newval)));
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
effect(KILL cr);
|
||||
|
||||
format %{
|
||||
"cmpxchgs $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
|
||||
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||
%}
|
||||
|
||||
ins_encode(aarch64_enc_cmpxchgs(mem, oldval, newval),
|
||||
aarch64_enc_cset_eq(res));
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct compareAndSwapI(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
|
||||
|
||||
match(Set res (CompareAndSwapI mem (Binary oldval newval)));
|
||||
@ -12597,6 +12658,64 @@ instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask m
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// We can use ubfiz when masking by a positive number and then left shifting the result.
|
||||
// We know that the mask is positive because immI_bitmask guarantees it.
|
||||
instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
|
||||
%{
|
||||
match(Set dst (LShiftI (AndI src mask) lshift));
|
||||
predicate((unsigned int)n->in(2)->get_int() <= 31 &&
|
||||
(exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfizw $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant;
|
||||
long mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfizw(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
// We can use ubfiz when masking by a positive number and then left shifting the result.
|
||||
// We know that the mask is positive because immL_bitmask guarantees it.
|
||||
instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
|
||||
%{
|
||||
match(Set dst (LShiftL (AndL src mask) lshift));
|
||||
predicate((unsigned int)n->in(2)->get_int() <= 63 &&
|
||||
(exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant;
|
||||
long mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfiz(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
|
||||
instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
|
||||
%{
|
||||
match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
|
||||
predicate((unsigned int)n->in(2)->get_int() <= 31 &&
|
||||
(exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant;
|
||||
long mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfiz(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// Rotations
|
||||
|
||||
instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
|
||||
|
@ -214,6 +214,48 @@ instruct ubfxIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI rshift, immI_bitmask m
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
define(`UBFIZ_INSN',
|
||||
// We can use ubfiz when masking by a positive number and then left shifting the result.
|
||||
// We know that the mask is positive because imm$1_bitmask guarantees it.
|
||||
`instruct $2$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, imm$1_bitmask mask)
|
||||
%{
|
||||
match(Set dst (LShift$1 (And$1 src mask) lshift));
|
||||
predicate((unsigned int)n->in(2)->get_int() <= $3 &&
|
||||
(exact_log2$5(n->in(1)->in(2)->get_$4()+1) + (unsigned int)n->in(2)->get_int()) <= ($3+1));
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "$2 $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant;
|
||||
long mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ $2(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}')
|
||||
UBFIZ_INSN(I, ubfizw, 31, int)
|
||||
UBFIZ_INSN(L, ubfiz, 63, long, _long)
|
||||
|
||||
// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
|
||||
instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
|
||||
%{
|
||||
match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
|
||||
predicate((unsigned int)n->in(2)->get_int() <= 31 &&
|
||||
(exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant;
|
||||
long mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfiz(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// Rotations
|
||||
|
||||
define(`EXTRACT_INSN',
|
||||
|
@ -272,8 +272,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
// load pointer for resolved_references[] objArray
|
||||
ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
|
||||
ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
|
||||
// JNIHandles::resolve(obj);
|
||||
ldr(result, Address(result, 0));
|
||||
resolve_oop_handle(result);
|
||||
// Add in the index
|
||||
add(result, result, tmp);
|
||||
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
|
||||
|
@ -3279,6 +3279,12 @@ void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
}
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
ldr(result, Address(result, 0));
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register dst, Register method) {
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
ldr(dst, Address(rmethod, Method::const_offset()));
|
||||
|
@ -790,6 +790,7 @@ public:
|
||||
void store_klass(Register dst, Register src);
|
||||
void cmp_klass(Register oop, Register trial_klass, Register tmp);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register dst, Register method);
|
||||
|
||||
void load_heap_oop(Register dst, Address src);
|
||||
|
@ -56,6 +56,17 @@ public:
|
||||
static void assert_is_initialized() {
|
||||
}
|
||||
|
||||
static bool expensive_load(int ld_size, int scale) {
|
||||
if (cpu_family() == CPU_ARM) {
|
||||
// Half-word load with index shift by 1 (aka scale is 2) has
|
||||
// extra cycle latency, e.g. ldrsh w0, [x1,w2,sxtw #1].
|
||||
if (ld_size == 2 && scale == 2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum Family {
|
||||
CPU_ARM = 'A',
|
||||
CPU_BROADCOM = 'B',
|
||||
|
@ -300,8 +300,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
// load pointer for resolved_references[] objArray
|
||||
ldr(cache, Address(result, ConstantPool::cache_offset_in_bytes()));
|
||||
ldr(cache, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
|
||||
// JNIHandles::resolve(result)
|
||||
ldr(cache, Address(cache, 0));
|
||||
resolve_oop_handle(cache);
|
||||
// Add in the index
|
||||
// convert from field index to resolved_references() index and from
|
||||
// word index to byte offset. Since this is a java object, it can be compressed
|
||||
|
@ -2887,6 +2887,11 @@ int MacroAssembler::patchable_call(address target, RelocationHolder const& rspec
|
||||
return offset();
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
ldr(result, Address(result, 0));
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
@ -2896,6 +2901,7 @@ void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp)
|
||||
ldr(mirror, Address(tmp, mirror_offset));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Compressed pointers
|
||||
|
@ -687,6 +687,7 @@ public:
|
||||
AbstractAssembler::emit_address((address)L.data());
|
||||
}
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register mirror, Register method, Register tmp);
|
||||
|
||||
// Porting layer between 32-bit ARM and AArch64
|
||||
|
@ -559,7 +559,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
values.print(p);
|
||||
}
|
||||
if (Verbose) {
|
||||
if (has_mh && mh->is_oop()) {
|
||||
if (has_mh && oopDesc::is_oop(mh)) {
|
||||
mh->print();
|
||||
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
|
||||
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
|
||||
|
@ -464,8 +464,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
|
||||
// Load pointer for resolved_references[] objArray.
|
||||
ld(result, ConstantPool::cache_offset_in_bytes(), result);
|
||||
ld(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
|
||||
// JNIHandles::resolve(result)
|
||||
ld(result, 0, result);
|
||||
resolve_oop_handle(result);
|
||||
#ifdef ASSERT
|
||||
Label index_ok;
|
||||
lwa(R0, arrayOopDesc::length_offset_in_bytes(), result);
|
||||
|
@ -3372,6 +3372,12 @@ void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
}
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
ld(result, 0, result);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror_from_const_method(Register mirror, Register const_method) {
|
||||
ld(mirror, in_bytes(ConstMethod::constants_offset()), const_method);
|
||||
ld(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
|
||||
|
@ -725,6 +725,7 @@ class MacroAssembler: public Assembler {
|
||||
void store_klass(Register dst_oop, Register klass, Register tmp = R0);
|
||||
void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror_from_const_method(Register mirror, Register const_method);
|
||||
|
||||
static int instr_size_for_decode_klass_not_null();
|
||||
|
@ -525,7 +525,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
values.print(p);
|
||||
}
|
||||
|
||||
if (has_mh && mh->is_oop()) {
|
||||
if (has_mh && oopDesc::is_oop(mh)) {
|
||||
mh->print();
|
||||
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
|
||||
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
|
||||
|
@ -830,7 +830,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// Wrapper which calls oopDesc::is_oop_or_null()
|
||||
// Only called by MacroAssembler::verify_oop
|
||||
static void verify_oop_helper(const char* message, oop o) {
|
||||
if (!o->is_oop_or_null()) {
|
||||
if (!oopDesc::is_oop_or_null(o)) {
|
||||
fatal("%s", message);
|
||||
}
|
||||
++ StubRoutines::_verify_oop_count;
|
||||
|
@ -56,7 +56,7 @@
|
||||
// if too small.
|
||||
// Run with +PrintInterpreter to get the VM to print out the size.
|
||||
// Max size with JVMTI
|
||||
int TemplateInterpreter::InterpreterCodeSize = 230*K;
|
||||
int TemplateInterpreter::InterpreterCodeSize = 256*K;
|
||||
|
||||
#ifdef PRODUCT
|
||||
#define BLOCK_COMMENT(str) /* nothing */
|
||||
|
@ -246,8 +246,8 @@ inline void Assembler::z_mvcle(Register r1, Register r3, int64_t d2, Register b2
|
||||
inline void Assembler::z_mvhhi( int64_t d1, Register b1, int64_t i2) { emit_48( MVHHI_ZOPC | uimm12( d1, 20, 48) | regz(b1, 16, 48) | simm16(i2, 32, 48)); }
|
||||
inline void Assembler::z_mvhi ( int64_t d1, Register b1, int64_t i2) { emit_48( MVHI_ZOPC | uimm12( d1, 20, 48) | regz(b1, 16, 48) | simm16(i2, 32, 48)); }
|
||||
inline void Assembler::z_mvghi( int64_t d1, Register b1, int64_t i2) { emit_48( MVGHI_ZOPC | uimm12( d1, 20, 48) | regz(b1, 16, 48) | simm16(i2, 32, 48)); }
|
||||
inline void Assembler::z_mvhhi( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVHHI"); z_mvghi( d.disp(), d.baseOrR0(), i2); }
|
||||
inline void Assembler::z_mvhi ( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVHI"); z_mvghi( d.disp(), d.baseOrR0(), i2); }
|
||||
inline void Assembler::z_mvhhi( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVHHI"); z_mvhhi( d.disp(), d.baseOrR0(), i2); }
|
||||
inline void Assembler::z_mvhi ( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVHI"); z_mvhi( d.disp(), d.baseOrR0(), i2); }
|
||||
inline void Assembler::z_mvghi( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVGHI"); z_mvghi( d.disp(), d.baseOrR0(), i2); }
|
||||
|
||||
inline void Assembler::z_ex(Register r1, int64_t d2, Register x2, Register b2) { emit_32( EX_ZOPC | regz(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
|
||||
|
@ -105,15 +105,18 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + NativeCall::get_IC_pos_in_java_to_interp_stub());
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
|
||||
#ifdef ASSERT
|
||||
// A generated lambda form might be deleted from the Lambdaform
|
||||
// cache in MethodTypeForm. If a jit compiled lambdaform method
|
||||
// becomes not entrant and the cache access returns null, the new
|
||||
// resolve will lead to a new generated LambdaForm.
|
||||
|
||||
assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee() || callee->is_compiled_lambda_form(),
|
||||
volatile intptr_t data = method_holder->data();
|
||||
volatile address destination = jump->jump_destination();
|
||||
assert(data == 0 || data == (intptr_t)callee() || callee->is_compiled_lambda_form(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#endif
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee());
|
||||
|
@ -364,8 +364,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result
|
||||
// Load pointer for resolved_references[] objArray.
|
||||
z_lg(result, ConstantPool::cache_offset_in_bytes(), result);
|
||||
z_lg(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
|
||||
// JNIHandles::resolve(result)
|
||||
z_lg(result, 0, result); // Load resolved references array itself.
|
||||
resolve_oop_handle(result); // Load resolved references array itself.
|
||||
#ifdef ASSERT
|
||||
NearLabel index_ok;
|
||||
z_lgf(Z_R0, Address(result, arrayOopDesc::length_offset_in_bytes()));
|
||||
|
@ -4660,6 +4660,12 @@ void MacroAssembler::oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL, R
|
||||
}
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
z_lg(result, 0, result);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method) {
|
||||
mem2reg_opt(mirror, Address(method, Method::const_offset()));
|
||||
mem2reg_opt(mirror, Address(mirror, ConstMethod::constants_offset()));
|
||||
|
@ -832,6 +832,7 @@ class MacroAssembler: public Assembler {
|
||||
void oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL,
|
||||
Register Rbase = Z_R1, int pow2_offset = -1);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register mirror, Register method);
|
||||
|
||||
//--------------------------
|
||||
|
@ -595,7 +595,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
// Note: the unextended_sp may not be correct.
|
||||
tty->print_cr(" stack layout:");
|
||||
values.print(p);
|
||||
if (has_mh && mh->is_oop()) {
|
||||
if (has_mh && oopDesc::is_oop(mh)) {
|
||||
mh->print();
|
||||
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
|
||||
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0) {
|
||||
|
@ -730,8 +730,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
// load pointer for resolved_references[] objArray
|
||||
ld_ptr(result, ConstantPool::cache_offset_in_bytes(), result);
|
||||
ld_ptr(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
|
||||
// JNIHandles::resolve(result)
|
||||
ld_ptr(result, 0, result);
|
||||
resolve_oop_handle(result);
|
||||
// Add in the index
|
||||
add(result, tmp, result);
|
||||
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
|
||||
|
@ -3822,6 +3822,12 @@ void MacroAssembler::card_write_barrier_post(Register store_addr, Register new_v
|
||||
card_table_write(bs->byte_map_base, tmp, store_addr);
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
ld_ptr(result, 0, result);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method) {
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
ld_ptr(method, in_bytes(Method::const_offset()), mirror);
|
||||
|
@ -995,6 +995,7 @@ public:
|
||||
inline void ldbool(const Address& a, Register d);
|
||||
inline void movbool( bool boolconst, Register d);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register mirror, Register method);
|
||||
|
||||
// klass oop manipulations if compressed
|
||||
|
@ -562,7 +562,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
// Note: the unextended_sp may not be correct
|
||||
tty->print_cr(" stack layout:");
|
||||
values.print(p);
|
||||
if (has_mh && mh->is_oop()) {
|
||||
if (has_mh && oopDesc::is_oop(mh)) {
|
||||
mh->print();
|
||||
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
|
||||
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
|
||||
|
@ -511,8 +511,7 @@ void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
// load pointer for resolved_references[] objArray
|
||||
movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
|
||||
movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
|
||||
// JNIHandles::resolve(obj);
|
||||
movptr(result, Address(result, 0));
|
||||
resolve_oop_handle(result);
|
||||
// Add in the index
|
||||
addptr(result, tmp);
|
||||
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
|
||||
|
@ -6604,6 +6604,12 @@ void MacroAssembler::restore_cpu_control_state_after_jni() {
|
||||
#endif // _LP64
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
movptr(result, Address(result, 0));
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method) {
|
||||
// get mirror
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
@ -7030,7 +7036,6 @@ void MacroAssembler::reinit_heapbase() {
|
||||
|
||||
#endif // _LP64
|
||||
|
||||
|
||||
// C2 compiled method's prolog code.
|
||||
void MacroAssembler::verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b) {
|
||||
|
||||
|
@ -327,6 +327,7 @@ class MacroAssembler: public Assembler {
|
||||
void movbool(Address dst, Register src);
|
||||
void testbool(Register dst);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register mirror, Register method);
|
||||
|
||||
// oop manipulations
|
||||
|
@ -561,7 +561,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
tty->print_cr("Stack layout:");
|
||||
values.print(p);
|
||||
}
|
||||
if (has_mh && mh->is_oop()) {
|
||||
if (has_mh && oopDesc::is_oop(mh)) {
|
||||
mh->print();
|
||||
if (java_lang_invoke_MethodHandle::is_instance(mh)) {
|
||||
if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 1997, 2017, 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
|
||||
@ -391,7 +391,7 @@ void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec,
|
||||
int format) {
|
||||
#ifdef ASSERT
|
||||
if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) {
|
||||
assert(cast_to_oop(d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||
assert(oopDesc::is_oop(cast_to_oop(d32)) && (ScavengeRootsInCode || !cast_to_oop(d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||
}
|
||||
#endif
|
||||
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2003, 2017, 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
|
||||
@ -653,7 +653,7 @@ void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, in
|
||||
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
||||
d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
|
||||
assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
|
||||
assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||
assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
|
||||
}
|
||||
#endif
|
||||
cbuf.relocate(cbuf.insts_mark(), rspec, format);
|
||||
@ -680,7 +680,7 @@ void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec
|
||||
if (rspec.reloc()->type() == relocInfo::oop_type &&
|
||||
d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
|
||||
assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
|
||||
assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()),
|
||||
assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()),
|
||||
"cannot embed scavengable oops in code");
|
||||
}
|
||||
#endif
|
||||
|
@ -58,7 +58,7 @@ import org.graalvm.compiler.options.OptionValues;
|
||||
* <p>
|
||||
* Methods to record and access code section contents, symbols and relocations are provided.
|
||||
*/
|
||||
public class BinaryContainer implements SymbolTable {
|
||||
public final class BinaryContainer implements SymbolTable {
|
||||
private final OptionValues graalOptions;
|
||||
|
||||
private final int codeSegmentSize;
|
||||
@ -70,20 +70,20 @@ public class BinaryContainer implements SymbolTable {
|
||||
*/
|
||||
private final CodeContainer codeContainer;
|
||||
|
||||
/**
|
||||
* Container holding external hotspot linkage bits (PLT entries).
|
||||
*/
|
||||
private final CodeContainer extLinkageContainer;
|
||||
|
||||
/**
|
||||
* Container holding global offset data for hotspot linkage.
|
||||
*/
|
||||
private final ByteContainer extLinkageGOTContainer;
|
||||
|
||||
/**
|
||||
* Patched by HotSpot, contains metaspace pointers.
|
||||
* Patched by HotSpot, contains Klass pointers.
|
||||
*/
|
||||
private final ByteContainer metaspaceGotContainer;
|
||||
private final ByteContainer klassesGotContainer;
|
||||
|
||||
/**
|
||||
* Patched by HotSpot, contains MethodCounters pointers.
|
||||
*/
|
||||
private final ByteContainer countersGotContainer;
|
||||
|
||||
/**
|
||||
* Patched lazily by hotspot, contains klass/method pointers.
|
||||
@ -268,33 +268,41 @@ public class BinaryContainer implements SymbolTable {
|
||||
this.graalOptions = graalOptions;
|
||||
|
||||
this.codeSegmentSize = graalHotSpotVMConfig.codeSegmentSize;
|
||||
if (codeSegmentSize < 1 || codeSegmentSize > 1024) {
|
||||
throw new InternalError("codeSegmentSize is not in range [1, 1024] bytes: (" + codeSegmentSize + "), update JPECoffRelocObject");
|
||||
}
|
||||
if ((codeSegmentSize & (codeSegmentSize - 1)) != 0) {
|
||||
throw new InternalError("codeSegmentSize is not power of 2: (" + codeSegmentSize + "), update JPECoffRelocObject");
|
||||
}
|
||||
|
||||
this.codeEntryAlignment = graalHotSpotVMConfig.codeEntryAlignment;
|
||||
|
||||
// Section unique name is limited to 8 characters due to limitation on Windows.
|
||||
// Name could be longer but only first 8 characters are stored on Windows.
|
||||
|
||||
// read only, code
|
||||
codeContainer = new CodeContainer(".text", this);
|
||||
extLinkageContainer = new CodeContainer(".hs.plt.linkage", this);
|
||||
|
||||
// read only, info
|
||||
headerContainer = new HeaderContainer(jvmVersion, new ReadOnlyDataContainer(".header", this));
|
||||
configContainer = new ReadOnlyDataContainer(".config", this);
|
||||
metaspaceNamesContainer = new ReadOnlyDataContainer(".meta.names", this);
|
||||
methodsOffsetsContainer = new ReadOnlyDataContainer(".methods.offsets", this);
|
||||
methodsOffsetsContainer = new ReadOnlyDataContainer(".meth.offsets", this);
|
||||
klassesOffsetsContainer = new ReadOnlyDataContainer(".kls.offsets", this);
|
||||
klassesDependenciesContainer = new ReadOnlyDataContainer(".kls.dependencies", this);
|
||||
|
||||
headerContainer = new HeaderContainer(jvmVersion, new ReadOnlyDataContainer(".header", this));
|
||||
stubsOffsetsContainer = new ReadOnlyDataContainer(".stubs.offsets", this);
|
||||
codeSegmentsContainer = new ReadOnlyDataContainer(".code.segments", this);
|
||||
constantDataContainer = new ReadOnlyDataContainer(".meth.constdata", this);
|
||||
|
||||
// needs relocation patching at load time by the loader
|
||||
methodMetadataContainer = new ReadOnlyDataContainer(".meth.metadata", this);
|
||||
|
||||
// writable sections
|
||||
metaspaceGotContainer = new ByteContainer(".meta.got", this);
|
||||
metadataGotContainer = new ByteContainer(".metadata.got", this);
|
||||
methodStateContainer = new ByteContainer(".meth.state", this);
|
||||
oopGotContainer = new ByteContainer(".oop.got", this);
|
||||
extLinkageGOTContainer = new ByteContainer(".hs.got.linkage", this);
|
||||
klassesGotContainer = new ByteContainer(".kls.got", this);
|
||||
countersGotContainer = new ByteContainer(".cnt.got", this);
|
||||
metadataGotContainer = new ByteContainer(".meta.got", this);
|
||||
methodStateContainer = new ByteContainer(".meth.state", this);
|
||||
extLinkageGOTContainer = new ByteContainer(".got.linkage", this);
|
||||
|
||||
addGlobalSymbols();
|
||||
|
||||
@ -368,51 +376,51 @@ public class BinaryContainer implements SymbolTable {
|
||||
* in the named GOT cell.
|
||||
*/
|
||||
|
||||
public String getCardTableAddressSymbolName() {
|
||||
public static String getCardTableAddressSymbolName() {
|
||||
return "_aot_card_table_address";
|
||||
}
|
||||
|
||||
public String getHeapTopAddressSymbolName() {
|
||||
public static String getHeapTopAddressSymbolName() {
|
||||
return "_aot_heap_top_address";
|
||||
}
|
||||
|
||||
public String getHeapEndAddressSymbolName() {
|
||||
public static String getHeapEndAddressSymbolName() {
|
||||
return "_aot_heap_end_address";
|
||||
}
|
||||
|
||||
public String getCrcTableAddressSymbolName() {
|
||||
public static String getCrcTableAddressSymbolName() {
|
||||
return "_aot_stub_routines_crc_table_adr";
|
||||
}
|
||||
|
||||
public String getPollingPageSymbolName() {
|
||||
public static String getPollingPageSymbolName() {
|
||||
return "_aot_polling_page";
|
||||
}
|
||||
|
||||
public String getResolveStaticEntrySymbolName() {
|
||||
public static String getResolveStaticEntrySymbolName() {
|
||||
return "_resolve_static_entry";
|
||||
}
|
||||
|
||||
public String getResolveVirtualEntrySymbolName() {
|
||||
public static String getResolveVirtualEntrySymbolName() {
|
||||
return "_resolve_virtual_entry";
|
||||
}
|
||||
|
||||
public String getResolveOptVirtualEntrySymbolName() {
|
||||
public static String getResolveOptVirtualEntrySymbolName() {
|
||||
return "_resolve_opt_virtual_entry";
|
||||
}
|
||||
|
||||
public String getNarrowKlassBaseAddressSymbolName() {
|
||||
public static String getNarrowKlassBaseAddressSymbolName() {
|
||||
return "_aot_narrow_klass_base_address";
|
||||
}
|
||||
|
||||
public String getNarrowOopBaseAddressSymbolName() {
|
||||
public static String getNarrowOopBaseAddressSymbolName() {
|
||||
return "_aot_narrow_oop_base_address";
|
||||
}
|
||||
|
||||
public String getLogOfHeapRegionGrainBytesSymbolName() {
|
||||
public static String getLogOfHeapRegionGrainBytesSymbolName() {
|
||||
return "_aot_log_of_heap_region_grain_bytes";
|
||||
}
|
||||
|
||||
public String getInlineContiguousAllocationSupportedSymbolName() {
|
||||
public static String getInlineContiguousAllocationSupportedSymbolName() {
|
||||
return "_aot_inline_contiguous_allocation_supported";
|
||||
}
|
||||
|
||||
@ -430,7 +438,7 @@ public class BinaryContainer implements SymbolTable {
|
||||
* @param functionName function name
|
||||
* @return AOT symbol for the given function name, or null if there is no mapping.
|
||||
*/
|
||||
public String getAOTSymbolForVMFunctionName(String functionName) {
|
||||
public static String getAOTSymbolForVMFunctionName(String functionName) {
|
||||
return functionNamesToAOTSymbols.get(functionName);
|
||||
}
|
||||
|
||||
@ -441,7 +449,8 @@ public class BinaryContainer implements SymbolTable {
|
||||
createContainerSymbol(methodsOffsetsContainer);
|
||||
createContainerSymbol(klassesOffsetsContainer);
|
||||
createContainerSymbol(klassesDependenciesContainer);
|
||||
createContainerSymbol(metaspaceGotContainer);
|
||||
createContainerSymbol(klassesGotContainer);
|
||||
createContainerSymbol(countersGotContainer);
|
||||
createContainerSymbol(metadataGotContainer);
|
||||
createContainerSymbol(methodStateContainer);
|
||||
createContainerSymbol(oopGotContainer);
|
||||
@ -469,12 +478,13 @@ public class BinaryContainer implements SymbolTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a global symbol of the form {@code "JVM" + container name}.
|
||||
* Creates a global symbol of the form {@code "A" + container name}.
|
||||
* Note, linker on Windows does not allow names which start with '.'
|
||||
*
|
||||
* @param container container to create a symbol for
|
||||
*/
|
||||
private static void createContainerSymbol(ByteContainer container) {
|
||||
container.createSymbol(0, Kind.OBJECT, Binding.GLOBAL, 0, "JVM" + container.getContainerName());
|
||||
container.createSymbol(0, Kind.OBJECT, Binding.GLOBAL, 0, "A" + container.getContainerName());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -499,12 +509,12 @@ public class BinaryContainer implements SymbolTable {
|
||||
*
|
||||
* @throws IOException in case of file creation failure
|
||||
*/
|
||||
public void createBinary(String outputFileName, String aotVersion) throws IOException {
|
||||
public void createBinary(String outputFileName) throws IOException {
|
||||
String osName = System.getProperty("os.name");
|
||||
switch (osName) {
|
||||
case "Linux":
|
||||
case "SunOS":
|
||||
JELFRelocObject elfobj = new JELFRelocObject(this, outputFileName, aotVersion);
|
||||
JELFRelocObject elfobj = new JELFRelocObject(this, outputFileName);
|
||||
elfobj.createELFRelocObject(relocationTable, symbolTable.values());
|
||||
break;
|
||||
case "Mac OS X":
|
||||
@ -513,7 +523,7 @@ public class BinaryContainer implements SymbolTable {
|
||||
break;
|
||||
default:
|
||||
if (osName.startsWith("Windows")) {
|
||||
JPECoffRelocObject pecoffobj = new JPECoffRelocObject(this, outputFileName, aotVersion);
|
||||
JPECoffRelocObject pecoffobj = new JPECoffRelocObject(this, outputFileName);
|
||||
pecoffobj.createPECoffRelocObject(relocationTable, symbolTable.values());
|
||||
break;
|
||||
} else
|
||||
@ -626,12 +636,6 @@ public class BinaryContainer implements SymbolTable {
|
||||
return startOffset;
|
||||
}
|
||||
|
||||
public int appendMetaspaceGotBytes(byte[] bytes, int offset, int size) {
|
||||
int startOffset = metaspaceGotContainer.getByteStreamSize();
|
||||
appendBytes(metaspaceGotContainer, bytes, offset, size);
|
||||
return startOffset;
|
||||
}
|
||||
|
||||
public void addMetadataGotEntry(int offset) {
|
||||
metadataGotContainer.appendLong(offset);
|
||||
}
|
||||
@ -681,8 +685,7 @@ public class BinaryContainer implements SymbolTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add oop symbol by as follows. Extend the oop.got section with another slot for the VM to
|
||||
* patch.
|
||||
* Add oop symbol by as follows. Extend the oop.got section with another slot for the VM to patch.
|
||||
*
|
||||
* @param oopName name of the oop symbol
|
||||
*/
|
||||
@ -708,13 +711,13 @@ public class BinaryContainer implements SymbolTable {
|
||||
return relocationSymbol.getOffset();
|
||||
}
|
||||
|
||||
public int addMetaspaceSymbol(String metaspaceName) {
|
||||
public int addCountersSymbol(String metaspaceName) {
|
||||
String gotName = "got." + metaspaceName;
|
||||
Symbol relocationSymbol = getGotSymbol(gotName);
|
||||
int metaspaceOffset = -1;
|
||||
if (relocationSymbol == null) {
|
||||
// Add slots when asked in the .metaspace.got section:
|
||||
metaspaceGotContainer.createGotSymbol(gotName);
|
||||
countersGotContainer.createGotSymbol(gotName);
|
||||
}
|
||||
return metaspaceOffset;
|
||||
}
|
||||
@ -725,29 +728,30 @@ public class BinaryContainer implements SymbolTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add metaspace symbol by as follows. - Adding the symbol name to the metaspace.names section -
|
||||
* Add the offset of the name in metaspace.names to metaspace.offsets - Extend the metaspace.got
|
||||
* section with another slot for the VM to patch
|
||||
* Add klass symbol by as follows.
|
||||
* - Adding the symbol name to the metaspace.names section
|
||||
* - Add the offset of the name in metaspace.names to metaspace.offsets
|
||||
* - Extend the klasses.got section with another slot for the VM to patch
|
||||
*
|
||||
* @param metaspaceName name of the metaspace symbol
|
||||
* @return the got offset in the metaspace.got of the metaspace symbol
|
||||
* @param klassName name of the metaspace symbol
|
||||
* @return the got offset in the klasses.got of the metaspace symbol
|
||||
*/
|
||||
public int addTwoSlotMetaspaceSymbol(String metaspaceName) {
|
||||
String gotName = "got." + metaspaceName;
|
||||
public int addTwoSlotKlassSymbol(String klassName) {
|
||||
String gotName = "got." + klassName;
|
||||
Symbol previous = getGotSymbol(gotName);
|
||||
assert previous == null : "should be called only once for: " + metaspaceName;
|
||||
assert previous == null : "should be called only once for: " + klassName;
|
||||
// Add slots when asked in the .metaspace.got section:
|
||||
// First slot
|
||||
String gotInitName = "got.init." + metaspaceName;
|
||||
GotSymbol slot1Symbol = metaspaceGotContainer.createGotSymbol(gotInitName);
|
||||
GotSymbol slot2Symbol = metaspaceGotContainer.createGotSymbol(gotName);
|
||||
String gotInitName = "got.init." + klassName;
|
||||
GotSymbol slot1Symbol = klassesGotContainer.createGotSymbol(gotInitName);
|
||||
GotSymbol slot2Symbol = klassesGotContainer.createGotSymbol(gotName);
|
||||
|
||||
slot1Symbol.getIndex(); // check alignment and ignore result
|
||||
// Get the index (offset/8) to the got in the .metaspace.got section
|
||||
return slot2Symbol.getIndex();
|
||||
}
|
||||
|
||||
public int addMethodsCount(int count, ReadOnlyDataContainer container) {
|
||||
public static int addMethodsCount(int count, ReadOnlyDataContainer container) {
|
||||
return appendInt(count, container);
|
||||
}
|
||||
|
||||
@ -772,7 +776,7 @@ public class BinaryContainer implements SymbolTable {
|
||||
return constantDataOffset;
|
||||
}
|
||||
|
||||
public int alignUp(ByteContainer container, int alignment) {
|
||||
public static int alignUp(ByteContainer container, int alignment) {
|
||||
if (Integer.bitCount(alignment) != 1) {
|
||||
throw new IllegalArgumentException("Must be a power of 2");
|
||||
}
|
||||
@ -814,15 +818,11 @@ public class BinaryContainer implements SymbolTable {
|
||||
appendBytes(codeSegmentsContainer, segments, 0, segmentsCount);
|
||||
}
|
||||
|
||||
public CodeContainer getExtLinkageContainer() {
|
||||
return extLinkageContainer;
|
||||
}
|
||||
|
||||
public ByteContainer getExtLinkageGOTContainer() {
|
||||
return extLinkageGOTContainer;
|
||||
}
|
||||
|
||||
public ByteContainer getMethodMetadataContainer() {
|
||||
public ReadOnlyDataContainer getMethodMetadataContainer() {
|
||||
return methodMetadataContainer;
|
||||
}
|
||||
|
||||
@ -854,8 +854,12 @@ public class BinaryContainer implements SymbolTable {
|
||||
return constantDataContainer;
|
||||
}
|
||||
|
||||
public ByteContainer getMetaspaceGotContainer() {
|
||||
return metaspaceGotContainer;
|
||||
public ByteContainer getKlassesGotContainer() {
|
||||
return klassesGotContainer;
|
||||
}
|
||||
|
||||
public ByteContainer getCountersGotContainer() {
|
||||
return countersGotContainer;
|
||||
}
|
||||
|
||||
public ByteContainer getMetadataGotContainer() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -26,7 +26,7 @@ package jdk.tools.jaotc.binformat;
|
||||
/**
|
||||
* A container that holds information about code section. This is simply a ByteContainer.
|
||||
*/
|
||||
public class CodeContainer extends ByteContainer {
|
||||
public final class CodeContainer extends ByteContainer {
|
||||
|
||||
public CodeContainer(String containerName, SymbolTable symbolTable) {
|
||||
super(containerName, symbolTable);
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public interface Container {
|
||||
interface Container {
|
||||
|
||||
String getContainerName();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public class GotSymbol extends Symbol {
|
||||
public final class GotSymbol extends Symbol {
|
||||
|
||||
private static final int GOT_SIZE = 8;
|
||||
|
||||
@ -33,18 +33,27 @@ public class GotSymbol extends Symbol {
|
||||
return offset / GOT_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create GOT symbol info.
|
||||
*
|
||||
* @param type type of the symbol (UNDEFINED, FUNC, etc)
|
||||
* @param binding binding of the symbol (LOCAL, GLOBAL, ...)
|
||||
* @param container section in which this symbol is "defined"
|
||||
* @param name name of the symbol
|
||||
*/
|
||||
public GotSymbol(Kind type, Binding binding, ByteContainer container, String name) {
|
||||
this(container.getByteStreamSize(), type, binding, container, name);
|
||||
container.appendBytes(new byte[GOT_SIZE], 0, GOT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create symbol info.
|
||||
* Create GOT symbol info.
|
||||
*
|
||||
* @param offset section offset for the defined symbol
|
||||
* @param type type of the symbol (UNDEFINED, FUNC, etc)
|
||||
* @param binding binding of the symbol (LOCAL, GLOBAL, ...)
|
||||
* @param sec section in which this symbol is "defined"
|
||||
* @param name name of the symbol
|
||||
*/
|
||||
public GotSymbol(int offset, Kind type, Binding binding, ByteContainer sec, String name) {
|
||||
super(offset, type, binding, sec, GOT_SIZE, name);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -27,14 +27,15 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class HeaderContainer {
|
||||
public final class HeaderContainer {
|
||||
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
private final ReadOnlyDataContainer container;
|
||||
|
||||
// int _version;
|
||||
// int _class_count;
|
||||
// int _method_count;
|
||||
// int _metaspace_got_size;
|
||||
// int _klasses_got_size;
|
||||
// int _metadata_got_size;
|
||||
// int _oop_got_size;
|
||||
// int _jvm_version_offset;
|
||||
@ -76,7 +77,7 @@ public class HeaderContainer {
|
||||
this.container.putIntAt(2 * 4, count);
|
||||
}
|
||||
|
||||
public void setMetaspaceGotSize(int size) {
|
||||
public void setKlassesGotSize(int size) {
|
||||
this.container.putIntAt(3 * 4, size);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -23,9 +23,9 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public class ReadOnlyDataContainer extends ByteContainer {
|
||||
public final class ReadOnlyDataContainer extends ByteContainer {
|
||||
|
||||
public ReadOnlyDataContainer(String containerName, SymbolTable symbolTable) {
|
||||
ReadOnlyDataContainer(String containerName, SymbolTable symbolTable) {
|
||||
super(containerName, symbolTable);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -23,25 +23,17 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public class Relocation {
|
||||
public final class Relocation {
|
||||
|
||||
public enum RelocType {
|
||||
UNDEFINED,
|
||||
JAVA_CALL_INDIRECT,
|
||||
JAVA_CALL_DIRECT,
|
||||
FOREIGN_CALL_INDIRECT,
|
||||
FOREIGN_CALL_INDIRECT_GOT, // Call to address in GOT cell
|
||||
FOREIGN_CALL_DIRECT,
|
||||
FOREIGN_CALL_DIRECT_FAR,
|
||||
STUB_CALL_DIRECT,
|
||||
STUB_CALL_INDIRECT,
|
||||
EXTERNAL_DATA_REFERENCE_FAR,
|
||||
METASPACE_GOT_REFERENCE,
|
||||
EXTERNAL_GOT_TO_PLT,
|
||||
EXTERNAL_PLT_TO_GOT,
|
||||
STATIC_STUB_TO_STATIC_METHOD,
|
||||
STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT,
|
||||
LOADTIME_ADDRESS
|
||||
EXTERNAL_PLT_TO_GOT
|
||||
}
|
||||
|
||||
private final RelocType type;
|
||||
|
@ -39,7 +39,6 @@ public class Symbol {
|
||||
UNDEFINED,
|
||||
NATIVE_FUNCTION,
|
||||
JAVA_FUNCTION,
|
||||
STATIC_STUB_CALL, // static call stub inside the text section
|
||||
OBJECT,
|
||||
NOTYPE
|
||||
}
|
||||
|
@ -25,17 +25,16 @@ package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for the creation of Elf Object files.
|
||||
* Current support is limited to 64 bit x86_64.
|
||||
* Support for the creation of Elf Object files. Current support is limited to 64 bit x86_64.
|
||||
*
|
||||
*/
|
||||
|
||||
public class Elf {
|
||||
|
||||
final class Elf {
|
||||
//@formatter:off
|
||||
/**
|
||||
* Elf64_Ehdr structure defines
|
||||
*/
|
||||
public enum Elf64_Ehdr {
|
||||
enum Elf64_Ehdr {
|
||||
e_ident( 0,16),
|
||||
e_type(16, 2),
|
||||
e_machine(18, 2),
|
||||
@ -51,15 +50,15 @@ public class Elf {
|
||||
e_shnum(60, 2),
|
||||
e_shstrndx(62, 2);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
Elf64_Ehdr(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 64;
|
||||
static int totalsize = 64;
|
||||
|
||||
/**
|
||||
* Elf64_Ehdr defines
|
||||
@ -68,50 +67,44 @@ public class Elf {
|
||||
/**
|
||||
* e_ident
|
||||
*/
|
||||
public static final int EI_MAG0 = 0;
|
||||
public static final byte ELFMAG0 = 0x7f;
|
||||
public static final int EI_MAG1 = 1;
|
||||
public static final byte ELFMAG1 = 0x45;
|
||||
public static final int EI_MAG2 = 2;
|
||||
public static final byte ELFMAG2 = 0x4c;
|
||||
public static final int EI_MAG3 = 3;
|
||||
public static final byte ELFMAG3 = 0x46;
|
||||
static final int EI_MAG0 = 0;
|
||||
static final byte ELFMAG0 = 0x7f;
|
||||
static final int EI_MAG1 = 1;
|
||||
static final byte ELFMAG1 = 0x45;
|
||||
static final int EI_MAG2 = 2;
|
||||
static final byte ELFMAG2 = 0x4c;
|
||||
static final int EI_MAG3 = 3;
|
||||
static final byte ELFMAG3 = 0x46;
|
||||
static final int EI_CLASS = 4;
|
||||
static final byte ELFCLASS64 = 0x2;
|
||||
|
||||
public static final int EI_CLASS = 4;
|
||||
public static final byte ELFCLASS64 = 0x2;
|
||||
static final int EI_DATA = 5;
|
||||
static final byte ELFDATA2LSB = 0x1;
|
||||
|
||||
public static final int EI_DATA = 5;
|
||||
public static final byte ELFDATA2LSB = 0x1;
|
||||
static final int EI_VERSION = 6;
|
||||
static final byte EV_CURRENT = 0x1;
|
||||
|
||||
public static final int EI_VERSION = 6;
|
||||
public static final byte EV_CURRENT = 0x1;
|
||||
|
||||
public static final int EI_OSABI = 7;
|
||||
public static final byte ELFOSABI_NONE = 0x0;
|
||||
static final int EI_OSABI = 7;
|
||||
static final byte ELFOSABI_NONE = 0x0;
|
||||
|
||||
/**
|
||||
* e_type
|
||||
*/
|
||||
public static final char ET_REL = 0x1;
|
||||
static final char ET_REL = 0x1;
|
||||
|
||||
/**
|
||||
* e_machine
|
||||
*/
|
||||
public static final char EM_NONE = 0;
|
||||
public static final char EM_X86_64 = 62;
|
||||
public static final char EM_AARCH64 = 183;
|
||||
|
||||
/**
|
||||
* e_version
|
||||
*/
|
||||
// public static final int EV_CURRENT = 1;
|
||||
static final char EM_NONE = 0;
|
||||
static final char EM_X86_64 = 62;
|
||||
static final char EM_AARCH64 = 183;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Elf64_Shdr structure defines
|
||||
*/
|
||||
public enum Elf64_Shdr {
|
||||
enum Elf64_Shdr {
|
||||
sh_name( 0, 4),
|
||||
sh_type( 4, 4),
|
||||
sh_flags( 8, 8),
|
||||
@ -123,15 +116,15 @@ public class Elf {
|
||||
sh_addralign(48, 8),
|
||||
sh_entsize(56, 8);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
Elf64_Shdr(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 64;
|
||||
static int totalsize = 64;
|
||||
|
||||
/**
|
||||
* Elf64_Shdr defines
|
||||
@ -140,21 +133,21 @@ public class Elf {
|
||||
/**
|
||||
* sh_type
|
||||
*/
|
||||
public static final int SHT_PROGBITS = 0x1;
|
||||
public static final int SHT_SYMTAB = 0x2;
|
||||
public static final int SHT_STRTAB = 0x3;
|
||||
public static final int SHT_RELA = 0x4;
|
||||
public static final int SHT_NOBITS = 0x8;
|
||||
public static final int SHT_REL = 0x9;
|
||||
static final int SHT_PROGBITS = 0x1;
|
||||
static final int SHT_SYMTAB = 0x2;
|
||||
static final int SHT_STRTAB = 0x3;
|
||||
static final int SHT_RELA = 0x4;
|
||||
static final int SHT_NOBITS = 0x8;
|
||||
static final int SHT_REL = 0x9;
|
||||
|
||||
public static final byte SHN_UNDEF = 0x0;
|
||||
static final byte SHN_UNDEF = 0x0;
|
||||
|
||||
/**
|
||||
* sh_flag
|
||||
*/
|
||||
public static final int SHF_WRITE = 0x1;
|
||||
public static final int SHF_ALLOC = 0x2;
|
||||
public static final int SHF_EXECINSTR = 0x4;
|
||||
static final int SHF_WRITE = 0x1;
|
||||
static final int SHF_ALLOC = 0x2;
|
||||
static final int SHF_EXECINSTR = 0x4;
|
||||
|
||||
}
|
||||
|
||||
@ -163,7 +156,7 @@ public class Elf {
|
||||
*
|
||||
* Elf64_Sym structure defines
|
||||
*/
|
||||
public enum Elf64_Sym {
|
||||
enum Elf64_Sym {
|
||||
st_name( 0, 4),
|
||||
st_info( 4, 1),
|
||||
st_other( 5, 1),
|
||||
@ -171,25 +164,25 @@ public class Elf {
|
||||
st_value( 8, 8),
|
||||
st_size(16, 8);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
Elf64_Sym(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 24;
|
||||
static int totalsize = 24;
|
||||
|
||||
/* ST_BIND is in bits 4-7 of st_info. ST_TYPE is in low 4 bits */
|
||||
public static final byte STB_LOCAL = 0x0;
|
||||
public static final byte STB_GLOBAL = 0x1;
|
||||
static final byte STB_LOCAL = 0x0;
|
||||
static final byte STB_GLOBAL = 0x1;
|
||||
|
||||
public static final byte STT_NOTYPE = 0x0;
|
||||
public static final byte STT_OBJECT = 0x1;
|
||||
public static final byte STT_FUNC = 0x2;
|
||||
static final byte STT_NOTYPE = 0x0;
|
||||
static final byte STT_OBJECT = 0x1;
|
||||
static final byte STT_FUNC = 0x2;
|
||||
|
||||
public static byte ELF64_ST_INFO(byte bind, byte type) {
|
||||
static byte ELF64_ST_INFO(byte bind, byte type) {
|
||||
return (byte)(((bind) << 4) + ((type) & 0xf));
|
||||
}
|
||||
|
||||
@ -198,59 +191,59 @@ public class Elf {
|
||||
/**
|
||||
* Elf64_Rel structure defines
|
||||
*/
|
||||
public enum Elf64_Rel {
|
||||
enum Elf64_Rel {
|
||||
r_offset( 0, 8),
|
||||
r_info( 8, 8);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
Elf64_Rel(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 16;
|
||||
static int totalsize = 16;
|
||||
|
||||
/**
|
||||
* Relocation types
|
||||
*/
|
||||
public static final int R_X86_64_NONE = 0x0;
|
||||
public static final int R_X86_64_64 = 0x1;
|
||||
public static final int R_X86_64_PC32 = 0x2;
|
||||
public static final int R_X86_64_PLT32 = 0x4;
|
||||
public static final int R_X86_64_GOTPCREL = 0x9;
|
||||
static final int R_X86_64_NONE = 0x0;
|
||||
static final int R_X86_64_64 = 0x1;
|
||||
static final int R_X86_64_PC32 = 0x2;
|
||||
static final int R_X86_64_PLT32 = 0x4;
|
||||
static final int R_X86_64_GOTPCREL = 0x9;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Elf64_Rela structure defines
|
||||
*/
|
||||
public enum Elf64_Rela {
|
||||
enum Elf64_Rela {
|
||||
r_offset( 0, 8),
|
||||
r_info( 8, 8),
|
||||
r_addend(16, 8);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
Elf64_Rela(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 24;
|
||||
static int totalsize = 24;
|
||||
|
||||
public static final int R_X86_64_NONE = 0x0;
|
||||
public static final int R_X86_64_64 = 0x1;
|
||||
public static final int R_X86_64_PC32 = 0x2;
|
||||
public static final int R_X86_64_PLT32 = 0x4;
|
||||
public static final int R_X86_64_GOTPCREL = 0x9;
|
||||
static final int R_X86_64_NONE = 0x0;
|
||||
static final int R_X86_64_64 = 0x1;
|
||||
static final int R_X86_64_PC32 = 0x2;
|
||||
static final int R_X86_64_PLT32 = 0x4;
|
||||
static final int R_X86_64_GOTPCREL = 0x9;
|
||||
|
||||
public static long ELF64_R_INFO(int symidx, int type) {
|
||||
return (((long)symidx << 32) + ((long)type));
|
||||
static long ELF64_R_INFO(int symidx, int type) {
|
||||
return (((long)symidx << 32) + type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//@formatter:on
|
||||
}
|
||||
|
@ -23,20 +23,20 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
|
||||
|
||||
public class ElfByteBuffer {
|
||||
final class ElfByteBuffer {
|
||||
|
||||
public static ByteBuffer allocate(int size) {
|
||||
static ByteBuffer allocate(int size) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(size);
|
||||
if (ElfTargetInfo.getElfEndian() == Elf64_Ehdr.ELFDATA2LSB)
|
||||
if (ElfTargetInfo.getElfEndian() == Elf64_Ehdr.ELFDATA2LSB) {
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
else
|
||||
} else {
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,13 @@ package jdk.tools.jaotc.binformat.elf;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class ElfContainer {
|
||||
final class ElfContainer {
|
||||
|
||||
File outputFile;
|
||||
FileOutputStream outputStream;
|
||||
long fileOffset;
|
||||
private final File outputFile;
|
||||
private FileOutputStream outputStream;
|
||||
private long fileOffset;
|
||||
|
||||
public ElfContainer(String fileName, String aotVersion) {
|
||||
String baseName;
|
||||
ElfContainer(String fileName) {
|
||||
|
||||
outputFile = new File(fileName);
|
||||
if (outputFile.exists()) {
|
||||
@ -48,7 +47,7 @@ public class ElfContainer {
|
||||
fileOffset = 0;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
void close() {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
@ -56,8 +55,10 @@ public class ElfContainer {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(byte [] bytes) {
|
||||
if (bytes == null) return;
|
||||
void writeBytes(byte[] bytes) {
|
||||
if (bytes == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
outputStream.write(bytes);
|
||||
} catch (Exception e) {
|
||||
@ -67,11 +68,13 @@ public class ElfContainer {
|
||||
}
|
||||
|
||||
// Write bytes to output file with up front alignment padding
|
||||
public void writeBytes(byte [] bytes, int alignment) {
|
||||
if (bytes == null) return;
|
||||
void writeBytes(byte[] bytes, int alignment) {
|
||||
if (bytes == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Pad to alignment
|
||||
while ((fileOffset & (long)(alignment-1)) != 0) {
|
||||
while ((fileOffset & (alignment - 1)) != 0) {
|
||||
outputStream.write(0);
|
||||
fileOffset++;
|
||||
}
|
||||
@ -82,4 +85,3 @@ public class ElfContainer {
|
||||
fileOffset += bytes.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,55 +24,52 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
public class ElfHeader {
|
||||
ByteBuffer header;
|
||||
final class ElfHeader {
|
||||
private final ByteBuffer header;
|
||||
|
||||
public ElfHeader() {
|
||||
ElfHeader() {
|
||||
header = ElfByteBuffer.allocate(Elf64_Ehdr.totalsize);
|
||||
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_MAG0, Elf64_Ehdr.ELFMAG0);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_MAG1, Elf64_Ehdr.ELFMAG1);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_MAG2, Elf64_Ehdr.ELFMAG2);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_MAG3, Elf64_Ehdr.ELFMAG3);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_CLASS, Elf64_Ehdr.ELFCLASS64);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_DATA, Elf64_Ehdr.ELFDATA2LSB);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_VERSION, Elf64_Ehdr.EV_CURRENT);
|
||||
header.put(Elf64_Ehdr.e_ident.off+Elf64_Ehdr.EI_OSABI, Elf64_Ehdr.ELFOSABI_NONE);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_MAG0, Elf64_Ehdr.ELFMAG0);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_MAG1, Elf64_Ehdr.ELFMAG1);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_MAG2, Elf64_Ehdr.ELFMAG2);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_MAG3, Elf64_Ehdr.ELFMAG3);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_CLASS, Elf64_Ehdr.ELFCLASS64);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_DATA, Elf64_Ehdr.ELFDATA2LSB);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_VERSION, Elf64_Ehdr.EV_CURRENT);
|
||||
header.put(Elf64_Ehdr.e_ident.off + Elf64_Ehdr.EI_OSABI, Elf64_Ehdr.ELFOSABI_NONE);
|
||||
|
||||
header.putChar(Elf64_Ehdr.e_type.off, Elf64_Ehdr.ET_REL);
|
||||
header.putChar(Elf64_Ehdr.e_machine.off, ElfTargetInfo.getElfArch());
|
||||
header.putInt(Elf64_Ehdr.e_version.off, Elf64_Ehdr.EV_CURRENT);
|
||||
header.putChar(Elf64_Ehdr.e_ehsize.off, (char)Elf64_Ehdr.totalsize);
|
||||
header.putChar(Elf64_Ehdr.e_shentsize.off, (char)Elf64_Shdr.totalsize);
|
||||
header.putChar(Elf64_Ehdr.e_ehsize.off, (char) Elf64_Ehdr.totalsize);
|
||||
header.putChar(Elf64_Ehdr.e_shentsize.off, (char) Elf64_Shdr.totalsize);
|
||||
|
||||
}
|
||||
|
||||
// Update header with file offset of first section
|
||||
public void setSectionOff(int offset) {
|
||||
void setSectionOff(int offset) {
|
||||
header.putLong(Elf64_Ehdr.e_shoff.off, offset);
|
||||
}
|
||||
|
||||
// Update header with the number of total sections
|
||||
public void setSectionNum(int count) {
|
||||
header.putChar(Elf64_Ehdr.e_shnum.off, (char)count);
|
||||
void setSectionNum(int count) {
|
||||
header.putChar(Elf64_Ehdr.e_shnum.off, (char) count);
|
||||
}
|
||||
|
||||
// Update header with the section index containing the
|
||||
// string table for section names
|
||||
public void setSectionStrNdx(int index) {
|
||||
header.putChar(Elf64_Ehdr.e_shstrndx.off, (char)index);
|
||||
void setSectionStrNdx(int index) {
|
||||
header.putChar(Elf64_Ehdr.e_shstrndx.off, (char) index);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return header.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,28 +24,23 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
public class ElfRelocEntry {
|
||||
ByteBuffer entry;
|
||||
final class ElfRelocEntry {
|
||||
private final ByteBuffer entry;
|
||||
|
||||
public ElfRelocEntry(int offset, int symno, int type, int addend) {
|
||||
ElfRelocEntry(int offset, int symno, int type, int addend) {
|
||||
|
||||
entry = ElfByteBuffer.allocate(Elf64_Rela.totalsize);
|
||||
|
||||
entry.putLong(Elf64_Rela.r_offset.off, offset);
|
||||
entry.putLong(Elf64_Rela.r_info.off, Elf64_Rela.ELF64_R_INFO(symno,type));
|
||||
entry.putLong(Elf64_Rela.r_info.off, Elf64_Rela.ELF64_R_INFO(symno, type));
|
||||
entry.putLong(Elf64_Rela.r_addend.off, addend);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return entry.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,48 +25,38 @@ package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.ElfRelocEntry;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
public class ElfRelocTable {
|
||||
ArrayList<ArrayList<ElfRelocEntry>> relocEntries;
|
||||
final class ElfRelocTable {
|
||||
private final ArrayList<ArrayList<ElfRelocEntry>> relocEntries;
|
||||
|
||||
public ElfRelocTable(int numsects) {
|
||||
relocEntries = new ArrayList<ArrayList<ElfRelocEntry>>(numsects);
|
||||
for (int i = 0; i < numsects; i++)
|
||||
ElfRelocTable(int numsects) {
|
||||
relocEntries = new ArrayList<>(numsects);
|
||||
for (int i = 0; i < numsects; i++) {
|
||||
relocEntries.add(new ArrayList<ElfRelocEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
public void createRelocationEntry(int sectindex,
|
||||
int offset,
|
||||
int symno,
|
||||
int type,
|
||||
int addend) {
|
||||
|
||||
ElfRelocEntry entry = new ElfRelocEntry(offset,
|
||||
symno,
|
||||
type,
|
||||
addend);
|
||||
void createRelocationEntry(int sectindex, int offset, int symno, int type, int addend) {
|
||||
ElfRelocEntry entry = new ElfRelocEntry(offset, symno, type, addend);
|
||||
relocEntries.get(sectindex).add(entry);
|
||||
}
|
||||
|
||||
public int getNumRelocs(int section_index) {
|
||||
int getNumRelocs(int section_index) {
|
||||
return relocEntries.get(section_index).size();
|
||||
}
|
||||
|
||||
// Return the relocation entries for a single section
|
||||
// or null if no entries added to section
|
||||
public byte [] getRelocData(int section_index) {
|
||||
// or null if no entries added to section
|
||||
byte[] getRelocData(int section_index) {
|
||||
ArrayList<ElfRelocEntry> entryList = relocEntries.get(section_index);
|
||||
|
||||
if (entryList.size() == 0)
|
||||
if (entryList.size() == 0) {
|
||||
return null;
|
||||
|
||||
}
|
||||
ByteBuffer relocData = ElfByteBuffer.allocate(entryList.size() * Elf64_Rela.totalsize);
|
||||
|
||||
// Copy each entry to a single ByteBuffer
|
||||
@ -78,4 +68,3 @@ public class ElfRelocTable {
|
||||
return (relocData.array());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,40 +24,36 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rel;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
public class ElfSection {
|
||||
String name;
|
||||
ByteBuffer section;
|
||||
byte [] data;
|
||||
boolean hasrelocations;
|
||||
int sectionIndex;
|
||||
final class ElfSection {
|
||||
private final String name;
|
||||
private final ByteBuffer section;
|
||||
private final byte[] data;
|
||||
private final boolean hasrelocations;
|
||||
private final int sectionIndex;
|
||||
|
||||
/**
|
||||
* String holding section name strings
|
||||
*/
|
||||
private static StringBuilder sectNameTab = new StringBuilder();
|
||||
private final static StringBuilder sectNameTab = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Keeps track of bytes in section string table since strTabContent.length()
|
||||
* is number of chars, not bytes.
|
||||
* Keeps track of bytes in section string table since strTabContent.length() is number of chars,
|
||||
* not bytes.
|
||||
*/
|
||||
private static int shStrTabNrOfBytes = 0;
|
||||
|
||||
public ElfSection(String sectName, byte [] sectData, int sectFlags,
|
||||
int sectType, boolean hasRelocations, int align,
|
||||
int sectIndex) {
|
||||
ElfSection(String sectName, byte[] sectData, int sectFlags, int sectType,
|
||||
boolean hasRelocations, int align, int sectIndex) {
|
||||
|
||||
section = ElfByteBuffer.allocate(Elf64_Shdr.totalsize);
|
||||
|
||||
name = sectName;
|
||||
// Return all 0's for NULL section
|
||||
if (sectIndex == 0) {
|
||||
sectNameTab.append('\0');
|
||||
@ -71,7 +67,6 @@ public class ElfSection {
|
||||
section.putInt(Elf64_Shdr.sh_name.off, shStrTabNrOfBytes);
|
||||
sectNameTab.append(sectName).append('\0');
|
||||
shStrTabNrOfBytes += (sectName.getBytes().length + 1);
|
||||
name = sectName;
|
||||
|
||||
section.putInt(Elf64_Shdr.sh_type.off, sectType);
|
||||
section.putLong(Elf64_Shdr.sh_flags.off, sectFlags);
|
||||
@ -81,8 +76,7 @@ public class ElfSection {
|
||||
if (sectName.equals(".shstrtab")) {
|
||||
section.putLong(Elf64_Shdr.sh_size.off, shStrTabNrOfBytes);
|
||||
data = sectNameTab.toString().getBytes();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
data = sectData;
|
||||
section.putLong(Elf64_Shdr.sh_size.off, sectData.length);
|
||||
}
|
||||
@ -110,55 +104,53 @@ public class ElfSection {
|
||||
sectionIndex = sectIndex;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
long getSize() {
|
||||
return section.getLong(Elf64_Shdr.sh_size.off);
|
||||
}
|
||||
|
||||
public int getDataAlign() {
|
||||
return ((int)section.getLong(Elf64_Shdr.sh_addralign.off));
|
||||
int getDataAlign() {
|
||||
return ((int) section.getLong(Elf64_Shdr.sh_addralign.off));
|
||||
}
|
||||
|
||||
// Alignment requirements for the Elf64_Shdr structures
|
||||
public static int getShdrAlign() {
|
||||
static int getShdrAlign() {
|
||||
return (4);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return section.array();
|
||||
}
|
||||
|
||||
public byte[] getDataArray() {
|
||||
byte[] getDataArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setOffset(long offset) {
|
||||
void setOffset(long offset) {
|
||||
section.putLong(Elf64_Shdr.sh_offset.off, offset);
|
||||
}
|
||||
|
||||
public void setLink(int link) {
|
||||
void setLink(int link) {
|
||||
section.putInt(Elf64_Shdr.sh_link.off, link);
|
||||
}
|
||||
|
||||
public void setInfo(int info) {
|
||||
void setInfo(int info) {
|
||||
section.putInt(Elf64_Shdr.sh_info.off, info);
|
||||
}
|
||||
|
||||
public long getOffset() {
|
||||
long getOffset() {
|
||||
return (section.getLong(Elf64_Shdr.sh_offset.off));
|
||||
}
|
||||
|
||||
public boolean hasRelocations() {
|
||||
boolean hasRelocations() {
|
||||
return hasrelocations;
|
||||
}
|
||||
|
||||
public int getSectionId() {
|
||||
int getSectionId() {
|
||||
return sectionIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,34 +24,29 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
public class ElfSymbol extends NativeSymbol {
|
||||
ByteBuffer sym;
|
||||
final class ElfSymbol extends NativeSymbol {
|
||||
private final ByteBuffer sym;
|
||||
|
||||
public ElfSymbol(int symbolindex, int strindex, byte type, byte bind,
|
||||
byte sectindex, long offset, long size) {
|
||||
ElfSymbol(int symbolindex, int strindex, byte type, byte bind, byte sectindex, long offset, long size) {
|
||||
super(symbolindex);
|
||||
sym = ElfByteBuffer.allocate(Elf64_Sym.totalsize);
|
||||
|
||||
sym.putInt(Elf64_Sym.st_name.off, strindex);
|
||||
sym.put(Elf64_Sym.st_info.off, Elf64_Sym.ELF64_ST_INFO(bind, type));
|
||||
sym.put(Elf64_Sym.st_other.off, (byte)0);
|
||||
sym.put(Elf64_Sym.st_other.off, (byte) 0);
|
||||
// Section indexes start at 1 but we manage the index internally
|
||||
// as 0 relative
|
||||
sym.putChar(Elf64_Sym.st_shndx.off, (char)(sectindex));
|
||||
sym.putChar(Elf64_Sym.st_shndx.off, (char) (sectindex));
|
||||
sym.putLong(Elf64_Sym.st_value.off, offset);
|
||||
sym.putLong(Elf64_Sym.st_size.off, size);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return sym.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,41 +24,38 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfSymbol;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
public class ElfSymtab {
|
||||
final class ElfSymtab {
|
||||
|
||||
ArrayList<ElfSymbol>localSymbols = new ArrayList<ElfSymbol>();
|
||||
ArrayList<ElfSymbol>globalSymbols = new ArrayList<ElfSymbol>();
|
||||
private final ArrayList<ElfSymbol> localSymbols = new ArrayList<>();
|
||||
private final ArrayList<ElfSymbol> globalSymbols = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* number of symbols added
|
||||
*/
|
||||
int symbolCount;
|
||||
private int symbolCount;
|
||||
|
||||
/**
|
||||
* String holding symbol table strings
|
||||
*/
|
||||
private StringBuilder strTabContent = new StringBuilder();
|
||||
private final StringBuilder strTabContent = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Keeps track of bytes in string table since strTabContent.length()
|
||||
* is number of chars, not bytes.
|
||||
* Keeps track of bytes in string table since strTabContent.length() is number of chars, not
|
||||
* bytes.
|
||||
*/
|
||||
private int strTabNrOfBytes = 0;
|
||||
|
||||
public ElfSymtab() {
|
||||
ElfSymtab() {
|
||||
symbolCount = 0;
|
||||
}
|
||||
|
||||
public ElfSymbol addSymbolEntry(String name, byte type, byte bind,
|
||||
byte secHdrIndex, long offset, long size) {
|
||||
ElfSymbol addSymbolEntry(String name, byte type, byte bind, byte secHdrIndex, long offset, long size) {
|
||||
// Get the current symbol index and append symbol name to string table.
|
||||
int index;
|
||||
ElfSymbol sym;
|
||||
@ -76,7 +73,7 @@ public class ElfSymtab {
|
||||
// strTabContent.append("_").append(name).append('\0');
|
||||
strTabContent.append(name).append('\0');
|
||||
// + 1 for null, + 1 for "_"
|
||||
//strTabNrOfBytes += (name.getBytes().length + 1 + 1);
|
||||
// strTabNrOfBytes += (name.getBytes().length + 1 + 1);
|
||||
strTabNrOfBytes += (name.getBytes().length + 1);
|
||||
|
||||
sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size);
|
||||
@ -92,44 +89,47 @@ public class ElfSymtab {
|
||||
// Update the symbol indexes once all symbols have been added.
|
||||
// This is required since we'll be reordering the symbols in the
|
||||
// file to be in the order of Local then global.
|
||||
public void updateIndexes() {
|
||||
void updateIndexes() {
|
||||
int index = 0;
|
||||
|
||||
// Update the local symbol indexes
|
||||
for (int i = 0; i < localSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < localSymbols.size(); i++) {
|
||||
ElfSymbol sym = localSymbols.get(i);
|
||||
sym.setIndex(index++);
|
||||
}
|
||||
|
||||
// Update the global symbol indexes
|
||||
for (int i = 0; i < globalSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < globalSymbols.size(); i++) {
|
||||
ElfSymbol sym = globalSymbols.get(i);
|
||||
sym.setIndex(index++);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumLocalSyms() { return localSymbols.size(); }
|
||||
public int getNumGlobalSyms() { return globalSymbols.size(); }
|
||||
int getNumLocalSyms() {
|
||||
return localSymbols.size();
|
||||
}
|
||||
|
||||
int getNumGlobalSyms() {
|
||||
return globalSymbols.size();
|
||||
}
|
||||
|
||||
// Create a single byte array that contains the symbol table entries
|
||||
public byte[] getSymtabArray() {
|
||||
int index = 0;
|
||||
ByteBuffer symtabData = ElfByteBuffer.allocate(symbolCount*Elf64_Sym.totalsize);
|
||||
byte [] retarray;
|
||||
byte[] getSymtabArray() {
|
||||
ByteBuffer symtabData = ElfByteBuffer.allocate(symbolCount * Elf64_Sym.totalsize);
|
||||
byte[] retarray;
|
||||
|
||||
updateIndexes();
|
||||
|
||||
// Add the local symbols
|
||||
for (int i = 0; i < localSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < localSymbols.size(); i++) {
|
||||
ElfSymbol sym = localSymbols.get(i);
|
||||
byte [] arr = sym.getArray();
|
||||
byte[] arr = sym.getArray();
|
||||
symtabData.put(arr);
|
||||
}
|
||||
// Add the global symbols
|
||||
for (int i = 0; i < globalSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < globalSymbols.size(); i++) {
|
||||
ElfSymbol sym = globalSymbols.get(i);
|
||||
byte [] arr = sym.getArray();
|
||||
byte[] arr = sym.getArray();
|
||||
symtabData.put(arr);
|
||||
}
|
||||
retarray = symtabData.array();
|
||||
@ -138,10 +138,8 @@ public class ElfSymtab {
|
||||
}
|
||||
|
||||
// Return the string table array
|
||||
public byte[] getStrtabArray() {
|
||||
byte [] strs = strTabContent.toString().getBytes();
|
||||
byte[] getStrtabArray() {
|
||||
byte[] strs = strTabContent.toString().getBytes();
|
||||
return (strs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,14 +24,13 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
|
||||
/**
|
||||
* Class that abstracts MACH-O target details.
|
||||
*
|
||||
*/
|
||||
public class ElfTargetInfo {
|
||||
final class ElfTargetInfo {
|
||||
/**
|
||||
* Target architecture.
|
||||
*/
|
||||
@ -68,16 +67,15 @@ public class ElfTargetInfo {
|
||||
}
|
||||
}
|
||||
|
||||
public static char getElfArch() {
|
||||
static char getElfArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public static int getElfEndian() {
|
||||
static int getElfEndian() {
|
||||
return endian;
|
||||
}
|
||||
|
||||
public static String getOsName() {
|
||||
static String getOsName() {
|
||||
return osName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,11 @@
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.tools.jaotc.binformat.Container;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.ByteContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
@ -38,17 +36,14 @@ import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
|
||||
import jdk.tools.jaotc.binformat.Relocation;
|
||||
import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfSymbol;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Ehdr;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Shdr;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rel;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
|
||||
|
||||
public class JELFRelocObject {
|
||||
@ -59,34 +54,29 @@ public class JELFRelocObject {
|
||||
|
||||
private final int segmentSize;
|
||||
|
||||
public JELFRelocObject(BinaryContainer binContainer, String outputFileName, String aotVersion) {
|
||||
public JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
|
||||
this.binContainer = binContainer;
|
||||
this.elfContainer = new ElfContainer(outputFileName, aotVersion);
|
||||
this.elfContainer = new ElfContainer(outputFileName);
|
||||
this.segmentSize = binContainer.getCodeSegmentSize();
|
||||
}
|
||||
|
||||
private ElfSection createByteSection(ArrayList<ElfSection>sections,
|
||||
String sectName,
|
||||
byte [] scnData,
|
||||
boolean hasRelocs,
|
||||
int align,
|
||||
int scnFlags,
|
||||
int scnType) {
|
||||
private static ElfSection createByteSection(ArrayList<ElfSection> sections,
|
||||
String sectName,
|
||||
byte[] scnData,
|
||||
boolean hasRelocs,
|
||||
int align,
|
||||
int scnFlags,
|
||||
int scnType) {
|
||||
|
||||
ElfSection sect = new ElfSection(sectName,
|
||||
scnData,
|
||||
scnFlags,
|
||||
scnType,
|
||||
hasRelocs,
|
||||
align,
|
||||
sections.size());
|
||||
ElfSection sect = new ElfSection(sectName, scnData, scnFlags, scnType,
|
||||
hasRelocs, align, sections.size());
|
||||
// Add this section to our list
|
||||
sections.add(sect);
|
||||
|
||||
return (sect);
|
||||
}
|
||||
|
||||
private void createByteSection(ArrayList<ElfSection>sections,
|
||||
private void createByteSection(ArrayList<ElfSection> sections,
|
||||
ByteContainer c, int scnFlags) {
|
||||
ElfSection sect;
|
||||
boolean hasRelocs = c.hasRelocations();
|
||||
@ -112,15 +102,15 @@ public class JELFRelocObject {
|
||||
c.setSectionId(sect.getSectionId());
|
||||
}
|
||||
|
||||
private void createCodeSection(ArrayList<ElfSection>sections, CodeContainer c) {
|
||||
private void createCodeSection(ArrayList<ElfSection> sections, CodeContainer c) {
|
||||
createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC | Elf64_Shdr.SHF_EXECINSTR);
|
||||
}
|
||||
|
||||
private void createReadOnlySection(ArrayList<ElfSection>sections, ReadOnlyDataContainer c) {
|
||||
private void createReadOnlySection(ArrayList<ElfSection> sections, ReadOnlyDataContainer c) {
|
||||
createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC);
|
||||
}
|
||||
|
||||
private void createReadWriteSection(ArrayList<ElfSection>sections, ByteContainer c) {
|
||||
private void createReadWriteSection(ArrayList<ElfSection> sections, ByteContainer c) {
|
||||
createByteSection(sections, c, Elf64_Shdr.SHF_ALLOC | Elf64_Shdr.SHF_WRITE);
|
||||
}
|
||||
|
||||
@ -135,7 +125,7 @@ public class JELFRelocObject {
|
||||
// Allocate ELF Header
|
||||
ElfHeader eh = new ElfHeader();
|
||||
|
||||
ArrayList<ElfSection> sections = new ArrayList<ElfSection>();
|
||||
ArrayList<ElfSection> sections = new ArrayList<>();
|
||||
|
||||
// Create the null section
|
||||
createByteSection(sections, null, null, false, 1, 0, 0);
|
||||
@ -146,63 +136,49 @@ public class JELFRelocObject {
|
||||
createReadOnlySection(sections, binContainer.getKlassesOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getMethodsOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getKlassesDependenciesContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetaspaceGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodStateContainer());
|
||||
createReadWriteSection(sections, binContainer.getOopGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodMetadataContainer());
|
||||
createReadOnlySection(sections, binContainer.getMethodMetadataContainer());
|
||||
createReadOnlySection(sections, binContainer.getStubsOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getHeaderContainer().getContainer());
|
||||
createReadOnlySection(sections, binContainer.getCodeSegmentsContainer());
|
||||
createReadOnlySection(sections, binContainer.getConstantDataContainer());
|
||||
createReadOnlySection(sections, binContainer.getConfigContainer());
|
||||
|
||||
// createExternalLinkage();
|
||||
|
||||
createCodeSection(sections, binContainer.getExtLinkageContainer());
|
||||
createReadWriteSection(sections, binContainer.getKlassesGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getCountersGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getOopGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodStateContainer());
|
||||
createReadWriteSection(sections, binContainer.getExtLinkageGOTContainer());
|
||||
|
||||
// Get ELF symbol data from BinaryContainer object's symbol tables
|
||||
ElfSymtab symtab = createELFSymbolTables(sections, symbols);
|
||||
ElfSymtab symtab = createELFSymbolTables(symbols);
|
||||
|
||||
// Create string table section and symbol table sections in
|
||||
// that order since symtab section needs to set the index of
|
||||
// strtab in sh_link field
|
||||
ElfSection strTabSection = createByteSection(sections,
|
||||
".strtab",
|
||||
ElfSection strTabSection = createByteSection(sections, ".strtab",
|
||||
symtab.getStrtabArray(),
|
||||
false,
|
||||
1,
|
||||
0,
|
||||
false, 1, 0,
|
||||
Elf64_Shdr.SHT_STRTAB);
|
||||
|
||||
// Now create .symtab section with the symtab data constructed.
|
||||
// On Linux, sh_link of symtab contains the index of string table
|
||||
// its symbols reference and sh_info contains the index of first
|
||||
// non-local symbol
|
||||
ElfSection symTabSection = createByteSection(sections,
|
||||
".symtab",
|
||||
symtab.getSymtabArray(),
|
||||
false,
|
||||
8,
|
||||
0,
|
||||
Elf64_Shdr.SHT_SYMTAB);
|
||||
ElfSection symTabSection = createByteSection(sections, ".symtab",
|
||||
symtab.getSymtabArray(),
|
||||
false, 8, 0,
|
||||
Elf64_Shdr.SHT_SYMTAB);
|
||||
symTabSection.setLink(strTabSection.getSectionId());
|
||||
symTabSection.setInfo(symtab.getNumLocalSyms());
|
||||
|
||||
ElfRelocTable elfRelocTable = createElfRelocTable(sections,
|
||||
relocationTable);
|
||||
ElfRelocTable elfRelocTable = createElfRelocTable(sections, relocationTable);
|
||||
|
||||
createElfRelocSections(sections, elfRelocTable, symTabSection.getSectionId());
|
||||
|
||||
// Now, finally, after creating all sections, create shstrtab section
|
||||
ElfSection shStrTabSection = createByteSection(sections,
|
||||
".shstrtab",
|
||||
null,
|
||||
false,
|
||||
1,
|
||||
0,
|
||||
Elf64_Shdr.SHT_STRTAB);
|
||||
ElfSection shStrTabSection = createByteSection(sections, ".shstrtab",
|
||||
null, false, 1, 0,
|
||||
Elf64_Shdr.SHT_STRTAB);
|
||||
eh.setSectionStrNdx(shStrTabSection.getSectionId());
|
||||
|
||||
// Update all section offsets and the Elf header section offset
|
||||
@ -211,21 +187,21 @@ public class JELFRelocObject {
|
||||
int file_offset = Elf64_Ehdr.totalsize;
|
||||
|
||||
// and round it up
|
||||
file_offset = (file_offset + (sections.get(1).getDataAlign()-1)) &
|
||||
~((sections.get(1).getDataAlign()-1));
|
||||
file_offset = (file_offset + (sections.get(1).getDataAlign() - 1)) &
|
||||
~((sections.get(1).getDataAlign() - 1));
|
||||
|
||||
// Calc file offsets for section data skipping null section
|
||||
for (int i = 1; i < sections.size(); i++) {
|
||||
ElfSection sect = sections.get(i);
|
||||
file_offset = (file_offset + (sect.getDataAlign()-1)) &
|
||||
~((sect.getDataAlign()-1));
|
||||
file_offset = (file_offset + (sect.getDataAlign() - 1)) &
|
||||
~((sect.getDataAlign() - 1));
|
||||
sect.setOffset(file_offset);
|
||||
file_offset += sect.getSize();
|
||||
}
|
||||
|
||||
// Align the section table
|
||||
file_offset = (file_offset + (ElfSection.getShdrAlign()-1)) &
|
||||
~((ElfSection.getShdrAlign()-1));
|
||||
file_offset = (file_offset + (ElfSection.getShdrAlign() - 1)) &
|
||||
~((ElfSection.getShdrAlign() - 1));
|
||||
|
||||
// Update the Elf Header with the offset of the first Elf64_Shdr
|
||||
// and the number of sections.
|
||||
@ -249,24 +225,25 @@ public class JELFRelocObject {
|
||||
|
||||
elfContainer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct ELF symbol data from BinaryContainer object's symbol tables. Both dynamic ELF
|
||||
* symbol table and ELF symbol table are created from BinaryContainer's symbol info.
|
||||
* Construct ELF symbol data from BinaryContainer object's symbol tables. Both dynamic ELF symbol
|
||||
* table and ELF symbol table are created from BinaryContainer's symbol info.
|
||||
*
|
||||
* @param symbols
|
||||
*/
|
||||
private ElfSymtab createELFSymbolTables(ArrayList<ElfSection> sections, Collection<Symbol> symbols) {
|
||||
private static ElfSymtab createELFSymbolTables(Collection<Symbol> symbols) {
|
||||
ElfSymtab symtab = new ElfSymtab();
|
||||
|
||||
// First, create the initial null symbol. This is a local symbol.
|
||||
symtab.addSymbolEntry("", (byte)0, (byte)0, Elf64_Shdr.SHN_UNDEF, 0, 0);
|
||||
symtab.addSymbolEntry("", (byte) 0, (byte) 0, Elf64_Shdr.SHN_UNDEF, 0, 0);
|
||||
|
||||
// Now create ELF symbol entries for all symbols.
|
||||
for (Symbol symbol : symbols) {
|
||||
// Get the index of section this symbol is defined in.
|
||||
int secHdrIndex = symbol.getSection().getSectionId();
|
||||
ElfSymbol elfSymbol = symtab.addSymbolEntry(symbol.getName(), getELFTypeOf(symbol), getELFBindOf(symbol), (byte)secHdrIndex, symbol.getOffset(), symbol.getSize());
|
||||
symbol.setNativeSymbol((NativeSymbol)elfSymbol);
|
||||
ElfSymbol elfSymbol = symtab.addSymbolEntry(symbol.getName(), getELFTypeOf(symbol), getELFBindOf(symbol), (byte) secHdrIndex, symbol.getOffset(), symbol.getSize());
|
||||
symbol.setNativeSymbol(elfSymbol);
|
||||
}
|
||||
return (symtab);
|
||||
}
|
||||
@ -300,8 +277,7 @@ public class JELFRelocObject {
|
||||
|
||||
ElfRelocTable elfRelocTable = new ElfRelocTable(sections.size());
|
||||
/*
|
||||
* For each of the symbols with associated relocation records, create a Elf relocation
|
||||
* entry.
|
||||
* For each of the symbols with associated relocation records, create a Elf relocation entry.
|
||||
*/
|
||||
for (Map.Entry<Symbol, List<Relocation>> entry : relocationTable.entrySet()) {
|
||||
List<Relocation> relocs = entry.getValue();
|
||||
@ -319,69 +295,39 @@ public class JELFRelocObject {
|
||||
return (elfRelocTable);
|
||||
}
|
||||
|
||||
private void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
|
||||
private static void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
|
||||
RelocType relocType = reloc.getType();
|
||||
|
||||
int elfRelocType = getELFRelocationType(relocType);
|
||||
ElfSymbol sym = (ElfSymbol)symbol.getNativeSymbol();
|
||||
ElfSymbol sym = (ElfSymbol) symbol.getNativeSymbol();
|
||||
int symno = sym.getIndex();
|
||||
int sectindex = reloc.getSection().getSectionId();
|
||||
int offset = reloc.getOffset();
|
||||
int addend = 0;
|
||||
|
||||
switch (relocType) {
|
||||
case FOREIGN_CALL_DIRECT:
|
||||
case JAVA_CALL_DIRECT:
|
||||
case STUB_CALL_DIRECT:
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
// Create relocation entry
|
||||
// System.out.println("getELFRelocationType: PLT relocation type using X86_64_RELOC_BRANCH");
|
||||
addend = -4; // Size in bytes of the patch location
|
||||
// Relocation should be applied at the location after call operand
|
||||
offset = offset + reloc.getSize() + addend;
|
||||
break;
|
||||
}
|
||||
case FOREIGN_CALL_DIRECT_FAR: {
|
||||
// Create relocation entry
|
||||
addend = -8; // Size in bytes of the patch location
|
||||
// Relocation should be applied at the location after call operand
|
||||
// 10 = 2 (jmp [r]) + 8 (imm64)
|
||||
offset = offset + reloc.getSize() + addend - 2;
|
||||
break;
|
||||
}
|
||||
case FOREIGN_CALL_INDIRECT:
|
||||
case JAVA_CALL_INDIRECT:
|
||||
case STUB_CALL_INDIRECT: {
|
||||
// Do nothing.
|
||||
return;
|
||||
}
|
||||
case EXTERNAL_DATA_REFERENCE_FAR: {
|
||||
// Create relocation entry
|
||||
case METASPACE_GOT_REFERENCE:
|
||||
case EXTERNAL_PLT_TO_GOT: {
|
||||
addend = -4; // Size of 32-bit address of the GOT
|
||||
/*
|
||||
* Relocation should be applied before the test instruction to the move instruction.
|
||||
* offset points to the test instruction after the instruction that loads
|
||||
* the address of polling page. So set the offset appropriately.
|
||||
* reloc.getOffset() points to the test instruction after the instruction that loads the address of
|
||||
* polling page. So set the offset appropriately.
|
||||
*/
|
||||
offset = offset + addend;
|
||||
break;
|
||||
}
|
||||
case METASPACE_GOT_REFERENCE:
|
||||
case EXTERNAL_PLT_TO_GOT:
|
||||
case STATIC_STUB_TO_STATIC_METHOD:
|
||||
case STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT: {
|
||||
addend = -4; // Size of 32-bit address of the GOT
|
||||
/*
|
||||
* Relocation should be applied before the test instruction to
|
||||
* the move instruction. reloc.getOffset() points to the
|
||||
* test instruction after the instruction that loads the
|
||||
* address of polling page. So set the offset appropriately.
|
||||
*/
|
||||
offset = offset + addend;
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_GOT_TO_PLT:
|
||||
case LOADTIME_ADDRESS: {
|
||||
case EXTERNAL_GOT_TO_PLT: {
|
||||
// this is load time relocations
|
||||
break;
|
||||
}
|
||||
@ -396,27 +342,17 @@ public class JELFRelocObject {
|
||||
switch (ElfTargetInfo.getElfArch()) {
|
||||
case Elf64_Ehdr.EM_X86_64:
|
||||
// Return R_X86_64_* entries based on relocType
|
||||
if (relocType == RelocType.FOREIGN_CALL_DIRECT ||
|
||||
relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
if (relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_PLT32;
|
||||
} else if (relocType == RelocType.STUB_CALL_DIRECT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_PC32;
|
||||
} else if (relocType == RelocType.FOREIGN_CALL_DIRECT_FAR) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_64;
|
||||
} else if (relocType == RelocType.FOREIGN_CALL_INDIRECT ||
|
||||
relocType == RelocType.JAVA_CALL_INDIRECT ||
|
||||
relocType == RelocType.STUB_CALL_INDIRECT) {
|
||||
} else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_NONE;
|
||||
} else if ((relocType == RelocType.EXTERNAL_DATA_REFERENCE_FAR)) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_GOTPCREL;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT ||
|
||||
relocType == RelocType.STATIC_STUB_TO_STATIC_METHOD ||
|
||||
relocType == RelocType.STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT) {
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_PC32;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT ||
|
||||
relocType == RelocType.LOADTIME_ADDRESS) {
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_64;
|
||||
} else {
|
||||
assert false : "Unhandled relocation type: " + relocType;
|
||||
@ -428,9 +364,9 @@ public class JELFRelocObject {
|
||||
return elfRelocType;
|
||||
}
|
||||
|
||||
private void createElfRelocSections(ArrayList<ElfSection> sections,
|
||||
ElfRelocTable elfRelocTable,
|
||||
int symtabsectidx) {
|
||||
private static void createElfRelocSections(ArrayList<ElfSection> sections,
|
||||
ElfRelocTable elfRelocTable,
|
||||
int symtabsectidx) {
|
||||
|
||||
// Grab count before we create new sections
|
||||
int count = sections.size();
|
||||
@ -439,15 +375,11 @@ public class JELFRelocObject {
|
||||
if (elfRelocTable.getNumRelocs(i) > 0) {
|
||||
ElfSection sect = sections.get(i);
|
||||
String relname = ".rela" + sect.getName();
|
||||
ElfSection relocSection = createByteSection(sections,
|
||||
relname,
|
||||
elfRelocTable.getRelocData(i),
|
||||
false,
|
||||
8,
|
||||
0,
|
||||
Elf64_Shdr.SHT_RELA);
|
||||
relocSection.setLink(symtabsectidx);
|
||||
relocSection.setInfo(sect.getSectionId());
|
||||
ElfSection relocSection = createByteSection(sections, relname,
|
||||
elfRelocTable.getRelocData(i),
|
||||
false, 8, 0, Elf64_Shdr.SHT_RELA);
|
||||
relocSection.setLink(symtabsectidx);
|
||||
relocSection.setInfo(sect.getSectionId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,11 +53,8 @@ import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
|
||||
import jdk.tools.jaotc.binformat.Relocation;
|
||||
import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.section_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64;
|
||||
@ -85,7 +82,7 @@ public class JMachORelocObject {
|
||||
this.segmentSize = binContainer.getCodeSegmentSize();
|
||||
}
|
||||
|
||||
private void createByteSection(ArrayList<MachOSection>sections,
|
||||
private void createByteSection(ArrayList<MachOSection> sections,
|
||||
ByteContainer c, String sectName, String segName, int scnFlags) {
|
||||
|
||||
if (c.getByteArray().length == 0) {
|
||||
@ -102,24 +99,24 @@ public class JMachORelocObject {
|
||||
sections.add(sect);
|
||||
|
||||
// Record the section Id (0 relative)
|
||||
c.setSectionId(sections.size()-1);
|
||||
c.setSectionId(sections.size() - 1);
|
||||
|
||||
// TODO: Clear out code section data to allow for GC
|
||||
// c.clear();
|
||||
}
|
||||
|
||||
private void createCodeSection(ArrayList<MachOSection>sections, CodeContainer c) {
|
||||
createByteSection(sections, c, /*c.getContainerName()*/ "__text", "__TEXT",
|
||||
section_64.S_ATTR_PURE_INSTRUCTIONS|
|
||||
private void createCodeSection(ArrayList<MachOSection> sections, CodeContainer c) {
|
||||
createByteSection(sections, c, /* c.getContainerName() */ "__text", "__TEXT",
|
||||
section_64.S_ATTR_PURE_INSTRUCTIONS |
|
||||
section_64.S_ATTR_SOME_INSTRUCTIONS);
|
||||
}
|
||||
|
||||
private void createReadOnlySection(ArrayList<MachOSection>sections, ReadOnlyDataContainer c) {
|
||||
private void createReadOnlySection(ArrayList<MachOSection> sections, ReadOnlyDataContainer c) {
|
||||
createByteSection(sections, c, c.getContainerName(), "__TEXT",
|
||||
section_64.S_ATTR_SOME_INSTRUCTIONS);
|
||||
}
|
||||
|
||||
private void createReadWriteSection(ArrayList<MachOSection>sections, ByteContainer c) {
|
||||
private void createReadWriteSection(ArrayList<MachOSection> sections, ByteContainer c) {
|
||||
createByteSection(sections, c, c.getContainerName(), "__DATA", section_64.S_REGULAR);
|
||||
}
|
||||
|
||||
@ -140,7 +137,7 @@ public class JMachORelocObject {
|
||||
|
||||
MachOHeader mh = new MachOHeader();
|
||||
|
||||
ArrayList<MachOSection> sections = new ArrayList<MachOSection>();
|
||||
ArrayList<MachOSection> sections = new ArrayList<>();
|
||||
|
||||
// Create Sections contained in the main Segment LC_SEGMENT_64
|
||||
|
||||
@ -149,21 +146,19 @@ public class JMachORelocObject {
|
||||
createReadOnlySection(sections, binContainer.getKlassesOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getMethodsOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getKlassesDependenciesContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetaspaceGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodStateContainer());
|
||||
createReadWriteSection(sections, binContainer.getOopGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodMetadataContainer());
|
||||
createReadOnlySection(sections, binContainer.getMethodMetadataContainer());
|
||||
createReadOnlySection(sections, binContainer.getStubsOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getHeaderContainer().getContainer());
|
||||
createReadOnlySection(sections, binContainer.getCodeSegmentsContainer());
|
||||
createReadOnlySection(sections, binContainer.getConstantDataContainer());
|
||||
createReadOnlySection(sections, binContainer.getConfigContainer());
|
||||
|
||||
// createExternalLinkage();
|
||||
|
||||
createCodeSection(sections, binContainer.getExtLinkageContainer());
|
||||
createReadWriteSection(sections, binContainer.getKlassesGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getCountersGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodStateContainer());
|
||||
createReadWriteSection(sections, binContainer.getOopGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getExtLinkageGOTContainer());
|
||||
|
||||
// Update the Header sizeofcmds size.
|
||||
// This doesn't include the Header struct size
|
||||
mh.setCmdSizes(4, segment_command_64.totalsize +
|
||||
@ -175,14 +170,14 @@ public class JMachORelocObject {
|
||||
// Initialize file offset for data past commands
|
||||
int file_offset = mach_header_64.totalsize + mh.getCmdSize();
|
||||
// and round it up
|
||||
file_offset = (file_offset + (sections.get(0).getAlign()-1)) & ~((sections.get(0).getAlign()-1));
|
||||
file_offset = (file_offset + (sections.get(0).getAlign() - 1)) & ~((sections.get(0).getAlign() - 1));
|
||||
long address = 0;
|
||||
int segment_offset = file_offset;
|
||||
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
MachOSection sect = sections.get(i);
|
||||
file_offset = (file_offset + (sect.getAlign()-1)) & ~((sect.getAlign()-1));
|
||||
address = (address + (sect.getAlign()-1)) & ~((sect.getAlign()-1));
|
||||
file_offset = (file_offset + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1));
|
||||
address = (address + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1));
|
||||
sect.setOffset(file_offset);
|
||||
sect.setAddr(address);
|
||||
file_offset += sect.getSize();
|
||||
@ -199,7 +194,6 @@ public class JMachORelocObject {
|
||||
segment_size,
|
||||
sections.size());
|
||||
|
||||
|
||||
MachOVersion vers = new MachOVersion();
|
||||
|
||||
// Get symbol data from BinaryContainer object's symbol tables
|
||||
@ -213,7 +207,7 @@ public class JMachORelocObject {
|
||||
// Create the Relocation Tables
|
||||
MachORelocTable machORelocs = createMachORelocTable(sections, relocationTable, symtab);
|
||||
// Calculate file offset for relocation data
|
||||
file_offset = (file_offset + (machORelocs.getAlign()-1)) & ~((machORelocs.getAlign()-1));
|
||||
file_offset = (file_offset + (MachORelocTable.getAlign() - 1)) & ~((MachORelocTable.getAlign() - 1));
|
||||
|
||||
// Update relocation sizing information in each section
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
@ -227,10 +221,9 @@ public class JMachORelocObject {
|
||||
}
|
||||
|
||||
// Calculate and set file offset for symbol table data
|
||||
file_offset = (file_offset + (symtab.getAlign()-1)) & ~((symtab.getAlign()-1));
|
||||
file_offset = (file_offset + (MachOSymtab.getAlign() - 1)) & ~((MachOSymtab.getAlign() - 1));
|
||||
symtab.setOffset(file_offset);
|
||||
|
||||
|
||||
// Write Out Header
|
||||
machoContainer.writeBytes(mh.getArray());
|
||||
// Write out first Segment
|
||||
@ -259,12 +252,13 @@ public class JMachORelocObject {
|
||||
|
||||
// Write out the relocation tables for all sections
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
if (machORelocs.getNumRelocs(i) > 0)
|
||||
machoContainer.writeBytes(machORelocs.getRelocData(i), machORelocs.getAlign());
|
||||
if (machORelocs.getNumRelocs(i) > 0) {
|
||||
machoContainer.writeBytes(machORelocs.getRelocData(i), MachORelocTable.getAlign());
|
||||
}
|
||||
}
|
||||
|
||||
// Write out data associated with LC_SYMTAB
|
||||
machoContainer.writeBytes(symtab.getDataArray(), symtab.getAlign());
|
||||
machoContainer.writeBytes(symtab.getDataArray(), MachOSymtab.getAlign());
|
||||
|
||||
machoContainer.close();
|
||||
}
|
||||
@ -273,14 +267,14 @@ public class JMachORelocObject {
|
||||
* Construct MachO symbol data from BinaryContainer object's symbol tables. Both dynamic MachO
|
||||
* symbol table and MachO symbol table are created from BinaryContainer's symbol info.
|
||||
*
|
||||
* @param sections
|
||||
* @param symbols
|
||||
* @param symtab
|
||||
*/
|
||||
private MachOSymtab createMachOSymbolTables(ArrayList<MachOSection>sections,
|
||||
Collection<Symbol> symbols) {
|
||||
private static MachOSymtab createMachOSymbolTables(ArrayList<MachOSection> sections,
|
||||
Collection<Symbol> symbols) {
|
||||
MachOSymtab symtab = new MachOSymtab();
|
||||
// First, create the initial null symbol. This is a local symbol.
|
||||
symtab.addSymbolEntry("", (byte)nlist_64.N_UNDF, (byte)0, (long)0);
|
||||
symtab.addSymbolEntry("", (byte) nlist_64.N_UNDF, (byte) 0, 0);
|
||||
|
||||
// Now create MachO symbol entries for all symbols.
|
||||
for (Symbol symbol : symbols) {
|
||||
@ -290,14 +284,14 @@ public class JMachORelocObject {
|
||||
long sectionAddr = sections.get(sectionId).getAddr();
|
||||
|
||||
MachOSymbol machoSymbol = symtab.addSymbolEntry(symbol.getName(),
|
||||
getMachOTypeOf(symbol),
|
||||
(byte)sectionId,
|
||||
symbol.getOffset() + sectionAddr);
|
||||
symbol.setNativeSymbol((NativeSymbol)machoSymbol);
|
||||
getMachOTypeOf(symbol),
|
||||
(byte) sectionId,
|
||||
symbol.getOffset() + sectionAddr);
|
||||
symbol.setNativeSymbol(machoSymbol);
|
||||
}
|
||||
|
||||
// Now that all symbols are enterred, update the
|
||||
// symbol indexes. This is necessary since they will
|
||||
// symbol indexes. This is necessary since they will
|
||||
// be reordered based on local, global and undefined.
|
||||
symtab.updateIndexes();
|
||||
|
||||
@ -309,9 +303,9 @@ public class JMachORelocObject {
|
||||
byte type = nlist_64.N_UNDF;
|
||||
|
||||
// Global or Local
|
||||
if (sym.getBinding() == Symbol.Binding.GLOBAL)
|
||||
if (sym.getBinding() == Symbol.Binding.GLOBAL) {
|
||||
type = nlist_64.N_EXT;
|
||||
|
||||
}
|
||||
// If Function or Data, add section type
|
||||
if (kind == Symbol.Kind.NATIVE_FUNCTION ||
|
||||
kind == Symbol.Kind.JAVA_FUNCTION ||
|
||||
@ -335,8 +329,7 @@ public class JMachORelocObject {
|
||||
|
||||
MachORelocTable machORelocTable = new MachORelocTable(sections.size());
|
||||
/*
|
||||
* For each of the symbols with associated relocation records, create a MachO relocation
|
||||
* entry.
|
||||
* For each of the symbols with associated relocation records, create a MachO relocation entry.
|
||||
*/
|
||||
for (Map.Entry<Symbol, List<Relocation>> entry : relocationTable.entrySet()) {
|
||||
List<Relocation> relocs = entry.getValue();
|
||||
@ -354,11 +347,11 @@ public class JMachORelocObject {
|
||||
return (machORelocTable);
|
||||
}
|
||||
|
||||
private void createRelocation(Symbol symbol, Relocation reloc, MachORelocTable machORelocTable) {
|
||||
private static void createRelocation(Symbol symbol, Relocation reloc, MachORelocTable machORelocTable) {
|
||||
RelocType relocType = reloc.getType();
|
||||
|
||||
int machORelocType = getMachORelocationType(relocType);
|
||||
MachOSymbol sym = (MachOSymbol)symbol.getNativeSymbol();
|
||||
MachOSymbol sym = (MachOSymbol) symbol.getNativeSymbol();
|
||||
int symno = sym.getIndex();
|
||||
int sectindex = reloc.getSection().getSectionId();
|
||||
int offset = reloc.getOffset();
|
||||
@ -366,73 +359,39 @@ public class JMachORelocObject {
|
||||
int length = 0;
|
||||
int isextern = 1;
|
||||
|
||||
/*
|
||||
System.out.println("reloctype: " + relocType + " size is " +
|
||||
reloc.getSize() + " offset is " + offset +
|
||||
" Section Index is " + (sectindex) +
|
||||
" Symbol Index is " + symno +
|
||||
" Symbol Name is " + symbol.getName() + "\n");
|
||||
*/
|
||||
|
||||
switch (relocType) {
|
||||
case FOREIGN_CALL_DIRECT:
|
||||
case JAVA_CALL_DIRECT:
|
||||
case STUB_CALL_DIRECT:
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
// Create relocation entry
|
||||
// System.out.println("getMachORelocationType: PLT relocation type using X86_64_RELOC_BRANCH");
|
||||
int addend = -4; // Size in bytes of the patch location
|
||||
// Relocation should be applied at the location after call operand
|
||||
offset = offset + reloc.getSize() + addend;
|
||||
pcrel = 1; length = 2;
|
||||
pcrel = 1;
|
||||
length = 2;
|
||||
break;
|
||||
}
|
||||
case FOREIGN_CALL_DIRECT_FAR: {
|
||||
// Create relocation entry
|
||||
int addend = -8; // Size in bytes of the patch location
|
||||
// Relocation should be applied at the location after call operand
|
||||
// 10 = 2 (jmp [r]) + 8 (imm64)
|
||||
offset = offset + reloc.getSize() + addend - 2;
|
||||
pcrel = 0; length = 3;
|
||||
break;
|
||||
}
|
||||
case FOREIGN_CALL_INDIRECT:
|
||||
case JAVA_CALL_INDIRECT:
|
||||
case STUB_CALL_INDIRECT: {
|
||||
case JAVA_CALL_INDIRECT: {
|
||||
// Do nothing.
|
||||
return;
|
||||
}
|
||||
case EXTERNAL_DATA_REFERENCE_FAR: {
|
||||
// Create relocation entry
|
||||
case METASPACE_GOT_REFERENCE:
|
||||
case EXTERNAL_PLT_TO_GOT: {
|
||||
int addend = -4; // Size of 32-bit address of the GOT
|
||||
/*
|
||||
* Relocation should be applied before the test instruction to the move instruction.
|
||||
* offset points to the test instruction after the instruction that loads
|
||||
* the address of polling page. So set the offset appropriately.
|
||||
* reloc.getOffset() points to the test instruction after the instruction that loads the address of
|
||||
* polling page. So set the offset appropriately.
|
||||
*/
|
||||
offset = offset + addend;
|
||||
pcrel = 0; length = 2;
|
||||
pcrel = 1;
|
||||
length = 2;
|
||||
break;
|
||||
}
|
||||
case METASPACE_GOT_REFERENCE:
|
||||
case EXTERNAL_PLT_TO_GOT:
|
||||
case STATIC_STUB_TO_STATIC_METHOD:
|
||||
case STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT: {
|
||||
int addend = -4; // Size of 32-bit address of the GOT
|
||||
/*
|
||||
* Relocation should be applied before the test instruction to
|
||||
* the move instruction. reloc.getOffset() points to the
|
||||
* test instruction after the instruction that loads the
|
||||
* address of polling page. So set the offset appropriately.
|
||||
*/
|
||||
offset = offset + addend;
|
||||
pcrel = 1; length = 2;
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_GOT_TO_PLT:
|
||||
case LOADTIME_ADDRESS: {
|
||||
case EXTERNAL_GOT_TO_PLT: {
|
||||
// this is load time relocations
|
||||
pcrel = 0; length = 3;
|
||||
pcrel = 0;
|
||||
length = 3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -448,20 +407,17 @@ public class JMachORelocObject {
|
||||
switch (MachOTargetInfo.getMachOArch()) {
|
||||
case mach_header_64.CPU_TYPE_X86_64:
|
||||
// Return X86_64_RELOC_* entries based on relocType
|
||||
if (relocType == RelocType.FOREIGN_CALL_DIRECT || relocType == RelocType.JAVA_CALL_DIRECT || relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
if (relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_BRANCH;
|
||||
} else if (relocType == RelocType.STUB_CALL_DIRECT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_BRANCH;
|
||||
} else if (relocType == RelocType.FOREIGN_CALL_DIRECT_FAR) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_UNSIGNED;
|
||||
} else if (relocType == RelocType.FOREIGN_CALL_INDIRECT || relocType == RelocType.JAVA_CALL_INDIRECT || relocType == RelocType.STUB_CALL_INDIRECT) {
|
||||
} else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_NONE;
|
||||
} else if ((relocType == RelocType.EXTERNAL_DATA_REFERENCE_FAR)) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_GOT;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE || relocType == RelocType.EXTERNAL_PLT_TO_GOT || relocType == RelocType.STATIC_STUB_TO_STATIC_METHOD ||
|
||||
relocType == RelocType.STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT) {
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_BRANCH;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT || relocType == RelocType.LOADTIME_ADDRESS) {
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_UNSIGNED;
|
||||
} else {
|
||||
assert false : "Unhandled relocation type: " + relocType;
|
||||
|
@ -23,10 +23,10 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
//@formatter:off
|
||||
/**
|
||||
*
|
||||
* Support for the creation of Mach-o Object files.
|
||||
* Current support is limited to 64 bit x86_64.
|
||||
* Support for the creation of Mach-o Object files. Current support is limited to 64 bit x86_64.
|
||||
*
|
||||
* File Format Overview:
|
||||
*
|
||||
@ -38,12 +38,12 @@ package jdk.tools.jaotc.binformat.macho;
|
||||
* (which each include multiple Sections)
|
||||
*/
|
||||
|
||||
public class MachO {
|
||||
final class MachO {
|
||||
|
||||
/**
|
||||
* mach_header_64 structure defines
|
||||
*/
|
||||
public enum mach_header_64 {
|
||||
enum mach_header_64 {
|
||||
magic( 0, 4),
|
||||
cputype( 4, 4),
|
||||
cpusubtype( 8, 4),
|
||||
@ -53,49 +53,49 @@ public class MachO {
|
||||
flags(24, 4),
|
||||
reserved(28, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
mach_header_64(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 32;
|
||||
static int totalsize = 32;
|
||||
|
||||
/**
|
||||
* mach_header_64 defines
|
||||
*/
|
||||
public static final int MH_MAGIC = 0xfeedface;
|
||||
public static final int MH_MAGIC_64 = 0xfeedfacf;
|
||||
public static final int MH_SUBSECTIONS_VIA_SYMBOLS = 0x2000;
|
||||
static final int MH_MAGIC = 0xfeedface;
|
||||
static final int MH_MAGIC_64 = 0xfeedfacf;
|
||||
static final int MH_SUBSECTIONS_VIA_SYMBOLS = 0x2000;
|
||||
|
||||
/**
|
||||
* filetype
|
||||
*/
|
||||
public static final int MH_OBJECT = 0x1;
|
||||
static final int MH_OBJECT = 0x1;
|
||||
|
||||
/**
|
||||
* cputype
|
||||
*/
|
||||
public static final int CPU_TYPE_ANY = -1;
|
||||
public static final int CPU_ARCH_ABI64 = 0x1000000;
|
||||
public static final int CPU_TYPE_X86_64 = 0x1000007;
|
||||
public static final int CPU_TYPE_ARM64 = 0x100000c;
|
||||
static final int CPU_TYPE_ANY = -1;
|
||||
static final int CPU_ARCH_ABI64 = 0x1000000;
|
||||
static final int CPU_TYPE_X86_64 = 0x1000007;
|
||||
static final int CPU_TYPE_ARM64 = 0x100000c;
|
||||
/**
|
||||
* cpusubtype
|
||||
*/
|
||||
public static final int CPU_SUBTYPE_I386_ALL = 3;
|
||||
public static final int CPU_SUBTYPE_ARM64_ALL = 0;
|
||||
public static final int CPU_SUBTYPE_LITTLE_ENDIAN = 0;
|
||||
public static final int CPU_SUBTYPE_BIG_ENDIAN = 1;
|
||||
static final int CPU_SUBTYPE_I386_ALL = 3;
|
||||
static final int CPU_SUBTYPE_ARM64_ALL = 0;
|
||||
static final int CPU_SUBTYPE_LITTLE_ENDIAN = 0;
|
||||
static final int CPU_SUBTYPE_BIG_ENDIAN = 1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* segment_command_64 structure defines
|
||||
*/
|
||||
public enum segment_command_64 {
|
||||
enum segment_command_64 {
|
||||
cmd( 0, 4),
|
||||
cmdsize( 4, 4),
|
||||
segname( 8,16),
|
||||
@ -108,23 +108,23 @@ public class MachO {
|
||||
nsects(64, 4),
|
||||
flags(68, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
segment_command_64(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 72;
|
||||
static int totalsize = 72;
|
||||
|
||||
public static final int LC_SEGMENT_64 = 0x19;
|
||||
static final int LC_SEGMENT_64 = 0x19;
|
||||
}
|
||||
|
||||
/**
|
||||
* section_64 structure defines
|
||||
*/
|
||||
public enum section_64 {
|
||||
enum section_64 {
|
||||
sectname( 0,16),
|
||||
segname(16,16),
|
||||
addr(32, 8),
|
||||
@ -138,49 +138,49 @@ public class MachO {
|
||||
reserved2(72, 4),
|
||||
reserved3(76, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
section_64(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 80;
|
||||
static int totalsize = 80;
|
||||
|
||||
public static int S_REGULAR = 0x0;
|
||||
public static int S_CSTRING_LITERALS = 0x2;
|
||||
public static int S_ATTR_PURE_INSTRUCTIONS = 0x80000000;
|
||||
public static int S_ATTR_SOME_INSTRUCTIONS = 0x400;
|
||||
static int S_REGULAR = 0x0;
|
||||
static int S_CSTRING_LITERALS = 0x2;
|
||||
static int S_ATTR_PURE_INSTRUCTIONS = 0x80000000;
|
||||
static int S_ATTR_SOME_INSTRUCTIONS = 0x400;
|
||||
}
|
||||
|
||||
/**
|
||||
* version_min_command structure defines
|
||||
*/
|
||||
public enum version_min_command {
|
||||
enum version_min_command {
|
||||
cmd( 0, 4),
|
||||
cmdsize( 4, 4),
|
||||
version( 8, 4),
|
||||
sdk(12, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
version_min_command(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 16;
|
||||
static int totalsize = 16;
|
||||
|
||||
public static final int LC_VERSION_MIN_MACOSX = 0x24;
|
||||
public static final int LC_VERSION_MIN_IPHONEOS = 0x25;
|
||||
static final int LC_VERSION_MIN_MACOSX = 0x24;
|
||||
static final int LC_VERSION_MIN_IPHONEOS = 0x25;
|
||||
}
|
||||
|
||||
/**
|
||||
* symtab_command structure defines
|
||||
*/
|
||||
public enum symtab_command {
|
||||
enum symtab_command {
|
||||
cmd( 0, 4),
|
||||
cmdsize( 4, 4),
|
||||
symoff( 8, 4),
|
||||
@ -188,17 +188,17 @@ public class MachO {
|
||||
stroff(16, 4),
|
||||
strsize(20, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
symtab_command(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 24;
|
||||
static int totalsize = 24;
|
||||
|
||||
public static final int LC_SYMTAB = 0x2;
|
||||
static final int LC_SYMTAB = 0x2;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,33 +206,33 @@ public class MachO {
|
||||
*
|
||||
* nlist_64 structure defines
|
||||
*/
|
||||
public enum nlist_64 {
|
||||
enum nlist_64 {
|
||||
n_strx( 0, 4),
|
||||
n_type( 4, 1),
|
||||
n_sect( 5, 1),
|
||||
n_desc( 6, 2),
|
||||
n_value( 8, 8);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
nlist_64(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 16;
|
||||
static int totalsize = 16;
|
||||
|
||||
public static final int N_EXT = 0x1;
|
||||
public static final int N_TYPE = 0xe;
|
||||
public static final int N_UNDF = 0x0;
|
||||
public static final int N_SECT = 0xe;
|
||||
static final int N_EXT = 0x1;
|
||||
static final int N_TYPE = 0xe;
|
||||
static final int N_UNDF = 0x0;
|
||||
static final int N_SECT = 0xe;
|
||||
}
|
||||
|
||||
/**
|
||||
* dysymtab_command structure defines
|
||||
*/
|
||||
public enum dysymtab_command {
|
||||
enum dysymtab_command {
|
||||
cmd( 0, 4),
|
||||
cmdsize( 4, 4),
|
||||
ilocalsym( 8, 4),
|
||||
@ -254,54 +254,55 @@ public class MachO {
|
||||
locreloff(72, 4),
|
||||
nlocrel(76, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
dysymtab_command(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 80;
|
||||
static int totalsize = 80;
|
||||
|
||||
public static final int LC_DYSYMTAB = 0xb;
|
||||
static final int LC_DYSYMTAB = 0xb;
|
||||
}
|
||||
|
||||
/**
|
||||
* relocation_info structure defines
|
||||
*/
|
||||
public enum reloc_info {
|
||||
enum reloc_info {
|
||||
r_address( 0, 4),
|
||||
r_relocinfo( 4, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
reloc_info(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 8;
|
||||
static int totalsize = 8;
|
||||
|
||||
public static final int REL_SYMNUM_MASK = 0xffffff;
|
||||
public static final int REL_SYMNUM_SHIFT = 0x0;
|
||||
public static final int REL_PCREL_MASK = 0x1;
|
||||
public static final int REL_PCREL_SHIFT = 0x18;
|
||||
public static final int REL_LENGTH_MASK = 0x3;
|
||||
public static final int REL_LENGTH_SHIFT = 0x19;
|
||||
public static final int REL_EXTERN_MASK = 0x1;
|
||||
public static final int REL_EXTERN_SHIFT = 0x1b;
|
||||
public static final int REL_TYPE_MASK = 0xf;
|
||||
public static final int REL_TYPE_SHIFT = 0x1c;
|
||||
static final int REL_SYMNUM_MASK = 0xffffff;
|
||||
static final int REL_SYMNUM_SHIFT = 0x0;
|
||||
static final int REL_PCREL_MASK = 0x1;
|
||||
static final int REL_PCREL_SHIFT = 0x18;
|
||||
static final int REL_LENGTH_MASK = 0x3;
|
||||
static final int REL_LENGTH_SHIFT = 0x19;
|
||||
static final int REL_EXTERN_MASK = 0x1;
|
||||
static final int REL_EXTERN_SHIFT = 0x1b;
|
||||
static final int REL_TYPE_MASK = 0xf;
|
||||
static final int REL_TYPE_SHIFT = 0x1c;
|
||||
|
||||
/* reloc_type_x86_64 defines */
|
||||
|
||||
public static final int X86_64_RELOC_NONE = 0x0;
|
||||
public static final int X86_64_RELOC_BRANCH = 0x2;
|
||||
public static final int X86_64_RELOC_GOT = 0x4;
|
||||
public static final int X86_64_RELOC_GOT_LOAD = 0x3;
|
||||
public static final int X86_64_RELOC_SIGNED = 0x1;
|
||||
public static final int X86_64_RELOC_UNSIGNED = 0x0;
|
||||
static final int X86_64_RELOC_NONE = 0x0;
|
||||
static final int X86_64_RELOC_BRANCH = 0x2;
|
||||
static final int X86_64_RELOC_GOT = 0x4;
|
||||
static final int X86_64_RELOC_GOT_LOAD = 0x3;
|
||||
static final int X86_64_RELOC_SIGNED = 0x1;
|
||||
static final int X86_64_RELOC_UNSIGNED = 0x0;
|
||||
}
|
||||
}
|
||||
//@formatter:on
|
||||
|
@ -23,21 +23,19 @@
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64;
|
||||
|
||||
public class MachOByteBuffer {
|
||||
final class MachOByteBuffer {
|
||||
|
||||
public static ByteBuffer allocate(int size) {
|
||||
static ByteBuffer allocate(int size) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(size);
|
||||
if (MachOTargetInfo.getMachOEndian() ==
|
||||
MachO.mach_header_64.CPU_SUBTYPE_LITTLE_ENDIAN)
|
||||
if (MachOTargetInfo.getMachOEndian() == MachO.mach_header_64.CPU_SUBTYPE_LITTLE_ENDIAN) {
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
else
|
||||
} else {
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,13 @@ package jdk.tools.jaotc.binformat.macho;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class MachOContainer {
|
||||
final class MachOContainer {
|
||||
|
||||
File outputFile;
|
||||
FileOutputStream outputStream;
|
||||
long fileOffset;
|
||||
private final File outputFile;
|
||||
private FileOutputStream outputStream;
|
||||
private long fileOffset;
|
||||
|
||||
public MachOContainer(String fileName) {
|
||||
String baseName;
|
||||
MachOContainer(String fileName) {
|
||||
|
||||
outputFile = new File(fileName);
|
||||
if (outputFile.exists()) {
|
||||
@ -48,7 +47,7 @@ public class MachOContainer {
|
||||
fileOffset = 0;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
void close() {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
@ -56,7 +55,7 @@ public class MachOContainer {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(byte [] bytes) {
|
||||
void writeBytes(byte[] bytes) {
|
||||
try {
|
||||
outputStream.write(bytes);
|
||||
} catch (Exception e) {
|
||||
@ -66,10 +65,10 @@ public class MachOContainer {
|
||||
}
|
||||
|
||||
// Write bytes to output file with up front alignment padding
|
||||
public void writeBytes(byte [] bytes, int alignment) {
|
||||
void writeBytes(byte[] bytes, int alignment) {
|
||||
try {
|
||||
// Pad to alignment
|
||||
while ((fileOffset & (long)(alignment-1)) != 0) {
|
||||
while ((fileOffset & (alignment - 1)) != 0) {
|
||||
outputStream.write(0);
|
||||
fileOffset++;
|
||||
}
|
||||
@ -80,4 +79,3 @@ public class MachOContainer {
|
||||
fileOffset += bytes.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,16 +24,14 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.dysymtab_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachODySymtab {
|
||||
ByteBuffer dysymtab;
|
||||
final class MachODySymtab {
|
||||
private final ByteBuffer dysymtab;
|
||||
|
||||
public MachODySymtab(int nlocal, int nglobal, int nundef) {
|
||||
MachODySymtab(int nlocal, int nglobal, int nundef) {
|
||||
dysymtab = MachOByteBuffer.allocate(dysymtab_command.totalsize);
|
||||
|
||||
dysymtab.putInt(dysymtab_command.cmd.off, dysymtab_command.LC_DYSYMTAB);
|
||||
@ -42,13 +40,11 @@ public class MachODySymtab {
|
||||
dysymtab.putInt(dysymtab_command.nlocalsym.off, nlocal);
|
||||
dysymtab.putInt(dysymtab_command.iextdefsym.off, nlocal);
|
||||
dysymtab.putInt(dysymtab_command.nextdefsym.off, nglobal);
|
||||
dysymtab.putInt(dysymtab_command.iundefsym.off, nlocal+nglobal);
|
||||
dysymtab.putInt(dysymtab_command.iundefsym.off, nlocal + nglobal);
|
||||
dysymtab.putInt(dysymtab_command.nundefsym.off, nundef);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return dysymtab.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,17 +24,15 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachOHeader {
|
||||
ByteBuffer header;
|
||||
final class MachOHeader {
|
||||
private final ByteBuffer header;
|
||||
|
||||
public MachOHeader() {
|
||||
MachOHeader() {
|
||||
header = MachOByteBuffer.allocate(mach_header_64.totalsize);
|
||||
|
||||
header.putInt(mach_header_64.magic.off, mach_header_64.MH_MAGIC_64);
|
||||
@ -44,17 +42,16 @@ public class MachOHeader {
|
||||
header.putInt(mach_header_64.filetype.off, mach_header_64.MH_OBJECT);
|
||||
}
|
||||
|
||||
public void setCmdSizes(int ncmds, int sizeofcmds) {
|
||||
void setCmdSizes(int ncmds, int sizeofcmds) {
|
||||
header.putInt(mach_header_64.ncmds.off, ncmds);
|
||||
header.putInt(mach_header_64.sizeofcmds.off, sizeofcmds);
|
||||
}
|
||||
|
||||
public int getCmdSize() {
|
||||
int getCmdSize() {
|
||||
return (header.getInt(mach_header_64.sizeofcmds.off));
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return header.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,42 +24,31 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.reloc_info;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachORelocEntry {
|
||||
ByteBuffer entry;
|
||||
final class MachORelocEntry {
|
||||
private final ByteBuffer entry;
|
||||
|
||||
public MachORelocEntry(int offset,
|
||||
int symno,
|
||||
int pcrel,
|
||||
int length,
|
||||
int isextern,
|
||||
int type) {
|
||||
MachORelocEntry(int offset, int symno, int pcrel, int length, int isextern, int type) {
|
||||
|
||||
entry = MachOByteBuffer.allocate(reloc_info.totalsize);
|
||||
|
||||
entry.putInt(reloc_info.r_address.off, offset);
|
||||
|
||||
// Encode and store the relocation entry bitfields
|
||||
// @formatter:off
|
||||
entry.putInt(reloc_info.r_relocinfo.off,
|
||||
((symno & reloc_info.REL_SYMNUM_MASK)
|
||||
<< reloc_info.REL_SYMNUM_SHIFT) |
|
||||
((pcrel & reloc_info.REL_PCREL_MASK)
|
||||
<< reloc_info.REL_PCREL_SHIFT) |
|
||||
((length & reloc_info.REL_LENGTH_MASK)
|
||||
<< reloc_info.REL_LENGTH_SHIFT) |
|
||||
((isextern & reloc_info.REL_EXTERN_MASK)
|
||||
<< reloc_info.REL_EXTERN_SHIFT) |
|
||||
((type & reloc_info.REL_TYPE_MASK)
|
||||
<< reloc_info.REL_TYPE_SHIFT));
|
||||
((symno & reloc_info.REL_SYMNUM_MASK) << reloc_info.REL_SYMNUM_SHIFT) |
|
||||
((pcrel & reloc_info.REL_PCREL_MASK) << reloc_info.REL_PCREL_SHIFT) |
|
||||
((length & reloc_info.REL_LENGTH_MASK) << reloc_info.REL_LENGTH_SHIFT) |
|
||||
((isextern & reloc_info.REL_EXTERN_MASK) << reloc_info.REL_EXTERN_SHIFT) |
|
||||
((type & reloc_info.REL_TYPE_MASK) << reloc_info.REL_TYPE_SHIFT));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return entry.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,56 +25,43 @@ package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachORelocEntry;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.reloc_info;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachORelocTable {
|
||||
ArrayList<ArrayList<MachORelocEntry>> relocEntries;
|
||||
final class MachORelocTable {
|
||||
private final ArrayList<ArrayList<MachORelocEntry>> relocEntries;
|
||||
int fileOffset;
|
||||
|
||||
public MachORelocTable(int numsects) {
|
||||
relocEntries = new ArrayList<ArrayList<MachORelocEntry>>(numsects);
|
||||
for (int i = 0; i < numsects; i++)
|
||||
MachORelocTable(int numsects) {
|
||||
relocEntries = new ArrayList<>(numsects);
|
||||
for (int i = 0; i < numsects; i++) {
|
||||
relocEntries.add(new ArrayList<MachORelocEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
public void createRelocationEntry(int sectindex,
|
||||
int offset,
|
||||
int symno,
|
||||
int pcrel,
|
||||
int length,
|
||||
int isextern,
|
||||
int type) {
|
||||
|
||||
MachORelocEntry entry = new MachORelocEntry(offset,
|
||||
symno,
|
||||
pcrel,
|
||||
length,
|
||||
isextern,
|
||||
type);
|
||||
void createRelocationEntry(int sectindex, int offset, int symno, int pcrel, int length, int isextern, int type) {
|
||||
MachORelocEntry entry = new MachORelocEntry(offset, symno, pcrel, length, isextern, type);
|
||||
relocEntries.get(sectindex).add(entry);
|
||||
}
|
||||
|
||||
public int getAlign() {
|
||||
static int getAlign() {
|
||||
return (4);
|
||||
}
|
||||
|
||||
public int getNumRelocs(int section_index) {
|
||||
int getNumRelocs(int section_index) {
|
||||
return relocEntries.get(section_index).size();
|
||||
}
|
||||
|
||||
// Return the relocation entries for a single section
|
||||
// or null if no entries added to section
|
||||
public byte [] getRelocData(int section_index) {
|
||||
// or null if no entries added to section
|
||||
byte[] getRelocData(int section_index) {
|
||||
ArrayList<MachORelocEntry> entryList = relocEntries.get(section_index);
|
||||
|
||||
if (entryList.size() == 0)
|
||||
if (entryList.size() == 0) {
|
||||
return null;
|
||||
|
||||
}
|
||||
ByteBuffer relocData = MachOByteBuffer.allocate(entryList.size() * reloc_info.totalsize);
|
||||
|
||||
// Copy each entry to a single ByteBuffer
|
||||
@ -86,4 +73,3 @@ public class MachORelocTable {
|
||||
return (relocData.array());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,41 +24,36 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.section_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachOSection {
|
||||
ByteBuffer section;
|
||||
byte [] data;
|
||||
boolean hasrelocations;
|
||||
final class MachOSection {
|
||||
private final ByteBuffer section;
|
||||
private final byte[] data;
|
||||
private final boolean hasrelocations;
|
||||
|
||||
public MachOSection(String sectName, String segName, byte [] sectData, int sectFlags, boolean hasRelocations, int align) {
|
||||
MachOSection(String sectName, String segName, byte[] sectData, int sectFlags, boolean hasRelocations, int align) {
|
||||
section = MachOByteBuffer.allocate(section_64.totalsize);
|
||||
|
||||
// TODO: Hotspot uses long section names.
|
||||
// They are getting truncated.
|
||||
// Is this a problem??
|
||||
// They are getting truncated.
|
||||
// Is this a problem??
|
||||
byte[] sectNameBytes = sectName.getBytes();
|
||||
int sectNameMax = section_64.sectname.sz < sectNameBytes.length ?
|
||||
section_64.sectname.sz : sectNameBytes.length;
|
||||
|
||||
for (int i = 0; i < sectNameMax; i++)
|
||||
section.put(section_64.sectname.off+i, sectNameBytes[i]);
|
||||
int sectNameMax = section_64.sectname.sz < sectNameBytes.length ? section_64.sectname.sz : sectNameBytes.length;
|
||||
|
||||
for (int i = 0; i < sectNameMax; i++) {
|
||||
section.put(section_64.sectname.off + i, sectNameBytes[i]);
|
||||
}
|
||||
byte[] segNameBytes = segName.getBytes();
|
||||
int segNameMax = section_64.segname.sz < segNameBytes.length ?
|
||||
section_64.segname.sz : segNameBytes.length;
|
||||
|
||||
for (int i = 0; i < segNameMax; i++)
|
||||
section.put(section_64.segname.off+i, segNameBytes[i]);
|
||||
int segNameMax = section_64.segname.sz < segNameBytes.length ? section_64.segname.sz : segNameBytes.length;
|
||||
|
||||
for (int i = 0; i < segNameMax; i++) {
|
||||
section.put(section_64.segname.off + i, segNameBytes[i]);
|
||||
}
|
||||
section.putLong(section_64.size.off, sectData.length);
|
||||
|
||||
section.putInt(section_64.align.off,
|
||||
31 - Integer.numberOfLeadingZeros(align));
|
||||
section.putInt(section_64.align.off, 31 - Integer.numberOfLeadingZeros(align));
|
||||
|
||||
section.putInt(section_64.flags.off, sectFlags);
|
||||
|
||||
@ -67,49 +62,47 @@ public class MachOSection {
|
||||
hasrelocations = hasRelocations;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
long getSize() {
|
||||
return section.getLong(section_64.size.off);
|
||||
}
|
||||
|
||||
public int getAlign() {
|
||||
int getAlign() {
|
||||
return (1 << section.getInt(section_64.align.off));
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return section.array();
|
||||
}
|
||||
|
||||
public byte[] getDataArray() {
|
||||
byte[] getDataArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setAddr(long addr) {
|
||||
void setAddr(long addr) {
|
||||
section.putLong(section_64.addr.off, addr);
|
||||
}
|
||||
|
||||
public long getAddr() {
|
||||
long getAddr() {
|
||||
return (section.getLong(section_64.addr.off));
|
||||
}
|
||||
|
||||
public void setOffset(int offset) {
|
||||
void setOffset(int offset) {
|
||||
section.putInt(section_64.offset.off, offset);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
int getOffset() {
|
||||
return (section.getInt(section_64.offset.off));
|
||||
}
|
||||
|
||||
public void setReloff(int offset) {
|
||||
void setReloff(int offset) {
|
||||
section.putInt(section_64.reloff.off, offset);
|
||||
}
|
||||
|
||||
public void setRelcount(int count) {
|
||||
void setRelcount(int count) {
|
||||
section.putInt(section_64.nreloc.off, count);
|
||||
}
|
||||
|
||||
public boolean hasRelocations() {
|
||||
boolean hasRelocations() {
|
||||
return hasrelocations;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,9 +24,7 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
@ -52,5 +50,3 @@ public class MachOSegment {
|
||||
return segment.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,17 +24,15 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.nlist_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachOSymbol extends NativeSymbol {
|
||||
ByteBuffer sym;
|
||||
final class MachOSymbol extends NativeSymbol {
|
||||
private final ByteBuffer sym;
|
||||
|
||||
public MachOSymbol(int symbolindex, int strindex, byte type, byte sectindex, long offset) {
|
||||
MachOSymbol(int symbolindex, int strindex, byte type, byte sectindex, long offset) {
|
||||
super(symbolindex);
|
||||
sym = MachOByteBuffer.allocate(nlist_64.totalsize);
|
||||
|
||||
@ -42,13 +40,12 @@ public class MachOSymbol extends NativeSymbol {
|
||||
sym.put(nlist_64.n_type.off, type);
|
||||
// Section indexes start at 1 but we manage the index internally
|
||||
// as 0 relative
|
||||
sym.put(nlist_64.n_sect.off, (byte)(sectindex+1));
|
||||
sym.putChar(nlist_64.n_desc.off, (char )0);
|
||||
sym.put(nlist_64.n_sect.off, (byte) (sectindex + 1));
|
||||
sym.putChar(nlist_64.n_desc.off, (char) 0);
|
||||
sym.putLong(nlist_64.n_value.off, offset);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return sym.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,50 +24,42 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.symtab_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.nlist_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOSymbol;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachOSymtab {
|
||||
final class MachOSymtab {
|
||||
|
||||
/**
|
||||
* ByteBuffer holding the LC_SYMTAB command contents
|
||||
*/
|
||||
ByteBuffer symtabCmd;
|
||||
private final ByteBuffer symtabCmd;
|
||||
|
||||
/**
|
||||
* ByteBuffer holding the symbol table entries and strings
|
||||
*/
|
||||
ByteBuffer symtabData;
|
||||
private int symtabDataSize;
|
||||
|
||||
int symtabDataSize;
|
||||
|
||||
ArrayList<MachOSymbol>localSymbols = new ArrayList<MachOSymbol>();
|
||||
ArrayList<MachOSymbol>globalSymbols = new ArrayList<MachOSymbol>();
|
||||
ArrayList<MachOSymbol>undefSymbols = new ArrayList<MachOSymbol>();
|
||||
private final ArrayList<MachOSymbol> localSymbols = new ArrayList<>();
|
||||
private final ArrayList<MachOSymbol> globalSymbols = new ArrayList<>();
|
||||
private final ArrayList<MachOSymbol> undefSymbols = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* number of symbols added
|
||||
*/
|
||||
int symbolCount;
|
||||
private int symbolCount;
|
||||
|
||||
/**
|
||||
* String holding symbol table strings
|
||||
*/
|
||||
private StringBuilder strTabContent = new StringBuilder();
|
||||
private final StringBuilder strTabContent = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Keeps track of bytes in string table since strTabContent.length()
|
||||
* is number of chars, not bytes.
|
||||
* Keeps track of bytes in string table since strTabContent.length() is number of chars, not bytes.
|
||||
*/
|
||||
private int strTabNrOfBytes = 0;
|
||||
|
||||
public MachOSymtab() {
|
||||
MachOSymtab() {
|
||||
symtabCmd = MachOByteBuffer.allocate(symtab_command.totalsize);
|
||||
|
||||
symtabCmd.putInt(symtab_command.cmd.off, symtab_command.LC_SYMTAB);
|
||||
@ -77,11 +69,11 @@ public class MachOSymtab {
|
||||
|
||||
}
|
||||
|
||||
public int getAlign() {
|
||||
static int getAlign() {
|
||||
return (4);
|
||||
}
|
||||
|
||||
public MachOSymbol addSymbolEntry(String name, byte type, byte secHdrIndex, long offset) {
|
||||
MachOSymbol addSymbolEntry(String name, byte type, byte secHdrIndex, long offset) {
|
||||
// Get the current symbol index and append symbol name to string table.
|
||||
int index;
|
||||
MachOSymbol sym;
|
||||
@ -109,7 +101,7 @@ public class MachOSymtab {
|
||||
case nlist_64.N_UNDF: // null symbol
|
||||
localSymbols.add(sym);
|
||||
break;
|
||||
case nlist_64.N_SECT|nlist_64.N_EXT:
|
||||
case nlist_64.N_SECT | nlist_64.N_EXT:
|
||||
globalSymbols.add(sym);
|
||||
break;
|
||||
default:
|
||||
@ -121,30 +113,30 @@ public class MachOSymtab {
|
||||
return (sym);
|
||||
}
|
||||
|
||||
public void setOffset(int symoff) {
|
||||
void setOffset(int symoff) {
|
||||
symtabCmd.putInt(symtab_command.symoff.off, symoff);
|
||||
}
|
||||
|
||||
// Update the symbol indexes once all symbols have been added.
|
||||
// This is required since we'll be reordering the symbols in the
|
||||
// file to be in the order of Local, global and Undefined.
|
||||
public void updateIndexes() {
|
||||
void updateIndexes() {
|
||||
int index = 0;
|
||||
|
||||
// Update the local symbol indexes
|
||||
for (int i = 0; i < localSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < localSymbols.size(); i++) {
|
||||
MachOSymbol sym = localSymbols.get(i);
|
||||
sym.setIndex(index++);
|
||||
}
|
||||
|
||||
// Update the global symbol indexes
|
||||
for (int i = 0; i < globalSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < globalSymbols.size(); i++) {
|
||||
MachOSymbol sym = globalSymbols.get(i);
|
||||
sym.setIndex(index++);
|
||||
}
|
||||
|
||||
// Update the undefined symbol indexes
|
||||
for (int i = index; i < undefSymbols.size(); i++ ) {
|
||||
for (int i = index; i < undefSymbols.size(); i++) {
|
||||
MachOSymbol sym = undefSymbols.get(i);
|
||||
sym.setIndex(index++);
|
||||
}
|
||||
@ -152,7 +144,7 @@ public class MachOSymtab {
|
||||
|
||||
// Update LC_SYMTAB command fields based on the number of symbols added
|
||||
// return the file size taken up by symbol table entries and strings
|
||||
public int calcSizes() {
|
||||
int calcSizes() {
|
||||
int stroff;
|
||||
|
||||
stroff = symtabCmd.getInt(symtab_command.symoff.off) + (nlist_64.totalsize * symbolCount);
|
||||
@ -164,42 +156,49 @@ public class MachOSymtab {
|
||||
return (symtabDataSize);
|
||||
}
|
||||
|
||||
public int getNumLocalSyms() { return localSymbols.size(); }
|
||||
public int getNumGlobalSyms() { return globalSymbols.size(); }
|
||||
public int getNumUndefSyms() { return undefSymbols.size(); }
|
||||
int getNumLocalSyms() {
|
||||
return localSymbols.size();
|
||||
}
|
||||
|
||||
public byte[] getCmdArray() {
|
||||
int getNumGlobalSyms() {
|
||||
return globalSymbols.size();
|
||||
}
|
||||
|
||||
int getNumUndefSyms() {
|
||||
return undefSymbols.size();
|
||||
}
|
||||
|
||||
byte[] getCmdArray() {
|
||||
return symtabCmd.array();
|
||||
}
|
||||
|
||||
// Create a single byte array that contains the symbol table entries
|
||||
// and string table
|
||||
public byte[] getDataArray() {
|
||||
int index = 0;
|
||||
symtabData = MachOByteBuffer.allocate(symtabDataSize);
|
||||
byte [] retarray;
|
||||
byte[] getDataArray() {
|
||||
ByteBuffer symtabData = MachOByteBuffer.allocate(symtabDataSize);
|
||||
byte[] retarray;
|
||||
|
||||
// Add the local symbols
|
||||
for (int i = 0; i < localSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < localSymbols.size(); i++) {
|
||||
MachOSymbol sym = localSymbols.get(i);
|
||||
byte [] arr = sym.getArray();
|
||||
byte[] arr = sym.getArray();
|
||||
symtabData.put(arr);
|
||||
}
|
||||
// Add the global symbols
|
||||
for (int i = 0; i < globalSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < globalSymbols.size(); i++) {
|
||||
MachOSymbol sym = globalSymbols.get(i);
|
||||
byte [] arr = sym.getArray();
|
||||
byte[] arr = sym.getArray();
|
||||
symtabData.put(arr);
|
||||
}
|
||||
// Add the undefined symbols
|
||||
for (int i = 0; i < undefSymbols.size(); i++ ) {
|
||||
for (int i = 0; i < undefSymbols.size(); i++) {
|
||||
MachOSymbol sym = undefSymbols.get(i);
|
||||
byte [] arr = sym.getArray();
|
||||
byte[] arr = sym.getArray();
|
||||
symtabData.put(arr);
|
||||
}
|
||||
|
||||
// Add the stringtable
|
||||
byte [] strs = strTabContent.toString().getBytes();
|
||||
byte[] strs = strTabContent.toString().getBytes();
|
||||
symtabData.put(strs);
|
||||
|
||||
retarray = symtabData.array();
|
||||
@ -207,5 +206,3 @@ public class MachOSymtab {
|
||||
return (retarray);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,14 +24,13 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64;
|
||||
|
||||
/**
|
||||
* Class that abstracts MACH-O target details.
|
||||
*
|
||||
*/
|
||||
public class MachOTargetInfo {
|
||||
final class MachOTargetInfo {
|
||||
/**
|
||||
* Target architecture and subtype.
|
||||
*/
|
||||
@ -68,20 +67,19 @@ public class MachOTargetInfo {
|
||||
osName = System.getProperty("os.name").toLowerCase();
|
||||
}
|
||||
|
||||
public static int getMachOArch() {
|
||||
static int getMachOArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public static int getMachOSubArch() {
|
||||
static int getMachOSubArch() {
|
||||
return subarch;
|
||||
}
|
||||
|
||||
public static int getMachOEndian() {
|
||||
static int getMachOEndian() {
|
||||
return endian;
|
||||
}
|
||||
|
||||
public static String getOsName() {
|
||||
static String getOsName() {
|
||||
return osName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,16 +24,14 @@
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.version_min_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachOVersion {
|
||||
ByteBuffer version;
|
||||
final class MachOVersion {
|
||||
private final ByteBuffer version;
|
||||
|
||||
public MachOVersion() {
|
||||
MachOVersion() {
|
||||
version = MachOByteBuffer.allocate(version_min_command.totalsize);
|
||||
|
||||
version.putInt(version_min_command.cmd.off, version_min_command.LC_VERSION_MIN_MACOSX);
|
||||
@ -42,8 +40,7 @@ public class MachOVersion {
|
||||
version.putInt(version_min_command.sdk.off, 0); /* N/A SDK */
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return version.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,13 +24,11 @@
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.tools.jaotc.binformat.Container;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.ByteContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
@ -38,11 +36,9 @@ import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
|
||||
import jdk.tools.jaotc.binformat.Relocation;
|
||||
import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffSymbol;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER;
|
||||
@ -56,71 +52,53 @@ public class JPECoffRelocObject {
|
||||
|
||||
private final PECoffContainer pecoffContainer;
|
||||
|
||||
private final int segmentSize;
|
||||
private final int sectionAlignment;
|
||||
|
||||
public JPECoffRelocObject(BinaryContainer binContainer, String outputFileName, String aotVersion) {
|
||||
public JPECoffRelocObject(BinaryContainer binContainer, String outputFileName) {
|
||||
this.binContainer = binContainer;
|
||||
this.pecoffContainer = new PECoffContainer(outputFileName, aotVersion);
|
||||
this.segmentSize = binContainer.getCodeSegmentSize();
|
||||
if (segmentSize != 64) {
|
||||
System.out.println("binContainer alignment size not 64 bytes, update JPECoffRelocObject");
|
||||
}
|
||||
this.pecoffContainer = new PECoffContainer(outputFileName);
|
||||
this.sectionAlignment = binContainer.getCodeSegmentSize();
|
||||
}
|
||||
|
||||
private PECoffSection createByteSection(ArrayList<PECoffSection>sections,
|
||||
String sectName,
|
||||
byte [] scnData,
|
||||
boolean hasRelocs,
|
||||
int scnFlags) {
|
||||
private static PECoffSection createByteSection(ArrayList<PECoffSection> sections, String sectName, byte[] scnData,
|
||||
boolean hasRelocs, int scnFlags, int sectAlign) {
|
||||
|
||||
PECoffSection sect = new PECoffSection(sectName,
|
||||
scnData,
|
||||
scnFlags,
|
||||
hasRelocs,
|
||||
sections.size());
|
||||
PECoffSection sect = new PECoffSection(sectName, scnData, scnFlags, sectAlign, hasRelocs, sections.size());
|
||||
// Add this section to our list
|
||||
sections.add(sect);
|
||||
|
||||
return (sect);
|
||||
}
|
||||
|
||||
private void createByteSection(ArrayList<PECoffSection>sections,
|
||||
ByteContainer c, int scnFlags) {
|
||||
private static void createByteSection(ArrayList<PECoffSection> sections, ByteContainer c, int scnFlags, int sectAlign) {
|
||||
PECoffSection sect;
|
||||
boolean hasRelocs = c.hasRelocations();
|
||||
byte[] scnData = c.getByteArray();
|
||||
|
||||
sect = createByteSection(sections, c.getContainerName(),
|
||||
scnData, hasRelocs,
|
||||
scnFlags);
|
||||
sect = createByteSection(sections, c.getContainerName(), scnData, hasRelocs, scnFlags, sectAlign);
|
||||
|
||||
c.setSectionId(sect.getSectionId());
|
||||
}
|
||||
|
||||
private void createCodeSection(ArrayList<PECoffSection>sections, CodeContainer c) {
|
||||
createByteSection(sections, c, IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_READ |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_EXECUTE |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_64BYTES |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_CNT_CODE);
|
||||
private void createCodeSection(ArrayList<PECoffSection> sections, CodeContainer c) {
|
||||
int scnFlags = IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_READ | IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_EXECUTE | IMAGE_SECTION_HEADER.IMAGE_SCN_CNT_CODE;
|
||||
createByteSection(sections, c, scnFlags, sectionAlignment);
|
||||
}
|
||||
|
||||
private void createReadOnlySection(ArrayList<PECoffSection>sections, ReadOnlyDataContainer c) {
|
||||
createByteSection(sections, c, IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_READ |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_64BYTES |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_CNT_INITIALIZED_DATA);
|
||||
private void createReadOnlySection(ArrayList<PECoffSection> sections, ReadOnlyDataContainer c) {
|
||||
int scnFlags = IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_READ | IMAGE_SECTION_HEADER.IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
createByteSection(sections, c, scnFlags, sectionAlignment);
|
||||
}
|
||||
|
||||
private void createReadWriteSection(ArrayList<PECoffSection>sections, ByteContainer c) {
|
||||
int scnFlags = IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_READ |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_WRITE |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_64BYTES;
|
||||
private void createReadWriteSection(ArrayList<PECoffSection> sections, ByteContainer c) {
|
||||
int scnFlags = IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_READ | IMAGE_SECTION_HEADER.IMAGE_SCN_MEM_WRITE;
|
||||
|
||||
if (c.getByteArray().length > 0)
|
||||
if (c.getByteArray().length > 0) {
|
||||
scnFlags |= IMAGE_SECTION_HEADER.IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
else
|
||||
} else {
|
||||
scnFlags |= IMAGE_SECTION_HEADER.IMAGE_SCN_CNT_UNINITIALIZED_DATA;
|
||||
|
||||
createByteSection(sections, c, scnFlags);
|
||||
}
|
||||
createByteSection(sections, c, scnFlags, sectionAlignment);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -131,7 +109,7 @@ public class JPECoffRelocObject {
|
||||
* @throws IOException throws {@code IOException} as a result of file system access failures.
|
||||
*/
|
||||
public void createPECoffRelocObject(Map<Symbol, List<Relocation>> relocationTable, Collection<Symbol> symbols) throws IOException {
|
||||
ArrayList<PECoffSection> sections = new ArrayList<PECoffSection>();
|
||||
ArrayList<PECoffSection> sections = new ArrayList<>();
|
||||
|
||||
// Create text section
|
||||
createCodeSection(sections, binContainer.getCodeContainer());
|
||||
@ -139,51 +117,45 @@ public class JPECoffRelocObject {
|
||||
createReadOnlySection(sections, binContainer.getKlassesOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getMethodsOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getKlassesDependenciesContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetaspaceGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodStateContainer());
|
||||
createReadWriteSection(sections, binContainer.getOopGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodMetadataContainer());
|
||||
createReadOnlySection(sections, binContainer.getMethodMetadataContainer());
|
||||
createReadOnlySection(sections, binContainer.getStubsOffsetsContainer());
|
||||
createReadOnlySection(sections, binContainer.getHeaderContainer().getContainer());
|
||||
createReadOnlySection(sections, binContainer.getCodeSegmentsContainer());
|
||||
createReadOnlySection(sections, binContainer.getConstantDataContainer());
|
||||
createReadOnlySection(sections, binContainer.getConfigContainer());
|
||||
|
||||
// createExternalLinkage();
|
||||
|
||||
createCodeSection(sections, binContainer.getExtLinkageContainer());
|
||||
createReadWriteSection(sections, binContainer.getKlassesGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getCountersGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMetadataGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getMethodStateContainer());
|
||||
createReadWriteSection(sections, binContainer.getOopGotContainer());
|
||||
createReadWriteSection(sections, binContainer.getExtLinkageGOTContainer());
|
||||
|
||||
// Allocate PECoff Header
|
||||
PECoffHeader header = new PECoffHeader();
|
||||
|
||||
// Get PECoff symbol data from BinaryContainer object's symbol tables
|
||||
PECoffSymtab symtab = createPECoffSymbolTables(sections, symbols);
|
||||
PECoffSymtab symtab = createPECoffSymbolTables(symbols);
|
||||
|
||||
// Add Linker Directives Section
|
||||
createByteSection(sections, ".drectve",
|
||||
symtab.getDirectiveArray(), false,
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_INFO |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_REMOVE |
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_1BYTES);
|
||||
int scnFlags = IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_INFO | IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_REMOVE;
|
||||
createByteSection(sections, ".drectve", symtab.getDirectiveArray(), false, scnFlags, 1 /* 1 byte alignment */);
|
||||
|
||||
// Create the Relocation Tables
|
||||
PECoffRelocTable pecoffRelocs = createPECoffRelocTable(sections, relocationTable);
|
||||
|
||||
// File Output Order
|
||||
//
|
||||
// HEADER (Need address of Symbol Table + symbol count)
|
||||
// SECTIONS (Need pointer to Section Data, Relocation Table)
|
||||
// DIRECTIVES
|
||||
// SYMBOL TABLE
|
||||
// SYMBOLS
|
||||
// SECTION DATA
|
||||
// RELOCATION TABLE
|
||||
// HEADER (Need address of Symbol Table + symbol count)
|
||||
// SECTIONS (Need pointer to Section Data, Relocation Table)
|
||||
// DIRECTIVES
|
||||
// SYMBOL TABLE
|
||||
// SYMBOLS
|
||||
// SECTION DATA
|
||||
// RELOCATION TABLE
|
||||
|
||||
// Calculate Offset for Symbol table
|
||||
int file_offset = IMAGE_FILE_HEADER.totalsize +
|
||||
(IMAGE_SECTION_HEADER.totalsize*sections.size());
|
||||
(IMAGE_SECTION_HEADER.totalsize * sections.size());
|
||||
|
||||
// Update Header fields
|
||||
header.setSectionCount(sections.size());
|
||||
@ -194,14 +166,14 @@ public class JPECoffRelocObject {
|
||||
file_offset += ((symtab.getSymtabCount() * IMAGE_SYMBOL.totalsize) +
|
||||
symtab.getStrtabSize());
|
||||
// And round it up
|
||||
file_offset = (file_offset + (sections.get(0).getDataAlign()-1)) &
|
||||
~((sections.get(0).getDataAlign()-1));
|
||||
file_offset = (file_offset + (sections.get(0).getDataAlign() - 1)) &
|
||||
~((sections.get(0).getDataAlign() - 1));
|
||||
|
||||
// Calc file offsets for section data
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
PECoffSection sect = sections.get(i);
|
||||
file_offset = (file_offset + (sect.getDataAlign()-1)) &
|
||||
~((sect.getDataAlign()-1));
|
||||
file_offset = (file_offset + (sect.getDataAlign() - 1)) &
|
||||
~((sect.getDataAlign() - 1));
|
||||
sect.setOffset(file_offset);
|
||||
file_offset += sect.getSize();
|
||||
}
|
||||
@ -214,7 +186,9 @@ public class JPECoffRelocObject {
|
||||
sect.setReloff(file_offset);
|
||||
sect.setRelcount(nreloc);
|
||||
// extended relocations add an addition entry
|
||||
if (nreloc > 0xFFFF) nreloc++;
|
||||
if (nreloc > 0xFFFF) {
|
||||
nreloc++;
|
||||
}
|
||||
file_offset += (nreloc * IMAGE_RELOCATION.totalsize);
|
||||
}
|
||||
}
|
||||
@ -253,7 +227,7 @@ public class JPECoffRelocObject {
|
||||
*
|
||||
* @param symbols
|
||||
*/
|
||||
private PECoffSymtab createPECoffSymbolTables(ArrayList<PECoffSection> sections, Collection<Symbol> symbols) {
|
||||
private static PECoffSymtab createPECoffSymbolTables(Collection<Symbol> symbols) {
|
||||
PECoffSymtab symtab = new PECoffSymtab();
|
||||
|
||||
// First, create the initial null symbol. This is a local symbol.
|
||||
@ -263,8 +237,8 @@ public class JPECoffRelocObject {
|
||||
for (Symbol symbol : symbols) {
|
||||
// Get the index of section this symbol is defined in.
|
||||
int secHdrIndex = symbol.getSection().getSectionId();
|
||||
PECoffSymbol pecoffSymbol = symtab.addSymbolEntry(symbol.getName(), getPECoffTypeOf(symbol), getPECoffClassOf(symbol), (byte)secHdrIndex, symbol.getOffset(), symbol.getSize());
|
||||
symbol.setNativeSymbol((NativeSymbol)pecoffSymbol);
|
||||
PECoffSymbol pecoffSymbol = symtab.addSymbolEntry(symbol.getName(), getPECoffTypeOf(symbol), getPECoffClassOf(symbol), (byte) secHdrIndex, symbol.getOffset());
|
||||
symbol.setNativeSymbol(pecoffSymbol);
|
||||
}
|
||||
return (symtab);
|
||||
}
|
||||
@ -291,13 +265,11 @@ public class JPECoffRelocObject {
|
||||
* @param sections
|
||||
* @param relocationTable
|
||||
*/
|
||||
private PECoffRelocTable createPECoffRelocTable(ArrayList<PECoffSection> sections,
|
||||
Map<Symbol, List<Relocation>> relocationTable) {
|
||||
private PECoffRelocTable createPECoffRelocTable(ArrayList<PECoffSection> sections, Map<Symbol, List<Relocation>> relocationTable) {
|
||||
|
||||
PECoffRelocTable pecoffRelocTable = new PECoffRelocTable(sections.size());
|
||||
/*
|
||||
* For each of the symbols with associated relocation records, create a PECoff relocation
|
||||
* entry.
|
||||
* For each of the symbols with associated relocation records, create a PECoff relocation entry.
|
||||
*/
|
||||
for (Map.Entry<Symbol, List<Relocation>> entry : relocationTable.entrySet()) {
|
||||
List<Relocation> relocs = entry.getValue();
|
||||
@ -315,18 +287,17 @@ public class JPECoffRelocObject {
|
||||
return (pecoffRelocTable);
|
||||
}
|
||||
|
||||
private void createRelocation(Symbol symbol, Relocation reloc, PECoffRelocTable pecoffRelocTable) {
|
||||
private static void createRelocation(Symbol symbol, Relocation reloc, PECoffRelocTable pecoffRelocTable) {
|
||||
RelocType relocType = reloc.getType();
|
||||
|
||||
int pecoffRelocType = getPECoffRelocationType(relocType);
|
||||
PECoffSymbol sym = (PECoffSymbol)symbol.getNativeSymbol();
|
||||
PECoffSymbol sym = (PECoffSymbol) symbol.getNativeSymbol();
|
||||
int symno = sym.getIndex();
|
||||
int sectindex = reloc.getSection().getSectionId();
|
||||
int offset = reloc.getOffset();
|
||||
int addend = 0;
|
||||
|
||||
switch (relocType) {
|
||||
case FOREIGN_CALL_DIRECT:
|
||||
case JAVA_CALL_DIRECT:
|
||||
case STUB_CALL_DIRECT:
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
@ -336,47 +307,22 @@ public class JPECoffRelocObject {
|
||||
offset = offset + reloc.getSize() + addend;
|
||||
break;
|
||||
}
|
||||
case FOREIGN_CALL_DIRECT_FAR: {
|
||||
// Create relocation entry
|
||||
addend = -8; // Size in bytes of the patch location
|
||||
// Relocation should be applied at the location after call operand
|
||||
// 10 = 2 (jmp [r]) + 8 (imm64)
|
||||
offset = offset + reloc.getSize() + addend - 2;
|
||||
break;
|
||||
}
|
||||
case FOREIGN_CALL_INDIRECT:
|
||||
case JAVA_CALL_INDIRECT:
|
||||
case STUB_CALL_INDIRECT: {
|
||||
case JAVA_CALL_INDIRECT: {
|
||||
// Do nothing.
|
||||
return;
|
||||
}
|
||||
case EXTERNAL_DATA_REFERENCE_FAR: {
|
||||
// Create relocation entry
|
||||
case METASPACE_GOT_REFERENCE:
|
||||
case EXTERNAL_PLT_TO_GOT: {
|
||||
addend = -4; // Size of 32-bit address of the GOT
|
||||
/*
|
||||
* Relocation should be applied before the test instruction to the move instruction.
|
||||
* offset points to the test instruction after the instruction that loads
|
||||
* the address of polling page. So set the offset appropriately.
|
||||
* reloc.getOffset() points to the test instruction after the instruction that loads the address of
|
||||
* polling page. So set the offset appropriately.
|
||||
*/
|
||||
offset = offset + addend;
|
||||
break;
|
||||
}
|
||||
case METASPACE_GOT_REFERENCE:
|
||||
case EXTERNAL_PLT_TO_GOT:
|
||||
case STATIC_STUB_TO_STATIC_METHOD:
|
||||
case STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT: {
|
||||
addend = -4; // Size of 32-bit address of the GOT
|
||||
/*
|
||||
* Relocation should be applied before the test instruction to
|
||||
* the move instruction. reloc.getOffset() points to the
|
||||
* test instruction after the instruction that loads the
|
||||
* address of polling page. So set the offset appropriately.
|
||||
*/
|
||||
offset = offset + addend;
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_GOT_TO_PLT:
|
||||
case LOADTIME_ADDRESS: {
|
||||
case EXTERNAL_GOT_TO_PLT: {
|
||||
// this is load time relocations
|
||||
break;
|
||||
}
|
||||
@ -391,27 +337,17 @@ public class JPECoffRelocObject {
|
||||
int pecoffRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
|
||||
switch (PECoffTargetInfo.getPECoffArch()) {
|
||||
case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64:
|
||||
if (relocType == RelocType.FOREIGN_CALL_DIRECT ||
|
||||
relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
if (relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32;
|
||||
} else if (relocType == RelocType.STUB_CALL_DIRECT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32;
|
||||
} else if (relocType == RelocType.FOREIGN_CALL_DIRECT_FAR) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ADDR64;
|
||||
} else if (relocType == RelocType.FOREIGN_CALL_INDIRECT ||
|
||||
relocType == RelocType.JAVA_CALL_INDIRECT ||
|
||||
relocType == RelocType.STUB_CALL_INDIRECT) {
|
||||
} else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ABSOLUTE;
|
||||
} else if ((relocType == RelocType.EXTERNAL_DATA_REFERENCE_FAR)) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT ||
|
||||
relocType == RelocType.STATIC_STUB_TO_STATIC_METHOD ||
|
||||
relocType == RelocType.STATIC_STUB_TO_HOTSPOT_LINKAGE_GOT) {
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT ||
|
||||
relocType == RelocType.LOADTIME_ADDRESS) {
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ADDR64;
|
||||
} else {
|
||||
assert false : "Unhandled relocation type: " + relocType;
|
||||
|
@ -25,17 +25,16 @@ package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for the creation of Coff files.
|
||||
* Current support is limited to 64 bit x86_64.
|
||||
* Support for the creation of Coff files. Current support is limited to 64 bit x86_64.
|
||||
*
|
||||
*/
|
||||
|
||||
public class PECoff {
|
||||
|
||||
final class PECoff {
|
||||
//@formatter:off
|
||||
/**
|
||||
* IMAGE_FILE_HEADER structure defines
|
||||
*/
|
||||
public enum IMAGE_FILE_HEADER {
|
||||
enum IMAGE_FILE_HEADER {
|
||||
Machine( 0, 2),
|
||||
NumberOfSections( 2, 2),
|
||||
TimeDateStamp( 4, 4),
|
||||
@ -44,15 +43,15 @@ public class PECoff {
|
||||
SizeOfOptionalHeader(16, 2),
|
||||
Characteristics(18, 2);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
IMAGE_FILE_HEADER(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 20;
|
||||
static int totalsize = 20;
|
||||
|
||||
/**
|
||||
* IMAGE_FILE_HEADER defines
|
||||
@ -61,15 +60,15 @@ public class PECoff {
|
||||
/**
|
||||
* Machine
|
||||
*/
|
||||
public static final char IMAGE_FILE_MACHINE_UNKNOWN = 0x0;
|
||||
public static final char IMAGE_FILE_MACHINE_AMD64 = 0x8664;
|
||||
static final char IMAGE_FILE_MACHINE_UNKNOWN = 0x0;
|
||||
static final char IMAGE_FILE_MACHINE_AMD64 = 0x8664;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* IMAGE_SECTION_HEADER structure defines
|
||||
*/
|
||||
public enum IMAGE_SECTION_HEADER {
|
||||
enum IMAGE_SECTION_HEADER {
|
||||
Name( 0, 8),
|
||||
PhysicalAddress( 8, 4),
|
||||
VirtualSize( 8, 4),
|
||||
@ -82,15 +81,15 @@ public class PECoff {
|
||||
NumberOfLinenumbers(34, 2),
|
||||
Characteristics(36, 4);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
IMAGE_SECTION_HEADER(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 40;
|
||||
static int totalsize = 40;
|
||||
|
||||
/**
|
||||
* IMAGE_SECTION_HEADER defines
|
||||
@ -99,29 +98,33 @@ public class PECoff {
|
||||
/**
|
||||
* Characteristics
|
||||
*/
|
||||
public static final int IMAGE_SCN_CNT_CODE = 0x20;
|
||||
public static final int IMAGE_SCN_CNT_INITIALIZED_DATA = 0x40;
|
||||
public static final int IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x80;
|
||||
public static final int IMAGE_SCN_LNK_COMDAT = 0x1000;
|
||||
public static final int IMAGE_SCN_LNK_INFO = 0x200;
|
||||
public static final int IMAGE_SCN_LNK_REMOVE = 0x800;
|
||||
static final int IMAGE_SCN_CNT_CODE = 0x20;
|
||||
static final int IMAGE_SCN_CNT_INITIALIZED_DATA = 0x40;
|
||||
static final int IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x80;
|
||||
static final int IMAGE_SCN_LNK_COMDAT = 0x1000;
|
||||
static final int IMAGE_SCN_LNK_INFO = 0x200;
|
||||
static final int IMAGE_SCN_LNK_REMOVE = 0x800;
|
||||
|
||||
public static final int IMAGE_SCN_ALIGN_1BYTES = 0x100000;
|
||||
public static final int IMAGE_SCN_ALIGN_2BYTES = 0x200000;
|
||||
public static final int IMAGE_SCN_ALIGN_4BYTES = 0x300000;
|
||||
public static final int IMAGE_SCN_ALIGN_8BYTES = 0x400000;
|
||||
public static final int IMAGE_SCN_ALIGN_16BYTES = 0x500000;
|
||||
public static final int IMAGE_SCN_ALIGN_32BYTES = 0x600000;
|
||||
public static final int IMAGE_SCN_ALIGN_64BYTES = 0x700000;
|
||||
public static final int IMAGE_SCN_ALIGN_MASK = 0xf00000;
|
||||
public static final int IMAGE_SCN_ALIGN_SHIFT = 20;
|
||||
static final int IMAGE_SCN_ALIGN_1BYTES = 0x100000;
|
||||
static final int IMAGE_SCN_ALIGN_2BYTES = 0x200000;
|
||||
static final int IMAGE_SCN_ALIGN_4BYTES = 0x300000;
|
||||
static final int IMAGE_SCN_ALIGN_8BYTES = 0x400000;
|
||||
static final int IMAGE_SCN_ALIGN_16BYTES = 0x500000;
|
||||
static final int IMAGE_SCN_ALIGN_32BYTES = 0x600000;
|
||||
static final int IMAGE_SCN_ALIGN_64BYTES = 0x700000;
|
||||
static final int IMAGE_SCN_ALIGN_128BYTES = 0x800000;
|
||||
static final int IMAGE_SCN_ALIGN_256BYTES = 0x900000;
|
||||
static final int IMAGE_SCN_ALIGN_512BYTES = 0xa00000;
|
||||
static final int IMAGE_SCN_ALIGN_1024BYTES = 0xb00000;
|
||||
static final int IMAGE_SCN_ALIGN_MASK = 0xf00000;
|
||||
static final int IMAGE_SCN_ALIGN_SHIFT = 20;
|
||||
|
||||
public static final int IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000;
|
||||
static final int IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000;
|
||||
|
||||
public static final int IMAGE_SCN_MEM_SHARED = 0x10000000;
|
||||
public static final int IMAGE_SCN_MEM_EXECUTE = 0x20000000;
|
||||
public static final int IMAGE_SCN_MEM_READ = 0x40000000;
|
||||
public static final int IMAGE_SCN_MEM_WRITE = 0x80000000;
|
||||
static final int IMAGE_SCN_MEM_SHARED = 0x10000000;
|
||||
static final int IMAGE_SCN_MEM_EXECUTE = 0x20000000;
|
||||
static final int IMAGE_SCN_MEM_READ = 0x40000000;
|
||||
static final int IMAGE_SCN_MEM_WRITE = 0x80000000;
|
||||
|
||||
}
|
||||
|
||||
@ -130,7 +133,7 @@ public class PECoff {
|
||||
*
|
||||
* IMAGE_SYMBOL structure defines
|
||||
*/
|
||||
public enum IMAGE_SYMBOL {
|
||||
enum IMAGE_SYMBOL {
|
||||
ShortName( 0, 8),
|
||||
Short( 0, 4),
|
||||
Long( 4, 4),
|
||||
@ -140,63 +143,63 @@ public class PECoff {
|
||||
StorageClass(16, 1),
|
||||
NumberOfAuxSymbols(17, 1);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
IMAGE_SYMBOL(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 18;
|
||||
static int totalsize = 18;
|
||||
|
||||
/**
|
||||
* Type
|
||||
*/
|
||||
public static final int IMAGE_SYM_DTYPE_NONE = 0x0;
|
||||
public static final int IMAGE_SYM_DTYPE_FUNCTION = 0x20;
|
||||
static final int IMAGE_SYM_DTYPE_NONE = 0x0;
|
||||
static final int IMAGE_SYM_DTYPE_FUNCTION = 0x20;
|
||||
|
||||
/**
|
||||
* StorageClass
|
||||
*/
|
||||
public static final int IMAGE_SYM_CLASS_NULL = 0x0;
|
||||
public static final int IMAGE_SYM_CLASS_EXTERNAL = 0x2;
|
||||
public static final int IMAGE_SYM_CLASS_STATIC = 0x3;
|
||||
public static final int IMAGE_SYM_CLASS_LABEL = 0x6;
|
||||
static final int IMAGE_SYM_CLASS_NULL = 0x0;
|
||||
static final int IMAGE_SYM_CLASS_EXTERNAL = 0x2;
|
||||
static final int IMAGE_SYM_CLASS_STATIC = 0x3;
|
||||
static final int IMAGE_SYM_CLASS_LABEL = 0x6;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* IMAGE_RELOCATION structure defines
|
||||
*/
|
||||
public enum IMAGE_RELOCATION {
|
||||
enum IMAGE_RELOCATION {
|
||||
VirtualAddress( 0, 4),
|
||||
SymbolTableIndex( 4, 4),
|
||||
Type( 8, 2);
|
||||
|
||||
public final int off;
|
||||
public final int sz;
|
||||
final int off;
|
||||
final int sz;
|
||||
|
||||
IMAGE_RELOCATION(int offset, int size) {
|
||||
this.off = offset;
|
||||
this.sz = size;
|
||||
}
|
||||
|
||||
public static int totalsize = 10;
|
||||
static int totalsize = 10;
|
||||
|
||||
/**
|
||||
* Relocation types
|
||||
*/
|
||||
public static final int IMAGE_REL_AMD64_ABSOLUTE = 0x0;
|
||||
public static final int IMAGE_REL_AMD64_ADDR32 = 0x2;
|
||||
public static final int IMAGE_REL_AMD64_ADDR64 = 0x1;
|
||||
public static final int IMAGE_REL_AMD64_REL32 = 0x4;
|
||||
public static final int IMAGE_REL_AMD64_REL32_1 = 0x5;
|
||||
public static final int IMAGE_REL_AMD64_REL32_2 = 0x6;
|
||||
public static final int IMAGE_REL_AMD64_REL32_3 = 0x7;
|
||||
public static final int IMAGE_REL_AMD64_REL32_4 = 0x8;
|
||||
public static final int IMAGE_REL_AMD64_REL32_5 = 0x9;
|
||||
static final int IMAGE_REL_AMD64_ABSOLUTE = 0x0;
|
||||
static final int IMAGE_REL_AMD64_ADDR32 = 0x2;
|
||||
static final int IMAGE_REL_AMD64_ADDR64 = 0x1;
|
||||
static final int IMAGE_REL_AMD64_REL32 = 0x4;
|
||||
static final int IMAGE_REL_AMD64_REL32_1 = 0x5;
|
||||
static final int IMAGE_REL_AMD64_REL32_2 = 0x6;
|
||||
static final int IMAGE_REL_AMD64_REL32_3 = 0x7;
|
||||
static final int IMAGE_REL_AMD64_REL32_4 = 0x8;
|
||||
static final int IMAGE_REL_AMD64_REL32_5 = 0x9;
|
||||
|
||||
}
|
||||
|
||||
//@formatter:on
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ package jdk.tools.jaotc.binformat.pecoff;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class PECoffByteBuffer {
|
||||
final class PECoffByteBuffer {
|
||||
|
||||
public static ByteBuffer allocate(int size) {
|
||||
static ByteBuffer allocate(int size) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(size);
|
||||
// Only support Little Endian on Windows
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
@ -26,14 +26,13 @@ package jdk.tools.jaotc.binformat.pecoff;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class PECoffContainer {
|
||||
final class PECoffContainer {
|
||||
|
||||
File outputFile;
|
||||
FileOutputStream outputStream;
|
||||
long fileOffset;
|
||||
private final File outputFile;
|
||||
private FileOutputStream outputStream;
|
||||
private long fileOffset;
|
||||
|
||||
public PECoffContainer(String fileName, String aotVersion) {
|
||||
String baseName;
|
||||
PECoffContainer(String fileName) {
|
||||
|
||||
outputFile = new File(fileName);
|
||||
if (outputFile.exists()) {
|
||||
@ -48,7 +47,7 @@ public class PECoffContainer {
|
||||
fileOffset = 0;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
void close() {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (Exception e) {
|
||||
@ -56,8 +55,10 @@ public class PECoffContainer {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBytes(byte [] bytes) {
|
||||
if (bytes == null) return;
|
||||
void writeBytes(byte[] bytes) {
|
||||
if (bytes == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
outputStream.write(bytes);
|
||||
} catch (Exception e) {
|
||||
@ -67,11 +68,13 @@ public class PECoffContainer {
|
||||
}
|
||||
|
||||
// Write bytes to output file with up front alignment padding
|
||||
public void writeBytes(byte [] bytes, int alignment) {
|
||||
if (bytes == null) return;
|
||||
void writeBytes(byte[] bytes, int alignment) {
|
||||
if (bytes == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// Pad to alignment
|
||||
while ((fileOffset & (long)(alignment-1)) != 0) {
|
||||
while ((fileOffset & (alignment - 1)) != 0) {
|
||||
outputStream.write(0);
|
||||
fileOffset++;
|
||||
}
|
||||
@ -82,4 +85,3 @@ public class PECoffContainer {
|
||||
fileOffset += bytes.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,45 +24,41 @@
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
public class PECoffHeader {
|
||||
ByteBuffer header;
|
||||
final class PECoffHeader {
|
||||
private final ByteBuffer header;
|
||||
|
||||
public PECoffHeader() {
|
||||
PECoffHeader() {
|
||||
header = PECoffByteBuffer.allocate(IMAGE_FILE_HEADER.totalsize);
|
||||
|
||||
header.putChar(IMAGE_FILE_HEADER.Machine.off, IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64);
|
||||
header.putInt(IMAGE_FILE_HEADER.TimeDateStamp.off, (int)(System.currentTimeMillis()/1000));
|
||||
header.putInt(IMAGE_FILE_HEADER.TimeDateStamp.off, (int) (System.currentTimeMillis() / 1000));
|
||||
header.putInt(IMAGE_FILE_HEADER.PointerToSymbolTable.off, 0);
|
||||
header.putInt(IMAGE_FILE_HEADER.NumberOfSymbols.off, 0);
|
||||
header.putChar(IMAGE_FILE_HEADER.SizeOfOptionalHeader.off, (char)0);
|
||||
header.putChar(IMAGE_FILE_HEADER.Characteristics.off, (char)0);
|
||||
header.putChar(IMAGE_FILE_HEADER.SizeOfOptionalHeader.off, (char) 0);
|
||||
header.putChar(IMAGE_FILE_HEADER.Characteristics.off, (char) 0);
|
||||
|
||||
}
|
||||
|
||||
// Update header with the number of total sections
|
||||
public void setSectionCount(int count) {
|
||||
header.putChar(IMAGE_FILE_HEADER.NumberOfSections.off, (char)count);
|
||||
void setSectionCount(int count) {
|
||||
header.putChar(IMAGE_FILE_HEADER.NumberOfSections.off, (char) count);
|
||||
}
|
||||
|
||||
// Update header with the number of total symbols
|
||||
public void setSymbolCount(int count) {
|
||||
void setSymbolCount(int count) {
|
||||
header.putInt(IMAGE_FILE_HEADER.NumberOfSymbols.off, count);
|
||||
}
|
||||
|
||||
// Update header with the offset of symbol table
|
||||
public void setSymbolOff(int offset) {
|
||||
void setSymbolOff(int offset) {
|
||||
header.putInt(IMAGE_FILE_HEADER.PointerToSymbolTable.off, offset);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return header.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,26 +24,23 @@
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
public class PECoffRelocEntry {
|
||||
ByteBuffer entry;
|
||||
final class PECoffRelocEntry {
|
||||
private final ByteBuffer entry;
|
||||
|
||||
public PECoffRelocEntry(int offset, int symno, int type) {
|
||||
PECoffRelocEntry(int offset, int symno, int type) {
|
||||
|
||||
entry = PECoffByteBuffer.allocate(IMAGE_RELOCATION.totalsize);
|
||||
|
||||
entry.putInt(IMAGE_RELOCATION.VirtualAddress.off, offset);
|
||||
entry.putInt(IMAGE_RELOCATION.SymbolTableIndex.off, symno);
|
||||
entry.putChar(IMAGE_RELOCATION.Type.off, (char)type);
|
||||
entry.putChar(IMAGE_RELOCATION.Type.off, (char) type);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return entry.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,52 +25,47 @@ package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffRelocEntry;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
public class PECoffRelocTable {
|
||||
final class PECoffRelocTable {
|
||||
ArrayList<ArrayList<PECoffRelocEntry>> relocEntries;
|
||||
|
||||
public PECoffRelocTable(int numsects) {
|
||||
relocEntries = new ArrayList<ArrayList<PECoffRelocEntry>>(numsects);
|
||||
for (int i = 0; i < numsects; i++)
|
||||
PECoffRelocTable(int numsects) {
|
||||
relocEntries = new ArrayList<>(numsects);
|
||||
for (int i = 0; i < numsects; i++) {
|
||||
relocEntries.add(new ArrayList<PECoffRelocEntry>());
|
||||
}
|
||||
}
|
||||
|
||||
public void createRelocationEntry(int sectindex,
|
||||
int offset,
|
||||
int symno,
|
||||
int type) {
|
||||
|
||||
PECoffRelocEntry entry = new PECoffRelocEntry(offset,
|
||||
symno,
|
||||
type);
|
||||
void createRelocationEntry(int sectindex, int offset, int symno, int type) {
|
||||
PECoffRelocEntry entry = new PECoffRelocEntry(offset, symno, type);
|
||||
relocEntries.get(sectindex).add(entry);
|
||||
}
|
||||
|
||||
public int getAlign() { return (4); }
|
||||
static int getAlign() {
|
||||
return (4);
|
||||
}
|
||||
|
||||
public int getNumRelocs(int section_index) {
|
||||
int getNumRelocs(int section_index) {
|
||||
return relocEntries.get(section_index).size();
|
||||
}
|
||||
|
||||
// Return the relocation entries for a single section
|
||||
// or null if no entries added to section
|
||||
public byte [] getRelocData(int section_index) {
|
||||
// or null if no entries added to section
|
||||
byte[] getRelocData(int section_index) {
|
||||
ArrayList<PECoffRelocEntry> entryList = relocEntries.get(section_index);
|
||||
int entryCount = entryList.size();
|
||||
int allocCount = entryCount;
|
||||
|
||||
if (entryCount == 0)
|
||||
if (entryCount == 0) {
|
||||
return null;
|
||||
|
||||
if (entryCount > 0xFFFF)
|
||||
}
|
||||
if (entryCount > 0xFFFF) {
|
||||
allocCount++;
|
||||
|
||||
}
|
||||
ByteBuffer relocData = PECoffByteBuffer.allocate(allocCount * IMAGE_RELOCATION.totalsize);
|
||||
|
||||
// If number of relocs exceeds 65K, add the real size
|
||||
@ -89,4 +84,3 @@ public class PECoffRelocTable {
|
||||
return (relocData.array());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,32 +24,39 @@
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
public class PECoffSection {
|
||||
ByteBuffer section;
|
||||
byte [] data;
|
||||
boolean hasrelocations;
|
||||
int sectionIndex;
|
||||
int align;
|
||||
final class PECoffSection {
|
||||
private final ByteBuffer section;
|
||||
private final byte[] data;
|
||||
private final boolean hasrelocations;
|
||||
private final int sectionIndex;
|
||||
private final int align;
|
||||
|
||||
public PECoffSection(String sectName, byte [] sectData, int sectFlags,
|
||||
boolean hasRelocations, int sectIndex) {
|
||||
PECoffSection(String sectName, byte[] sectData0, int sectFlags0, int sectAlign, boolean hasRelocations, int sectIndex) {
|
||||
|
||||
section = PECoffByteBuffer.allocate(IMAGE_SECTION_HEADER.totalsize);
|
||||
|
||||
// bug: If JVM.oop.got section is empty, VM exits since JVM.oop.got
|
||||
// symbol ends up as external forwarded reference.
|
||||
if (sectData.length == 0) sectData = new byte[8];
|
||||
// If .oop.got section is empty, VM exits since .oop.got
|
||||
// symbol ends up as external forwarded reference.
|
||||
byte[] sectData = sectData0;
|
||||
if (sectData0.length == 0) {
|
||||
sectData = new byte[8];
|
||||
}
|
||||
|
||||
// Copy only Max allowed bytes to Section Entry
|
||||
byte [] Name = sectName.getBytes();
|
||||
int max = Name.length <= IMAGE_SECTION_HEADER.Name.sz ?
|
||||
Name.length : IMAGE_SECTION_HEADER.Name.sz;
|
||||
byte[] Name = sectName.getBytes();
|
||||
int max = Name.length <= IMAGE_SECTION_HEADER.Name.sz ? Name.length : IMAGE_SECTION_HEADER.Name.sz;
|
||||
|
||||
assert !(sectAlign < 1 || sectAlign > 1024 || (sectAlign & (sectAlign - 1)) != 0) : "section alignment is not valid: " + sectAlign;
|
||||
align = sectAlign;
|
||||
|
||||
// Using 32 because IMAGE_SCN_ALIGN_*BYTES is value + 1
|
||||
int sectAlignBits = (32 - Integer.numberOfLeadingZeros(align)) << IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_SHIFT;
|
||||
// Clear and set alignment bits
|
||||
int sectFlags = (sectFlags0 & ~IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK) | (sectAlignBits & IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK);
|
||||
|
||||
section.put(Name, IMAGE_SECTION_HEADER.Name.off, max);
|
||||
|
||||
@ -57,84 +64,69 @@ public class PECoffSection {
|
||||
section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, 0);
|
||||
section.putInt(IMAGE_SECTION_HEADER.SizeOfRawData.off, sectData.length);
|
||||
section.putInt(IMAGE_SECTION_HEADER.PointerToLinenumbers.off, 0);
|
||||
section.putChar(IMAGE_SECTION_HEADER.NumberOfLinenumbers.off, (char)0);
|
||||
section.putChar(IMAGE_SECTION_HEADER.NumberOfLinenumbers.off, (char) 0);
|
||||
|
||||
section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, sectFlags);
|
||||
|
||||
// Extract alignment from Characteristics field
|
||||
int alignshift = (sectFlags & IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_MASK) >>
|
||||
IMAGE_SECTION_HEADER.IMAGE_SCN_ALIGN_SHIFT;
|
||||
|
||||
// Use 8 byte alignment if not specified
|
||||
if (alignshift == 0)
|
||||
alignshift = 3;
|
||||
else
|
||||
--alignshift;
|
||||
|
||||
align = 1 << alignshift;
|
||||
|
||||
data = sectData;
|
||||
hasrelocations = hasRelocations;
|
||||
sectionIndex = sectIndex;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
long getSize() {
|
||||
return section.getInt(IMAGE_SECTION_HEADER.SizeOfRawData.off);
|
||||
}
|
||||
|
||||
public int getDataAlign() {
|
||||
int getDataAlign() {
|
||||
return (align);
|
||||
}
|
||||
|
||||
// Alignment requirements for the IMAGE_SECTION_HEADER structures
|
||||
public static int getShdrAlign() {
|
||||
static int getShdrAlign() {
|
||||
return (4);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return section.array();
|
||||
}
|
||||
|
||||
public byte[] getDataArray() {
|
||||
byte[] getDataArray() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setOffset(long offset) {
|
||||
section.putInt(IMAGE_SECTION_HEADER.PointerToRawData.off, (int)offset);
|
||||
void setOffset(long offset) {
|
||||
section.putInt(IMAGE_SECTION_HEADER.PointerToRawData.off, (int) offset);
|
||||
}
|
||||
|
||||
public long getOffset() {
|
||||
long getOffset() {
|
||||
return (section.getInt(IMAGE_SECTION_HEADER.PointerToRawData.off));
|
||||
}
|
||||
|
||||
public void setReloff(int offset) {
|
||||
void setReloff(int offset) {
|
||||
section.putInt(IMAGE_SECTION_HEADER.PointerToRelocations.off, offset);
|
||||
}
|
||||
|
||||
public void setRelcount(int count) {
|
||||
void setRelcount(int count) {
|
||||
// If the number of relocs is larger than 65K, then set
|
||||
// the overflow bit. The real count will be written to
|
||||
// the overflow bit. The real count will be written to
|
||||
// the first reloc entry for this section.
|
||||
if (count > 0xFFFF) {
|
||||
int flags;
|
||||
section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char)0xFFFF);
|
||||
section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char) 0xFFFF);
|
||||
flags = section.getInt(IMAGE_SECTION_HEADER.Characteristics.off);
|
||||
flags |= IMAGE_SECTION_HEADER.IMAGE_SCN_LNK_NRELOC_OVFL;
|
||||
section.putInt(IMAGE_SECTION_HEADER.Characteristics.off, flags);
|
||||
}
|
||||
else {
|
||||
section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char)count);
|
||||
} else {
|
||||
section.putChar(IMAGE_SECTION_HEADER.NumberOfRelocations.off, (char) count);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasRelocations() {
|
||||
boolean hasRelocations() {
|
||||
return hasrelocations;
|
||||
}
|
||||
|
||||
public int getSectionId() {
|
||||
int getSectionId() {
|
||||
return sectionIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,18 +24,15 @@
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
public class PECoffSymbol extends NativeSymbol {
|
||||
ByteBuffer sym;
|
||||
final class PECoffSymbol extends NativeSymbol {
|
||||
private final ByteBuffer sym;
|
||||
|
||||
public PECoffSymbol(int symbolindex, int strindex, byte type, byte storageclass,
|
||||
byte sectindex, long offset, long size) {
|
||||
PECoffSymbol(int symbolindex, int strindex, byte type, byte storageclass, byte sectindex, long offset) {
|
||||
super(symbolindex);
|
||||
sym = PECoffByteBuffer.allocate(IMAGE_SYMBOL.totalsize);
|
||||
|
||||
@ -43,19 +40,18 @@ public class PECoffSymbol extends NativeSymbol {
|
||||
sym.putInt(IMAGE_SYMBOL.Short.off, 0);
|
||||
|
||||
sym.putInt(IMAGE_SYMBOL.Long.off, strindex);
|
||||
sym.putInt(IMAGE_SYMBOL.Value.off, (int)offset);
|
||||
sym.putInt(IMAGE_SYMBOL.Value.off, (int) offset);
|
||||
|
||||
// Section indexes start at 1 but we manage the index internally
|
||||
// as 0 relative except in this structure
|
||||
sym.putChar(IMAGE_SYMBOL.SectionNumber.off, (char)(sectindex+1));
|
||||
sym.putChar(IMAGE_SYMBOL.SectionNumber.off, (char) (sectindex + 1));
|
||||
|
||||
sym.putChar(IMAGE_SYMBOL.Type.off, (char)type);
|
||||
sym.putChar(IMAGE_SYMBOL.Type.off, (char) type);
|
||||
sym.put(IMAGE_SYMBOL.StorageClass.off, storageclass);
|
||||
sym.put(IMAGE_SYMBOL.NumberOfAuxSymbols.off, (byte)0);
|
||||
sym.put(IMAGE_SYMBOL.NumberOfAuxSymbols.off, (byte) 0);
|
||||
}
|
||||
|
||||
public byte[] getArray() {
|
||||
byte[] getArray() {
|
||||
return sym.array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,36 +27,35 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffSymbol;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
public class PECoffSymtab {
|
||||
ArrayList<PECoffSymbol>symbols = new ArrayList<PECoffSymbol>();
|
||||
final class PECoffSymtab {
|
||||
ArrayList<PECoffSymbol> symbols = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* number of symbols added
|
||||
*/
|
||||
int symbolCount;
|
||||
private int symbolCount;
|
||||
|
||||
/**
|
||||
* String holding symbol table strings
|
||||
*/
|
||||
private StringBuilder strTabContent;
|
||||
private final StringBuilder strTabContent;
|
||||
|
||||
/**
|
||||
* Keeps track of bytes in string table since strTabContent.length()
|
||||
* is number of chars, not bytes.
|
||||
* Keeps track of bytes in string table since strTabContent.length() is number of chars, not
|
||||
* bytes.
|
||||
*/
|
||||
private int strTabNrOfBytes;
|
||||
|
||||
/**
|
||||
* String holding Linker Directives
|
||||
*/
|
||||
private StringBuilder directives;
|
||||
private final StringBuilder directives;
|
||||
|
||||
public PECoffSymtab() {
|
||||
PECoffSymtab() {
|
||||
symbolCount = 0;
|
||||
strTabContent = new StringBuilder();
|
||||
directives = new StringBuilder();
|
||||
@ -72,8 +71,7 @@ public class PECoffSymtab {
|
||||
directives.append(" ");
|
||||
}
|
||||
|
||||
public PECoffSymbol addSymbolEntry(String name, byte type, byte storageclass,
|
||||
byte secHdrIndex, long offset, long size) {
|
||||
PECoffSymbol addSymbolEntry(String name, byte type, byte storageclass, byte secHdrIndex, long offset) {
|
||||
// Get the current symbol index and append symbol name to string table.
|
||||
int index;
|
||||
PECoffSymbol sym;
|
||||
@ -82,7 +80,7 @@ public class PECoffSymtab {
|
||||
index = 0;
|
||||
strTabContent.append('\0');
|
||||
strTabNrOfBytes += 1;
|
||||
sym = new PECoffSymbol(symbolCount, index, type, storageclass, secHdrIndex, offset, size);
|
||||
sym = new PECoffSymbol(symbolCount, index, type, storageclass, secHdrIndex, offset);
|
||||
symbols.add(sym);
|
||||
} else {
|
||||
int nameSize = name.getBytes().length;
|
||||
@ -94,10 +92,11 @@ public class PECoffSymtab {
|
||||
strTabContent.append(name).append('\0');
|
||||
strTabNrOfBytes += (nameSize + 1);
|
||||
|
||||
sym = new PECoffSymbol(symbolCount, index, type, storageclass, secHdrIndex, offset, size);
|
||||
sym = new PECoffSymbol(symbolCount, index, type, storageclass, secHdrIndex, offset);
|
||||
symbols.add(sym);
|
||||
if (storageclass == IMAGE_SYMBOL.IMAGE_SYM_CLASS_EXTERNAL)
|
||||
if (storageclass == IMAGE_SYMBOL.IMAGE_SYM_CLASS_EXTERNAL) {
|
||||
addDirective(name, type);
|
||||
}
|
||||
}
|
||||
symbolCount++;
|
||||
return (sym);
|
||||
@ -105,37 +104,37 @@ public class PECoffSymtab {
|
||||
|
||||
private void addDirective(String name, byte type) {
|
||||
directives.append("/EXPORT:" + name);
|
||||
if(type != IMAGE_SYMBOL.IMAGE_SYM_DTYPE_FUNCTION) {
|
||||
if (type != IMAGE_SYMBOL.IMAGE_SYM_DTYPE_FUNCTION) {
|
||||
directives.append(",DATA");
|
||||
}
|
||||
directives.append(" ");
|
||||
}
|
||||
|
||||
public int getSymtabCount() {
|
||||
int getSymtabCount() {
|
||||
return symbolCount;
|
||||
}
|
||||
|
||||
public int getStrtabSize() {
|
||||
int getStrtabSize() {
|
||||
return strTabNrOfBytes;
|
||||
}
|
||||
|
||||
// Return a byte array that contains the symbol table entries
|
||||
public byte[] getSymtabArray() {
|
||||
ByteBuffer symtabData = PECoffByteBuffer.allocate(symbolCount*IMAGE_SYMBOL.totalsize);
|
||||
byte[] getSymtabArray() {
|
||||
ByteBuffer symtabData = PECoffByteBuffer.allocate(symbolCount * IMAGE_SYMBOL.totalsize);
|
||||
symtabData.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// copy all symbols
|
||||
for (int i = 0; i < symbolCount; i++ ) {
|
||||
for (int i = 0; i < symbolCount; i++) {
|
||||
PECoffSymbol sym = symbols.get(i);
|
||||
byte [] arr = sym.getArray();
|
||||
byte[] arr = sym.getArray();
|
||||
symtabData.put(arr);
|
||||
}
|
||||
return (symtabData.array());
|
||||
}
|
||||
|
||||
// Return the string table array
|
||||
public byte[] getStrtabArray() {
|
||||
byte [] strs = strTabContent.toString().getBytes();
|
||||
byte[] getStrtabArray() {
|
||||
byte[] strs = strTabContent.toString().getBytes();
|
||||
|
||||
// Update the size of the string table
|
||||
ByteBuffer buff = ByteBuffer.wrap(strs);
|
||||
@ -145,7 +144,7 @@ public class PECoffSymtab {
|
||||
return (strs);
|
||||
}
|
||||
|
||||
public byte[] getDirectiveArray() {
|
||||
byte[] getDirectiveArray() {
|
||||
return (directives.toString().getBytes());
|
||||
}
|
||||
}
|
||||
|
@ -24,14 +24,13 @@
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER;
|
||||
|
||||
/**
|
||||
* Class that abstracts MACH-O target details.
|
||||
*
|
||||
*/
|
||||
public class PECoffTargetInfo {
|
||||
final class PECoffTargetInfo {
|
||||
/**
|
||||
* Target architecture.
|
||||
*/
|
||||
@ -63,12 +62,11 @@ public class PECoffTargetInfo {
|
||||
}
|
||||
}
|
||||
|
||||
public static char getPECoffArch() {
|
||||
static char getPECoffArch() {
|
||||
return arch;
|
||||
}
|
||||
|
||||
public static String getOsName() {
|
||||
static String getOsName() {
|
||||
return osName;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -52,7 +52,7 @@ import jdk.vm.ci.meta.ProfilingInfo;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.TriState;
|
||||
|
||||
public class AOTBackend {
|
||||
final class AOTBackend {
|
||||
private final Main main;
|
||||
private final OptionValues graalOptions;
|
||||
private final HotSpotBackend backend;
|
||||
@ -60,28 +60,26 @@ public class AOTBackend {
|
||||
private final HotSpotCodeCacheProvider codeCache;
|
||||
private final PhaseSuite<HighTierContext> graphBuilderSuite;
|
||||
private final HighTierContext highTierContext;
|
||||
private final GraalFilters filters;
|
||||
|
||||
public AOTBackend(Main main, OptionValues graalOptions, HotSpotBackend backend, GraalFilters filters) {
|
||||
AOTBackend(Main main, OptionValues graalOptions, HotSpotBackend backend) {
|
||||
this.main = main;
|
||||
this.graalOptions = graalOptions;
|
||||
this.backend = backend;
|
||||
this.filters = filters;
|
||||
providers = backend.getProviders();
|
||||
codeCache = providers.getCodeCache();
|
||||
graphBuilderSuite = initGraphBuilderSuite(backend, main.options.compileWithAssertions);
|
||||
highTierContext = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.ALL);
|
||||
}
|
||||
|
||||
public PhaseSuite<HighTierContext> getGraphBuilderSuite() {
|
||||
PhaseSuite<HighTierContext> getGraphBuilderSuite() {
|
||||
return graphBuilderSuite;
|
||||
}
|
||||
|
||||
public HotSpotBackend getBackend() {
|
||||
HotSpotBackend getBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
public HotSpotProviders getProviders() {
|
||||
HotSpotProviders getProviders() {
|
||||
return providers;
|
||||
}
|
||||
|
||||
@ -96,7 +94,7 @@ public class AOTBackend {
|
||||
}
|
||||
|
||||
@SuppressWarnings("try")
|
||||
public CompilationResult compileMethod(ResolvedJavaMethod resolvedMethod, DebugContext debug) {
|
||||
CompilationResult compileMethod(ResolvedJavaMethod resolvedMethod, DebugContext debug) {
|
||||
StructuredGraph graph = buildStructuredGraph(resolvedMethod, debug);
|
||||
if (graph != null) {
|
||||
return compileGraph(resolvedMethod, graph, debug);
|
||||
@ -118,7 +116,7 @@ public class AOTBackend {
|
||||
graphBuilderSuite.apply(graph, highTierContext);
|
||||
return graph;
|
||||
} catch (Throwable e) {
|
||||
handleError(javaMethod, e, " (building graph)");
|
||||
main.handleError(javaMethod, e, " (building graph)");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -135,20 +133,11 @@ public class AOTBackend {
|
||||
compilationResult, CompilationResultBuilderFactory.Default);
|
||||
|
||||
} catch (Throwable e) {
|
||||
handleError(resolvedMethod, e, " (compiling graph)");
|
||||
main.handleError(resolvedMethod, e, " (compiling graph)");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the VM is a debug build.
|
||||
*
|
||||
* @return true is debug VM, false otherwise
|
||||
*/
|
||||
public boolean isDebugVM() {
|
||||
return backend.getRuntime().getVMConfig().cAssertions;
|
||||
}
|
||||
|
||||
private static PhaseSuite<HighTierContext> initGraphBuilderSuite(HotSpotBackend backend, boolean compileWithAssertions) {
|
||||
PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy();
|
||||
ListIterator<BasePhase<? super HighTierContext>> iterator = graphBuilderSuite.findPhase(GraphBuilderPhase.class);
|
||||
@ -165,39 +154,12 @@ public class AOTBackend {
|
||||
return graphBuilderSuite;
|
||||
}
|
||||
|
||||
private void handleError(ResolvedJavaMethod resolvedMethod, Throwable e, String message) {
|
||||
String methodName = MiscUtils.uniqueMethodName(resolvedMethod);
|
||||
|
||||
if (main.options.debug) {
|
||||
main.printError("Failed compilation: " + methodName + ": " + e);
|
||||
}
|
||||
|
||||
// Ignore some exceptions when meta-compiling Graal.
|
||||
if (filters.shouldIgnoreException(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Main.writeLog("Failed compilation of method " + methodName + message);
|
||||
|
||||
if (!main.options.debug) {
|
||||
main.printError("Failed compilation: " + methodName + ": " + e);
|
||||
}
|
||||
|
||||
if (main.options.verbose) {
|
||||
e.printStackTrace(main.log);
|
||||
}
|
||||
|
||||
if (main.options.exitOnError) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void printCompiledMethod(HotSpotResolvedJavaMethod resolvedMethod, CompilationResult compResult) {
|
||||
void printCompiledMethod(HotSpotResolvedJavaMethod resolvedMethod, CompilationResult compResult) {
|
||||
// This is really not installing the method.
|
||||
InstalledCode installedCode = codeCache.addCode(resolvedMethod, HotSpotCompiledCodeBuilder.createCompiledCode(codeCache, null, null, compResult), null, null);
|
||||
String disassembly = codeCache.disassemble(installedCode);
|
||||
if (disassembly != null) {
|
||||
main.printlnDebug(disassembly);
|
||||
main.printer.printlnDebug(disassembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ import jdk.vm.ci.runtime.JVMCICompiler;
|
||||
* compilation of classes. It also defines methods that parse compilation result of Graal to create
|
||||
* target-independent representation {@code BinaryContainer} of the intended target binary.
|
||||
*/
|
||||
public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
|
||||
private static final AtomicInteger ids = new AtomicInteger();
|
||||
|
||||
@ -77,7 +77,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
*/
|
||||
private CompiledMethodInfo result;
|
||||
|
||||
public AOTCompilationTask(Main main, OptionValues graalOptions, AOTCompiledClass holder, ResolvedJavaMethod method, AOTBackend aotBackend) {
|
||||
AOTCompilationTask(Main main, OptionValues graalOptions, AOTCompiledClass holder, ResolvedJavaMethod method, AOTBackend aotBackend) {
|
||||
this.main = main;
|
||||
this.graalOptions = graalOptions;
|
||||
this.id = ids.incrementAndGet();
|
||||
@ -95,7 +95,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
// may include processing command line options used by the latter.
|
||||
HotSpotJVMCIRuntime.runtime();
|
||||
|
||||
AOTCompiler.logCompilation(MiscUtils.uniqueMethodName(method), "Compiling");
|
||||
AOTCompiler.logCompilation(JavaMethodInfo.uniqueMethodName(method), "Compiling");
|
||||
|
||||
final long threadId = Thread.currentThread().getId();
|
||||
|
||||
@ -137,7 +137,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
}
|
||||
|
||||
// For now precision to the nearest second is sufficient.
|
||||
Main.writeLog(" Compile Time: " + TimeUnit.MILLISECONDS.toSeconds(endTime - startTime) + "secs");
|
||||
LogPrinter.writeLog(" Compile Time: " + TimeUnit.MILLISECONDS.toSeconds(endTime - startTime) + "secs");
|
||||
if (main.options.debug) {
|
||||
aotBackend.printCompiledMethod((HotSpotResolvedJavaMethod) method, compResult);
|
||||
}
|
||||
@ -146,7 +146,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
}
|
||||
|
||||
private String getMethodDescription() {
|
||||
return String.format("%-6d aot %s %s", getId(), MiscUtils.uniqueMethodName(method),
|
||||
return String.format("%-6d aot %s %s", getId(), JavaMethodInfo.uniqueMethodName(method),
|
||||
getEntryBCI() == JVMCICompiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + getEntryBCI() + ") ");
|
||||
}
|
||||
|
||||
@ -154,11 +154,11 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getEntryBCI() {
|
||||
private static int getEntryBCI() {
|
||||
return JVMCICompiler.INVOCATION_ENTRY_BCI;
|
||||
}
|
||||
|
||||
public ResolvedJavaMethod getMethod() {
|
||||
ResolvedJavaMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
*
|
||||
* @return the holder of this method
|
||||
*/
|
||||
public AOTCompiledClass getHolder() {
|
||||
AOTCompiledClass getHolder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ public class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
*
|
||||
* @return result of this compilation task
|
||||
*/
|
||||
public CompiledMethodInfo getResult() {
|
||||
CompiledMethodInfo getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -41,16 +41,16 @@ import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
* Class encapsulating Graal-compiled output of a Java class. The compilation result of all methods
|
||||
* of a class {@code className} are maintained in an array list.
|
||||
*/
|
||||
public class AOTCompiledClass {
|
||||
final class AOTCompiledClass {
|
||||
|
||||
public static class AOTKlassData {
|
||||
int gotIndex; // Index (offset/8) to the got in the .metaspace.got section
|
||||
int classId; // Unique ID
|
||||
static class AOTKlassData {
|
||||
private int gotIndex; // Index (offset/8) to the got in the .metaspace.got section
|
||||
private int classId; // Unique ID
|
||||
// Offset to compiled methods data in the .methods.offsets section.
|
||||
int compiledMethodsOffset;
|
||||
private int compiledMethodsOffset;
|
||||
// Offset to dependent methods data.
|
||||
int dependentMethodsOffset;
|
||||
long fingerprint; // Class fingerprint
|
||||
private int dependentMethodsOffset;
|
||||
private long fingerprint; // Class fingerprint
|
||||
|
||||
private final String name;
|
||||
private boolean isArray;
|
||||
@ -60,25 +60,25 @@ public class AOTCompiledClass {
|
||||
*/
|
||||
private ArrayList<CompiledMethodInfo> dependentMethods;
|
||||
|
||||
public AOTKlassData(BinaryContainer binaryContainer, String name, long fingerprint, int classId) {
|
||||
AOTKlassData(BinaryContainer binaryContainer, String name, long fingerprint, int classId) {
|
||||
this.dependentMethods = new ArrayList<>();
|
||||
this.classId = classId;
|
||||
this.fingerprint = fingerprint;
|
||||
this.gotIndex = binaryContainer.addTwoSlotMetaspaceSymbol(name);
|
||||
this.gotIndex = binaryContainer.addTwoSlotKlassSymbol(name);
|
||||
this.compiledMethodsOffset = -1; // Not compiled classes do not have compiled methods.
|
||||
this.dependentMethodsOffset = -1;
|
||||
this.name = name;
|
||||
this.isArray = name.length() > 0 && name.charAt(0) == '[';
|
||||
}
|
||||
|
||||
public long getFingerprint() {
|
||||
long getFingerprint() {
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a method to the list of dependent methods.
|
||||
*/
|
||||
public synchronized boolean addDependentMethod(CompiledMethodInfo cm) {
|
||||
synchronized boolean addDependentMethod(CompiledMethodInfo cm) {
|
||||
return dependentMethods.add(cm);
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @return array list of dependent methods
|
||||
*/
|
||||
public ArrayList<CompiledMethodInfo> getDependentMethods() {
|
||||
ArrayList<CompiledMethodInfo> getDependentMethods() {
|
||||
return dependentMethods;
|
||||
}
|
||||
|
||||
@ -96,11 +96,11 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @return true if dependent methods exist, false otherwise
|
||||
*/
|
||||
public boolean hasDependentMethods() {
|
||||
boolean hasDependentMethods() {
|
||||
return !dependentMethods.isEmpty();
|
||||
}
|
||||
|
||||
public void setCompiledMethodsOffset(int offset) {
|
||||
void setCompiledMethodsOffset(int offset) {
|
||||
compiledMethodsOffset = offset;
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ public class AOTCompiledClass {
|
||||
int cntDepMethods = dependentMethods.size();
|
||||
// Create array of dependent methods IDs. First word is count.
|
||||
ReadOnlyDataContainer dependenciesContainer = binaryContainer.getKlassesDependenciesContainer();
|
||||
this.dependentMethodsOffset = binaryContainer.addMethodsCount(cntDepMethods, dependenciesContainer);
|
||||
this.dependentMethodsOffset = BinaryContainer.addMethodsCount(cntDepMethods, dependenciesContainer);
|
||||
for (CompiledMethodInfo methodInfo : dependentMethods) {
|
||||
dependenciesContainer.appendInt(methodInfo.getCodeId());
|
||||
}
|
||||
@ -176,7 +176,7 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @param compiledMethods AOT compiled methods
|
||||
*/
|
||||
public AOTCompiledClass(ArrayList<CompiledMethodInfo> compiledMethods) {
|
||||
AOTCompiledClass(ArrayList<CompiledMethodInfo> compiledMethods) {
|
||||
this.resolvedJavaType = null;
|
||||
this.compiledMethods = compiledMethods;
|
||||
this.representsStubs = true;
|
||||
@ -185,7 +185,7 @@ public class AOTCompiledClass {
|
||||
/**
|
||||
* Construct an object with compiled versions of the named class.
|
||||
*/
|
||||
public AOTCompiledClass(ResolvedJavaType resolvedJavaType) {
|
||||
AOTCompiledClass(ResolvedJavaType resolvedJavaType) {
|
||||
this.resolvedJavaType = (HotSpotResolvedObjectType) resolvedJavaType;
|
||||
this.compiledMethods = new ArrayList<>();
|
||||
this.representsStubs = false;
|
||||
@ -194,14 +194,14 @@ public class AOTCompiledClass {
|
||||
/**
|
||||
* @return the ResolvedJavaType of this class
|
||||
*/
|
||||
public ResolvedJavaType getResolvedJavaType() {
|
||||
ResolvedJavaType getResolvedJavaType() {
|
||||
return resolvedJavaType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of methods which should be compiled.
|
||||
*/
|
||||
public ArrayList<ResolvedJavaMethod> getMethods() {
|
||||
ArrayList<ResolvedJavaMethod> getMethods() {
|
||||
ArrayList<ResolvedJavaMethod> m = methods;
|
||||
methods = null; // Free - it is not used after that.
|
||||
return m;
|
||||
@ -210,7 +210,7 @@ public class AOTCompiledClass {
|
||||
/**
|
||||
* Get the number of all AOT classes.
|
||||
*/
|
||||
public static int getClassesCount() {
|
||||
static int getClassesCount() {
|
||||
return classesCount;
|
||||
}
|
||||
|
||||
@ -219,14 +219,14 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @return number of methods which should be compiled
|
||||
*/
|
||||
public int getMethodCount() {
|
||||
int getMethodCount() {
|
||||
return methods.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a method to the list of methods to be compiled.
|
||||
*/
|
||||
public void addMethod(ResolvedJavaMethod method) {
|
||||
void addMethod(ResolvedJavaMethod method) {
|
||||
methods.add(method);
|
||||
}
|
||||
|
||||
@ -235,14 +235,14 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @return true if this class contains methods which should be compiled, false otherwise
|
||||
*/
|
||||
public boolean hasMethods() {
|
||||
boolean hasMethods() {
|
||||
return !methods.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a method to the list of compiled methods. This method needs to be thread-safe.
|
||||
*/
|
||||
public synchronized boolean addCompiledMethod(CompiledMethodInfo cm) {
|
||||
synchronized boolean addCompiledMethod(CompiledMethodInfo cm) {
|
||||
return compiledMethods.add(cm);
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @return array list of compiled methods
|
||||
*/
|
||||
public ArrayList<CompiledMethodInfo> getCompiledMethods() {
|
||||
ArrayList<CompiledMethodInfo> getCompiledMethods() {
|
||||
return compiledMethods;
|
||||
}
|
||||
|
||||
@ -260,14 +260,14 @@ public class AOTCompiledClass {
|
||||
*
|
||||
* @return true if methods were compiled, false otherwise
|
||||
*/
|
||||
public boolean hasCompiledMethods() {
|
||||
boolean hasCompiledMethods() {
|
||||
return !compiledMethods.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a klass data.
|
||||
*/
|
||||
public synchronized static AOTKlassData addAOTKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
synchronized static AOTKlassData addAOTKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
String name = type.getName();
|
||||
long fingerprint = type.getFingerprint();
|
||||
AOTKlassData data = klassData.get(name);
|
||||
@ -280,15 +280,15 @@ public class AOTCompiledClass {
|
||||
return data;
|
||||
}
|
||||
|
||||
public synchronized static AOTKlassData getAOTKlassData(String name) {
|
||||
synchronized static AOTKlassData getAOTKlassData(String name) {
|
||||
return klassData.get(name);
|
||||
}
|
||||
|
||||
public synchronized static AOTKlassData getAOTKlassData(HotSpotResolvedObjectType type) {
|
||||
synchronized static AOTKlassData getAOTKlassData(HotSpotResolvedObjectType type) {
|
||||
return getAOTKlassData(type.getName());
|
||||
}
|
||||
|
||||
public void addAOTKlassData(BinaryContainer binaryContainer) {
|
||||
void addAOTKlassData(BinaryContainer binaryContainer) {
|
||||
for (CompiledMethodInfo methodInfo : compiledMethods) {
|
||||
// Record methods holder
|
||||
methodInfo.addDependentKlassData(binaryContainer, resolvedJavaType);
|
||||
@ -309,7 +309,7 @@ public class AOTCompiledClass {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static AOTKlassData addFingerprintKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
synchronized static AOTKlassData addFingerprintKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
if (type.isArray()) {
|
||||
return addAOTKlassData(binaryContainer, type);
|
||||
}
|
||||
@ -317,14 +317,15 @@ public class AOTCompiledClass {
|
||||
AOTKlassData old = getAOTKlassData(type);
|
||||
if (old != null) {
|
||||
boolean assertsEnabled = false;
|
||||
// Next assignment will be executed when asserts are enabled.
|
||||
assert assertsEnabled = true;
|
||||
if (assertsEnabled) {
|
||||
HotSpotResolvedObjectType s = type.getSuperclass();
|
||||
if (s != null) {
|
||||
assert getAOTKlassData(s) != null : "fingerprint super " + s.getName() + " needed for " + type.getName();
|
||||
assert getAOTKlassData(s) != null : "fingerprint for super " + s.getName() + " needed for " + type.getName();
|
||||
}
|
||||
for (HotSpotResolvedObjectType i : type.getInterfaces()) {
|
||||
assert getAOTKlassData(i) != null : "fingerprint super " + i.getName() + " needed for " + type.getName();
|
||||
assert getAOTKlassData(i) != null : "fingerprint for interface " + i.getName() + " needed for " + type.getName();
|
||||
}
|
||||
}
|
||||
return old;
|
||||
@ -345,10 +346,10 @@ public class AOTCompiledClass {
|
||||
/*
|
||||
* Put methods data to contained.
|
||||
*/
|
||||
public void putMethodsData(BinaryContainer binaryContainer) {
|
||||
void putMethodsData(BinaryContainer binaryContainer) {
|
||||
ReadOnlyDataContainer container = binaryContainer.getMethodsOffsetsContainer();
|
||||
int cntMethods = compiledMethods.size();
|
||||
int startMethods = binaryContainer.addMethodsCount(cntMethods, container);
|
||||
int startMethods = BinaryContainer.addMethodsCount(cntMethods, container);
|
||||
for (CompiledMethodInfo methodInfo : compiledMethods) {
|
||||
methodInfo.addMethodOffsets(binaryContainer, container);
|
||||
}
|
||||
@ -361,18 +362,18 @@ public class AOTCompiledClass {
|
||||
data.setCompiledMethodsOffset(startMethods);
|
||||
}
|
||||
|
||||
public static void putAOTKlassData(BinaryContainer binaryContainer) {
|
||||
static void putAOTKlassData(BinaryContainer binaryContainer) {
|
||||
ReadOnlyDataContainer container = binaryContainer.getKlassesOffsetsContainer();
|
||||
for (AOTKlassData data : klassData.values()) {
|
||||
data.putAOTKlassData(binaryContainer, container);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean representsStubs() {
|
||||
boolean representsStubs() {
|
||||
return representsStubs;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
void clear() {
|
||||
for (CompiledMethodInfo c : compiledMethods) {
|
||||
c.clear();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -35,7 +35,7 @@ import org.graalvm.compiler.options.OptionValues;
|
||||
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
public class AOTCompiler {
|
||||
final class AOTCompiler {
|
||||
|
||||
private final Main main;
|
||||
|
||||
@ -68,7 +68,7 @@ public class AOTCompiler {
|
||||
/**
|
||||
* Create a compile queue with the given number of threads.
|
||||
*/
|
||||
public CompileQueue(final int threads) {
|
||||
CompileQueue(final int threads) {
|
||||
super(threads, threads, 0L, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<>());
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
@ -79,7 +79,7 @@ public class AOTCompiler {
|
||||
if (task.getResult() != null) {
|
||||
final int count = successfulMethodCount.incrementAndGet();
|
||||
if (count % 100 == 0) {
|
||||
main.printInfo(".");
|
||||
main.printer.printInfo(".");
|
||||
}
|
||||
CompiledMethodInfo result = task.getResult();
|
||||
if (result != null) {
|
||||
@ -87,9 +87,9 @@ public class AOTCompiler {
|
||||
}
|
||||
} else {
|
||||
failedMethodCount.incrementAndGet();
|
||||
main.printlnVerbose("");
|
||||
main.printer.printlnVerbose("");
|
||||
ResolvedJavaMethod method = task.getMethod();
|
||||
main.printlnVerbose(" failed " + method.getName() + method.getSignature().toMethodDescriptor());
|
||||
main.printer.printlnVerbose(" failed " + method.getName() + method.getSignature().toMethodDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,8 +98,8 @@ public class AOTCompiler {
|
||||
final long endTime = System.currentTimeMillis();
|
||||
final int success = successfulMethodCount.get();
|
||||
final int failed = failedMethodCount.get();
|
||||
main.printlnInfo("");
|
||||
main.printlnInfo(success + " methods compiled, " + failed + " methods failed (" + (endTime - startTime) + " ms)");
|
||||
main.printer.printlnInfo("");
|
||||
main.printer.printlnInfo(success + " methods compiled, " + failed + " methods failed (" + (endTime - startTime) + " ms)");
|
||||
}
|
||||
|
||||
}
|
||||
@ -110,7 +110,7 @@ public class AOTCompiler {
|
||||
* @param aotBackend
|
||||
* @param threads number of compilation threads
|
||||
*/
|
||||
public AOTCompiler(Main main, OptionValues graalOptions, AOTBackend aotBackend, final int threads) {
|
||||
AOTCompiler(Main main, OptionValues graalOptions, AOTBackend aotBackend, final int threads) {
|
||||
this.main = main;
|
||||
this.graalOptions = graalOptions;
|
||||
this.compileQueue = new CompileQueue(threads);
|
||||
@ -123,9 +123,9 @@ public class AOTCompiler {
|
||||
* @param classes a list of class to compile
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public List<AOTCompiledClass> compileClasses(List<AOTCompiledClass> classes) throws InterruptedException {
|
||||
main.printlnInfo("Compiling with " + compileQueue.getCorePoolSize() + " threads");
|
||||
main.printInfo("."); // Compilation progress indication.
|
||||
List<AOTCompiledClass> compileClasses(List<AOTCompiledClass> classes) throws InterruptedException {
|
||||
main.printer.printlnInfo("Compiling with " + compileQueue.getCorePoolSize() + " threads");
|
||||
main.printer.printInfo("."); // Compilation progress indication.
|
||||
|
||||
for (AOTCompiledClass c : classes) {
|
||||
for (ResolvedJavaMethod m : c.getMethods()) {
|
||||
@ -160,8 +160,8 @@ public class AOTCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
public static void logCompilation(String methodName, String message) {
|
||||
Main.writeLog(message + " " + methodName);
|
||||
static void logCompilation(String methodName, String message) {
|
||||
LogPrinter.writeLog(message + " " + methodName);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -29,18 +29,18 @@ import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
||||
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
|
||||
public class AOTHotSpotResolvedJavaMethod implements JavaMethodInfo {
|
||||
final class AOTHotSpotResolvedJavaMethod implements JavaMethodInfo {
|
||||
|
||||
private final HotSpotResolvedJavaMethod method;
|
||||
private final Backend backend;
|
||||
|
||||
public AOTHotSpotResolvedJavaMethod(HotSpotResolvedJavaMethod method, Backend backend) {
|
||||
AOTHotSpotResolvedJavaMethod(HotSpotResolvedJavaMethod method, Backend backend) {
|
||||
this.method = method;
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
public String getSymbolName() {
|
||||
return MiscUtils.uniqueMethodName(method);
|
||||
return JavaMethodInfo.uniqueMethodName(method);
|
||||
}
|
||||
|
||||
public String getNameAndSignature() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -30,12 +30,12 @@ import org.graalvm.compiler.hotspot.stubs.Stub;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
||||
|
||||
public class AOTStub implements JavaMethodInfo {
|
||||
final class AOTStub implements JavaMethodInfo {
|
||||
|
||||
private final Stub stub;
|
||||
private final Backend backend;
|
||||
|
||||
public AOTStub(Stub stub, Backend backend) {
|
||||
AOTStub(Stub stub, Backend backend) {
|
||||
this.stub = stub;
|
||||
this.backend = backend;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -30,28 +30,16 @@ import jdk.vm.ci.code.site.Call;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
public class MiscUtils {
|
||||
final class CallInfo {
|
||||
|
||||
/**
|
||||
* Name a java method with class and signature to make it unique.
|
||||
*
|
||||
* @param method to generate unique identifier for
|
||||
* @return Unique name for this method including class and signature
|
||||
**/
|
||||
public static String uniqueMethodName(ResolvedJavaMethod method) {
|
||||
String className = method.getDeclaringClass().toClassName();
|
||||
String name = className + "." + method.getName() + method.getSignature().toMethodDescriptor();
|
||||
return name;
|
||||
}
|
||||
|
||||
public static boolean isStaticCall(Call call) {
|
||||
static boolean isStaticCall(Call call) {
|
||||
if (isJavaCall(call)) {
|
||||
return ((getByteCode(call) & 0xFF) == Bytecodes.INVOKESTATIC);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isSpecialCall(Call call) {
|
||||
static boolean isSpecialCall(Call call) {
|
||||
if (isJavaCall(call)) {
|
||||
return ((getByteCode(call) & 0xFF) == Bytecodes.INVOKESPECIAL);
|
||||
}
|
||||
@ -65,11 +53,11 @@ public class MiscUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isVirtualCall(CompiledMethodInfo methodInfo, Call call) {
|
||||
static boolean isVirtualCall(CompiledMethodInfo methodInfo, Call call) {
|
||||
return isInvokeVirtual(call) && !methodInfo.hasMark(call, MarkId.INVOKESPECIAL);
|
||||
}
|
||||
|
||||
public static boolean isOptVirtualCall(CompiledMethodInfo methodInfo, Call call) {
|
||||
static boolean isOptVirtualCall(CompiledMethodInfo methodInfo, Call call) {
|
||||
return isInvokeVirtual(call) && methodInfo.hasMark(call, MarkId.INVOKESPECIAL);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -31,10 +31,10 @@ import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
*/
|
||||
abstract class CallSiteRelocationInfo {
|
||||
|
||||
public final String targetSymbol;
|
||||
public final RelocType type;
|
||||
final String targetSymbol;
|
||||
final RelocType type;
|
||||
|
||||
public CallSiteRelocationInfo(String targetSymbol, RelocType type) {
|
||||
CallSiteRelocationInfo(String targetSymbol, RelocType type) {
|
||||
this.targetSymbol = targetSymbol;
|
||||
this.type = type;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -37,9 +37,9 @@ import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
*/
|
||||
abstract class CallSiteRelocationSymbol {
|
||||
|
||||
public final Symbol symbol;
|
||||
final Symbol symbol;
|
||||
|
||||
public CallSiteRelocationSymbol(Symbol symbol) {
|
||||
CallSiteRelocationSymbol(Symbol symbol) {
|
||||
assert symbol != null;
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -27,7 +27,7 @@ import java.util.List;
|
||||
|
||||
import jdk.vm.ci.code.site.Mark;
|
||||
|
||||
public final class CodeOffsets {
|
||||
final class CodeOffsets {
|
||||
private final int entry;
|
||||
private final int verifiedEntry;
|
||||
private final int exceptionHandler;
|
||||
@ -40,7 +40,7 @@ public final class CodeOffsets {
|
||||
this.deoptHandler = deoptHandler;
|
||||
}
|
||||
|
||||
public static CodeOffsets buildFrom(List<Mark> marks) {
|
||||
static CodeOffsets buildFrom(List<Mark> marks) {
|
||||
int entry = 0;
|
||||
int verifiedEntry = 0;
|
||||
int exceptionHandler = -1;
|
||||
@ -73,19 +73,19 @@ public final class CodeOffsets {
|
||||
return new CodeOffsets(entry, verifiedEntry, exceptionHandler, deoptHandler);
|
||||
}
|
||||
|
||||
public int entry() {
|
||||
int entry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public int verifiedEntry() {
|
||||
int verifiedEntry() {
|
||||
return verifiedEntry;
|
||||
}
|
||||
|
||||
public int exceptionHandler() {
|
||||
int exceptionHandler() {
|
||||
return exceptionHandler;
|
||||
}
|
||||
|
||||
public int deoptHandler() {
|
||||
int deoptHandler() {
|
||||
return deoptHandler;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -28,7 +28,7 @@ import java.util.ArrayList;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.CompiledMethodInfo.StubInformation;
|
||||
import jdk.tools.jaotc.StubInformation;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
|
||||
|
||||
@ -38,7 +38,7 @@ import jdk.vm.ci.code.site.Infopoint;
|
||||
import jdk.vm.ci.code.site.InfopointReason;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
||||
class CodeSectionProcessor {
|
||||
final class CodeSectionProcessor {
|
||||
|
||||
private final TargetDescription target;
|
||||
|
||||
@ -89,11 +89,11 @@ class CodeSectionProcessor {
|
||||
|
||||
// Align and pad method entry
|
||||
CodeContainer codeSection = binaryContainer.getCodeContainer();
|
||||
int codeIdOffset = binaryContainer.alignUp(codeSection, binaryContainer.getCodeSegmentSize());
|
||||
int codeIdOffset = BinaryContainer.alignUp(codeSection, binaryContainer.getCodeSegmentSize());
|
||||
// Store CodeId into code. It will be use by find_aot() using code.segments
|
||||
methodInfo.setCodeId();
|
||||
binaryContainer.appendIntToCode(methodInfo.getCodeId());
|
||||
int textBaseOffset = binaryContainer.alignUp(codeSection, binaryContainer.getCodeEntryAlignment());
|
||||
int textBaseOffset = BinaryContainer.alignUp(codeSection, binaryContainer.getCodeEntryAlignment());
|
||||
|
||||
codeSection.createSymbol(textBaseOffset, Symbol.Kind.JAVA_FUNCTION, Symbol.Binding.LOCAL, targetCodeSize, entry);
|
||||
|
||||
@ -102,7 +102,7 @@ class CodeSectionProcessor {
|
||||
|
||||
// Write code bytes of the current method into byte stream
|
||||
binaryContainer.appendCodeBytes(targetCode, 0, targetCodeSize);
|
||||
int currentStubOffset = binaryContainer.alignUp(codeSection, 8);
|
||||
int currentStubOffset = BinaryContainer.alignUp(codeSection, 8);
|
||||
// Set the offset at which stubs of this method would be laid out
|
||||
methodInfo.setStubsOffset(currentStubOffset - textBaseOffset);
|
||||
// step through all calls, for every call, add a stub
|
||||
@ -111,10 +111,10 @@ class CodeSectionProcessor {
|
||||
final Call callInfopoint = (Call) infopoint;
|
||||
if (callInfopoint.target instanceof ResolvedJavaMethod) {
|
||||
ResolvedJavaMethod call = (ResolvedJavaMethod) callInfopoint.target;
|
||||
StubInformation stub = addCallStub(MiscUtils.isVirtualCall(methodInfo, callInfopoint));
|
||||
StubInformation stub = addCallStub(CallInfo.isVirtualCall(methodInfo, callInfopoint));
|
||||
// Get the targetSymbol. A symbol for this will be created later during plt
|
||||
// creation
|
||||
String targetSymbol = MiscUtils.uniqueMethodName(call) + ".at." + infopoint.pcOffset;
|
||||
String targetSymbol = JavaMethodInfo.uniqueMethodName(call) + ".at." + infopoint.pcOffset;
|
||||
methodInfo.addStubCode(targetSymbol, stub);
|
||||
currentStubOffset += stub.getSize();
|
||||
}
|
||||
|
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.tools.jaotc.collect.ClassSearch;
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
import jdk.tools.jaotc.collect.classname.ClassNameSourceProvider;
|
||||
import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
|
||||
import jdk.tools.jaotc.collect.jar.JarSourceProvider;
|
||||
import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
|
||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
|
||||
final class Collector {
|
||||
|
||||
private final Main main;
|
||||
|
||||
Collector(Main main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
Set<Class<?>> collectClassesToCompile() {
|
||||
Set<Class<?>> classesToCompile = new HashSet<>();
|
||||
FileSupport fileSupport = new FileSupport();
|
||||
ClassSearch lookup = new ClassSearch();
|
||||
lookup.addProvider(new ModuleSourceProvider());
|
||||
lookup.addProvider(new ClassNameSourceProvider(fileSupport));
|
||||
lookup.addProvider(new JarSourceProvider());
|
||||
lookup.addProvider(new DirectorySourceProvider(fileSupport));
|
||||
|
||||
List<LoadedClass> foundClasses = null;
|
||||
try {
|
||||
foundClasses = lookup.search(main.options.files, main.options.searchPath);
|
||||
} catch (InternalError e) {
|
||||
main.printer.reportError(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
for (LoadedClass loadedClass : foundClasses) {
|
||||
classesToCompile.add(loadedClass.getLoadedClass());
|
||||
}
|
||||
return classesToCompile;
|
||||
}
|
||||
|
||||
private void addMethods(AOTCompiledClass aotClass, ResolvedJavaMethod[] methods, CompilationSpec compilationRestrictions) {
|
||||
for (ResolvedJavaMethod m : methods) {
|
||||
addMethod(aotClass, m, compilationRestrictions);
|
||||
}
|
||||
}
|
||||
|
||||
private void addMethod(AOTCompiledClass aotClass, ResolvedJavaMethod method, CompilationSpec compilationRestrictions) {
|
||||
// Don't compile native or abstract methods.
|
||||
if (!method.hasBytecodes()) {
|
||||
return;
|
||||
}
|
||||
if (!compilationRestrictions.shouldCompileMethod(method)) {
|
||||
return;
|
||||
}
|
||||
if (!main.filters.shouldCompileMethod(method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aotClass.addMethod(method);
|
||||
main.printer.printlnVerbose(" added " + method.getName() + method.getSignature().toMethodDescriptor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all method we should compile.
|
||||
*
|
||||
* @return array list of AOT classes which have compiled methods.
|
||||
*/
|
||||
List<AOTCompiledClass> collectMethodsToCompile(Set<Class<?>> classesToCompile, MetaAccessProvider metaAccess) {
|
||||
int total = 0;
|
||||
int count = 0;
|
||||
List<AOTCompiledClass> classes = new ArrayList<>();
|
||||
CompilationSpec compilationRestrictions = collectSpecifiedMethods();
|
||||
|
||||
for (Class<?> c : classesToCompile) {
|
||||
ResolvedJavaType resolvedJavaType = metaAccess.lookupJavaType(c);
|
||||
if (main.filters.shouldCompileAnyMethodInClass(resolvedJavaType)) {
|
||||
AOTCompiledClass aotClass = new AOTCompiledClass(resolvedJavaType);
|
||||
main.printer.printlnVerbose(" Scanning " + c.getName());
|
||||
|
||||
// Constructors
|
||||
try {
|
||||
ResolvedJavaMethod[] ctors = resolvedJavaType.getDeclaredConstructors();
|
||||
addMethods(aotClass, ctors, compilationRestrictions);
|
||||
total += ctors.length;
|
||||
} catch (Throwable e) {
|
||||
// If we are running in JCK mode we ignore all exceptions.
|
||||
if (main.options.ignoreClassLoadingErrors) {
|
||||
main.printer.printError(c.getName() + ": " + e);
|
||||
} else {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Methods
|
||||
try {
|
||||
ResolvedJavaMethod[] methods = resolvedJavaType.getDeclaredMethods();
|
||||
addMethods(aotClass, methods, compilationRestrictions);
|
||||
total += methods.length;
|
||||
} catch (Throwable e) {
|
||||
// If we are running in JCK mode we ignore all exceptions.
|
||||
if (main.options.ignoreClassLoadingErrors) {
|
||||
main.printer.printError(c.getName() + ": " + e);
|
||||
} else {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Class initializer
|
||||
try {
|
||||
ResolvedJavaMethod clinit = resolvedJavaType.getClassInitializer();
|
||||
if (clinit != null) {
|
||||
addMethod(aotClass, clinit, compilationRestrictions);
|
||||
total++;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
// If we are running in JCK mode we ignore all exceptions.
|
||||
if (main.options.ignoreClassLoadingErrors) {
|
||||
main.printer.printError(c.getName() + ": " + e);
|
||||
} else {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Found any methods to compile? Add the class.
|
||||
if (aotClass.hasMethods()) {
|
||||
classes.add(aotClass);
|
||||
count += aotClass.getMethodCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
main.printer.printInfo(total + " methods total, " + count + " methods to compile");
|
||||
return classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a file with compilation limitations is specified using flag --compile-commands, read the
|
||||
* file's contents and collect the restrictions.
|
||||
*/
|
||||
private CompilationSpec collectSpecifiedMethods() {
|
||||
CompilationSpec compilationRestrictions = new CompilationSpec();
|
||||
String methodListFileName = main.options.methodList;
|
||||
|
||||
if (methodListFileName != null && !methodListFileName.equals("")) {
|
||||
try {
|
||||
FileReader methListFile = new FileReader(methodListFileName);
|
||||
BufferedReader readBuf = new BufferedReader(methListFile);
|
||||
String line = null;
|
||||
while ((line = readBuf.readLine()) != null) {
|
||||
String trimmedLine = line.trim();
|
||||
if (!trimmedLine.startsWith("#")) {
|
||||
String[] components = trimmedLine.split(" ");
|
||||
if (components.length == 2) {
|
||||
String directive = components[0];
|
||||
String pattern = components[1];
|
||||
switch (directive) {
|
||||
case "compileOnly":
|
||||
compilationRestrictions.addCompileOnlyPattern(pattern);
|
||||
break;
|
||||
case "exclude":
|
||||
compilationRestrictions.addExcludePattern(pattern);
|
||||
break;
|
||||
default:
|
||||
System.out.println("Unrecognized command " + directive + ". Ignoring\n\t" + line + "\n encountered in " + methodListFileName);
|
||||
}
|
||||
} else {
|
||||
if (!trimmedLine.equals("")) {
|
||||
System.out.println("Ignoring malformed line:\n\t " + line + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
readBuf.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new InternalError("Unable to open method list file: " + methodListFileName, e);
|
||||
} catch (IOException e) {
|
||||
throw new InternalError("Unable to read method list file: " + methodListFileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
return compilationRestrictions;
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -32,7 +32,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
/**
|
||||
* A class encapsulating any user-specified compilation restrictions.
|
||||
*/
|
||||
public class CompilationSpec {
|
||||
final class CompilationSpec {
|
||||
|
||||
/**
|
||||
* Set of method names to restrict compilation to.
|
||||
@ -51,7 +51,7 @@ public class CompilationSpec {
|
||||
*
|
||||
* @param pattern regex or non-regex pattern string
|
||||
*/
|
||||
public void addCompileOnlyPattern(String pattern) {
|
||||
void addCompileOnlyPattern(String pattern) {
|
||||
if (pattern.contains("*")) {
|
||||
compileOnlyPatterns.add(Pattern.compile(pattern));
|
||||
} else {
|
||||
@ -64,7 +64,7 @@ public class CompilationSpec {
|
||||
*
|
||||
* @param pattern regex or non-regex pattern string
|
||||
*/
|
||||
public void addExcludePattern(String pattern) {
|
||||
void addExcludePattern(String pattern) {
|
||||
if (pattern.contains("*")) {
|
||||
excludePatterns.add(Pattern.compile(pattern));
|
||||
} else {
|
||||
@ -78,14 +78,14 @@ public class CompilationSpec {
|
||||
* @param method method to be checked
|
||||
* @return true or false
|
||||
*/
|
||||
public boolean shouldCompileMethod(ResolvedJavaMethod method) {
|
||||
boolean shouldCompileMethod(ResolvedJavaMethod method) {
|
||||
if (compileWithRestrictions()) {
|
||||
// If there are user-specified compileOnly patterns, default action
|
||||
// is not to compile the method.
|
||||
boolean compileMethod = compileOnlyStrings.isEmpty() && compileOnlyPatterns.isEmpty();
|
||||
|
||||
// Check if the method matches with any of the specified compileOnly patterns.
|
||||
String methodName = MiscUtils.uniqueMethodName(method);
|
||||
String methodName = JavaMethodInfo.uniqueMethodName(method);
|
||||
|
||||
// compileOnly
|
||||
if (!compileMethod) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -37,104 +37,7 @@ import jdk.vm.ci.code.site.Site;
|
||||
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
|
||||
public class CompiledMethodInfo {
|
||||
|
||||
public static class StubInformation {
|
||||
int stubOffset; // the offset inside the code (text + stubOffset)
|
||||
int stubSize; // the stub size
|
||||
int dispatchJumpOffset; // offset after main dispatch jump instruction
|
||||
int resolveJumpOffset; // offset after jump instruction to runtime call resolution
|
||||
// function.
|
||||
int resolveJumpStart; // offset of jump instruction to VM runtime call resolution
|
||||
// function.
|
||||
int c2iJumpOffset; // offset after jump instruction to c2i adapter for static calls.
|
||||
int movOffset; // offset after move instruction which loads from got cell:
|
||||
// - Method* for static call
|
||||
// - Klass* for virtual call
|
||||
|
||||
boolean isVirtual; // virtual call stub
|
||||
|
||||
// maybe add type of stub as well, right now we only have static stubs
|
||||
|
||||
public StubInformation(int stubOffset, boolean isVirtual) {
|
||||
this.stubOffset = stubOffset;
|
||||
this.isVirtual = isVirtual;
|
||||
this.stubSize = -1;
|
||||
this.movOffset = -1;
|
||||
this.c2iJumpOffset = -1;
|
||||
this.resolveJumpOffset = -1;
|
||||
this.resolveJumpStart = -1;
|
||||
this.dispatchJumpOffset = -1;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return stubOffset;
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return isVirtual;
|
||||
}
|
||||
|
||||
public void setSize(int stubSize) {
|
||||
this.stubSize = stubSize;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return stubSize;
|
||||
}
|
||||
|
||||
public void setMovOffset(int movOffset) {
|
||||
this.movOffset = movOffset + stubOffset;
|
||||
}
|
||||
|
||||
public int getMovOffset() {
|
||||
return movOffset;
|
||||
}
|
||||
|
||||
public void setC2IJumpOffset(int c2iJumpOffset) {
|
||||
this.c2iJumpOffset = c2iJumpOffset + stubOffset;
|
||||
}
|
||||
|
||||
public int getC2IJumpOffset() {
|
||||
return c2iJumpOffset;
|
||||
}
|
||||
|
||||
public void setResolveJumpOffset(int resolveJumpOffset) {
|
||||
this.resolveJumpOffset = resolveJumpOffset + stubOffset;
|
||||
}
|
||||
|
||||
public int getResolveJumpOffset() {
|
||||
return resolveJumpOffset;
|
||||
}
|
||||
|
||||
public void setResolveJumpStart(int resolveJumpStart) {
|
||||
this.resolveJumpStart = resolveJumpStart + stubOffset;
|
||||
}
|
||||
|
||||
public int getResolveJumpStart() {
|
||||
return resolveJumpStart;
|
||||
}
|
||||
|
||||
public void setDispatchJumpOffset(int dispatchJumpOffset) {
|
||||
this.dispatchJumpOffset = dispatchJumpOffset + stubOffset;
|
||||
}
|
||||
|
||||
public int getDispatchJumpOffset() {
|
||||
return dispatchJumpOffset;
|
||||
}
|
||||
|
||||
public void verify() {
|
||||
assert stubOffset > 0 : "incorrect stubOffset: " + stubOffset;
|
||||
assert stubSize > 0 : "incorrect stubSize: " + stubSize;
|
||||
assert movOffset > 0 : "incorrect movOffset: " + movOffset;
|
||||
assert dispatchJumpOffset > 0 : "incorrect dispatchJumpOffset: " + dispatchJumpOffset;
|
||||
assert resolveJumpStart > 0 : "incorrect resolveJumpStart: " + resolveJumpStart;
|
||||
assert resolveJumpOffset > 0 : "incorrect resolveJumpOffset: " + resolveJumpOffset;
|
||||
if (!isVirtual) {
|
||||
assert c2iJumpOffset > 0 : "incorrect c2iJumpOffset: " + c2iJumpOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
final class CompiledMethodInfo {
|
||||
|
||||
private static final int UNINITIALIZED_OFFSET = -1;
|
||||
|
||||
@ -169,7 +72,7 @@ public class CompiledMethodInfo {
|
||||
*/
|
||||
private int codeId;
|
||||
|
||||
public AOTMethodOffsets() {
|
||||
AOTMethodOffsets() {
|
||||
this.nameOffset = UNINITIALIZED_OFFSET;
|
||||
this.textSectionOffset = UNINITIALIZED_OFFSET;
|
||||
this.metadataOffset = UNINITIALIZED_OFFSET;
|
||||
@ -178,7 +81,7 @@ public class CompiledMethodInfo {
|
||||
this.codeId = -1;
|
||||
}
|
||||
|
||||
protected void addMethodOffsets(ReadOnlyDataContainer container, String name) {
|
||||
void addMethodOffsets(ReadOnlyDataContainer container, String name) {
|
||||
verify(name);
|
||||
// @formatter:off
|
||||
/*
|
||||
@ -291,7 +194,7 @@ public class CompiledMethodInfo {
|
||||
*/
|
||||
private static final AtomicInteger methodsCount = new AtomicInteger();
|
||||
|
||||
public CompiledMethodInfo(CompilationResult compilationResult, JavaMethodInfo methodInfo) {
|
||||
CompiledMethodInfo(CompilationResult compilationResult, JavaMethodInfo methodInfo) {
|
||||
this.name = methodInfo.getNameAndSignature();
|
||||
this.compilationResult = compilationResult;
|
||||
this.methodInfo = methodInfo;
|
||||
@ -299,11 +202,11 @@ public class CompiledMethodInfo {
|
||||
this.methodOffsets = new AOTMethodOffsets();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addMethodOffsets(BinaryContainer binaryContainer, ReadOnlyDataContainer container) {
|
||||
void addMethodOffsets(BinaryContainer binaryContainer, ReadOnlyDataContainer container) {
|
||||
this.methodOffsets.setNameOffset(binaryContainer.addMetaspaceName(name));
|
||||
this.methodOffsets.addMethodOffsets(container, name);
|
||||
for (AOTKlassData data : dependentKlasses.values()) {
|
||||
@ -311,15 +214,15 @@ public class CompiledMethodInfo {
|
||||
}
|
||||
}
|
||||
|
||||
public CompilationResult getCompilationResult() {
|
||||
CompilationResult getCompilationResult() {
|
||||
return compilationResult;
|
||||
}
|
||||
|
||||
public JavaMethodInfo getMethodInfo() {
|
||||
JavaMethodInfo getMethodInfo() {
|
||||
return methodInfo;
|
||||
}
|
||||
|
||||
public void setTextSectionOffset(int textSectionOffset) {
|
||||
void setTextSectionOffset(int textSectionOffset) {
|
||||
methodOffsets.setTextSectionOffset(textSectionOffset);
|
||||
}
|
||||
|
||||
@ -327,66 +230,66 @@ public class CompiledMethodInfo {
|
||||
return methodOffsets.getTextSectionOffset();
|
||||
}
|
||||
|
||||
public void setCodeId() {
|
||||
void setCodeId() {
|
||||
methodOffsets.setCodeId(CompiledMethodInfo.getNextCodeId());
|
||||
}
|
||||
|
||||
public int getCodeId() {
|
||||
int getCodeId() {
|
||||
return this.methodOffsets.getCodeId();
|
||||
}
|
||||
|
||||
public static int getMethodsCount() {
|
||||
static int getMethodsCount() {
|
||||
return methodsCount.get();
|
||||
}
|
||||
|
||||
public static int getNextCodeId() {
|
||||
static int getNextCodeId() {
|
||||
return methodsCount.getAndIncrement();
|
||||
}
|
||||
|
||||
public int getCodeSize() {
|
||||
int getCodeSize() {
|
||||
return stubsOffset + getStubCodeSize();
|
||||
}
|
||||
|
||||
public int getStubCodeSize() {
|
||||
int getStubCodeSize() {
|
||||
return totalStubSize;
|
||||
}
|
||||
|
||||
public void setMetadataOffset(int offset) {
|
||||
void setMetadataOffset(int offset) {
|
||||
this.methodOffsets.setMetadataOffset(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset into the code of this method where the stub section starts.
|
||||
*/
|
||||
public void setStubsOffset(int offset) {
|
||||
void setStubsOffset(int offset) {
|
||||
stubsOffset = offset;
|
||||
}
|
||||
|
||||
public int getStubsOffset() {
|
||||
int getStubsOffset() {
|
||||
return stubsOffset;
|
||||
}
|
||||
|
||||
public void setMetadataGotOffset(int metadataGotOffset) {
|
||||
void setMetadataGotOffset(int metadataGotOffset) {
|
||||
this.methodOffsets.setMetadataGotOffset(metadataGotOffset);
|
||||
}
|
||||
|
||||
public void setMetadataGotSize(int length) {
|
||||
void setMetadataGotSize(int length) {
|
||||
this.methodOffsets.setMetadataGotSize(length);
|
||||
}
|
||||
|
||||
public void addStubCode(String call, StubInformation stub) {
|
||||
void addStubCode(String call, StubInformation stub) {
|
||||
stubs.put(call, stub);
|
||||
totalStubSize += stub.getSize();
|
||||
}
|
||||
|
||||
public StubInformation getStubFor(String call) {
|
||||
StubInformation getStubFor(String call) {
|
||||
StubInformation stub = stubs.get(call);
|
||||
assert stub != null : "missing stub for call " + call;
|
||||
stub.verify();
|
||||
return stub;
|
||||
}
|
||||
|
||||
public void addDependentKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
void addDependentKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
AOTKlassData klassData = AOTCompiledClass.addFingerprintKlassData(binaryContainer, type);
|
||||
String klassName = type.getName();
|
||||
|
||||
@ -397,11 +300,11 @@ public class CompiledMethodInfo {
|
||||
}
|
||||
}
|
||||
|
||||
public AOTKlassData getDependentKlassData(String klassName) {
|
||||
AOTKlassData getDependentKlassData(String klassName) {
|
||||
return dependentKlasses.get(klassName);
|
||||
}
|
||||
|
||||
public boolean hasMark(Site call, MarkId id) {
|
||||
boolean hasMark(Site call, MarkId id) {
|
||||
for (Mark m : compilationResult.getMarks()) {
|
||||
// TODO: X64-specific code.
|
||||
// Call instructions are aligned to 8
|
||||
@ -415,11 +318,11 @@ public class CompiledMethodInfo {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String asTag() {
|
||||
String asTag() {
|
||||
return "[" + methodInfo.getSymbolName() + "]";
|
||||
}
|
||||
|
||||
public HotSpotCompiledCode compiledCode() {
|
||||
HotSpotCompiledCode compiledCode() {
|
||||
if (code == null) {
|
||||
code = methodInfo.compiledCode(compilationResult);
|
||||
}
|
||||
@ -427,12 +330,12 @@ public class CompiledMethodInfo {
|
||||
}
|
||||
|
||||
// Free memory
|
||||
public void clear() {
|
||||
void clear() {
|
||||
this.dependentKlasses = null;
|
||||
this.name = null;
|
||||
}
|
||||
|
||||
public void clearCompileData() {
|
||||
void clearCompileData() {
|
||||
this.code = null;
|
||||
this.stubs = null;
|
||||
this.compilationResult = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -31,7 +31,7 @@ import java.util.Map.Entry;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.ByteContainer;
|
||||
import jdk.tools.jaotc.binformat.HeaderContainer;
|
||||
import jdk.tools.jaotc.utils.Timer;
|
||||
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
||||
@ -42,7 +42,7 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||
import jdk.vm.ci.hotspot.VMField;
|
||||
|
||||
class DataBuilder {
|
||||
final class DataBuilder {
|
||||
|
||||
private final Main main;
|
||||
|
||||
@ -55,9 +55,9 @@ class DataBuilder {
|
||||
*/
|
||||
private final BinaryContainer binaryContainer;
|
||||
|
||||
private final HashMap<Long, String> vmAddresses = new HashMap<>();
|
||||
private static final HashMap<Long, String> vmAddresses = new HashMap<>();
|
||||
|
||||
public DataBuilder(Main main, HotSpotHostBackend backend, List<AOTCompiledClass> classes, BinaryContainer binaryContainer) {
|
||||
DataBuilder(Main main, HotSpotHostBackend backend, List<AOTCompiledClass> classes, BinaryContainer binaryContainer) {
|
||||
this.main = main;
|
||||
this.backend = backend;
|
||||
this.classes = classes;
|
||||
@ -68,7 +68,7 @@ class DataBuilder {
|
||||
/**
|
||||
* Returns a value-name map of all {@link VMField} fields.
|
||||
*/
|
||||
private void fillVMAddresses(HotSpotVMConfigStore config) {
|
||||
private static void fillVMAddresses(HotSpotVMConfigStore config) {
|
||||
for (VMField vmField : config.getFields().values()) {
|
||||
if (vmField.value != null && vmField.value instanceof Long) {
|
||||
final long address = (Long) vmField.value;
|
||||
@ -98,7 +98,7 @@ class DataBuilder {
|
||||
* @param address native address
|
||||
* @return C/C++ functio name associated with the native address
|
||||
*/
|
||||
public String getVMFunctionNameForAddress(long address) {
|
||||
static String getVMFunctionNameForAddress(long address) {
|
||||
return vmAddresses.get(address);
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ class DataBuilder {
|
||||
*
|
||||
* @return host backend
|
||||
*/
|
||||
public HotSpotHostBackend getBackend() {
|
||||
HotSpotHostBackend getBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ class DataBuilder {
|
||||
*
|
||||
* @return binary container
|
||||
*/
|
||||
public BinaryContainer getBinaryContainer() {
|
||||
BinaryContainer getBinaryContainer() {
|
||||
return binaryContainer;
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ class DataBuilder {
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings("try")
|
||||
public void prepareData(DebugContext debug) throws Exception {
|
||||
void prepareData(DebugContext debug) throws Exception {
|
||||
try (Timer t = new Timer(main, "Parsing compiled code")) {
|
||||
/*
|
||||
* Copy compiled code into code section container and calls stubs (PLT trampoline).
|
||||
@ -147,7 +147,7 @@ class DataBuilder {
|
||||
|
||||
// Free memory!
|
||||
try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
|
||||
main.printMemoryUsage();
|
||||
main.printer.printMemoryUsage();
|
||||
System.gc();
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ class DataBuilder {
|
||||
|
||||
// Free memory!
|
||||
try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
|
||||
main.printMemoryUsage();
|
||||
main.printer.printMemoryUsage();
|
||||
System.gc();
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ class DataBuilder {
|
||||
}
|
||||
try (Timer t = new Timer(main, "Preparing compiled binary")) {
|
||||
// Should be called after Stubs because they can set dependent klasses.
|
||||
prepareCompiledBinary(metadataBuilder);
|
||||
prepareCompiledBinary();
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ class DataBuilder {
|
||||
/**
|
||||
* Prepare metaspace.offsets section.
|
||||
*/
|
||||
private void prepareCompiledBinary(MetadataBuilder metadataBuilder) {
|
||||
private void prepareCompiledBinary() {
|
||||
for (AOTCompiledClass c : classes) {
|
||||
// Create records for compiled AOT methods.
|
||||
c.putMethodsData(binaryContainer);
|
||||
@ -216,8 +216,8 @@ class DataBuilder {
|
||||
header.setClassesCount(AOTCompiledClass.getClassesCount());
|
||||
header.setMethodsCount(CompiledMethodInfo.getMethodsCount());
|
||||
// Record size of got sections
|
||||
ByteContainer bc = binaryContainer.getMetaspaceGotContainer();
|
||||
header.setMetaspaceGotSize((bc.getByteStreamSize() / 8));
|
||||
ByteContainer bc = binaryContainer.getKlassesGotContainer();
|
||||
header.setKlassesGotSize((bc.getByteStreamSize() / 8));
|
||||
bc = binaryContainer.getMetadataGotContainer();
|
||||
header.setMetadataGotSize((bc.getByteStreamSize() / 8));
|
||||
bc = binaryContainer.getOopGotContainer();
|
||||
@ -232,7 +232,7 @@ class DataBuilder {
|
||||
// them.
|
||||
ArrayList<CompiledMethodInfo> compiledStubs = compiledClass.getCompiledMethods();
|
||||
int cntStubs = compiledStubs.size();
|
||||
binaryContainer.addMethodsCount(cntStubs, binaryContainer.getStubsOffsetsContainer());
|
||||
BinaryContainer.addMethodsCount(cntStubs, binaryContainer.getStubsOffsetsContainer());
|
||||
for (CompiledMethodInfo methodInfo : compiledStubs) {
|
||||
// Note, stubs have different offsets container.
|
||||
methodInfo.addMethodOffsets(binaryContainer, binaryContainer.getStubsOffsetsContainer());
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -32,7 +32,6 @@ import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
import jdk.tools.jaotc.AOTCompiledClass.AOTKlassData;
|
||||
import org.graalvm.compiler.code.DataSection;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
|
||||
|
||||
@ -47,7 +46,7 @@ import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
import jdk.vm.ci.hotspot.HotSpotSentinelConstant;
|
||||
import jdk.vm.ci.meta.VMConstant;
|
||||
|
||||
class DataPatchProcessor {
|
||||
final class DataPatchProcessor {
|
||||
|
||||
private final TargetDescription target;
|
||||
|
||||
@ -89,9 +88,9 @@ class DataPatchProcessor {
|
||||
gotName = ((action == HotSpotConstantLoadAction.INITIALIZE) ? "got.init." : "got.") + targetSymbol;
|
||||
methodInfo.addDependentKlassData(binaryContainer, type);
|
||||
} else if (metaspaceConstant.asResolvedJavaMethod() != null && action == HotSpotConstantLoadAction.LOAD_COUNTERS) {
|
||||
targetSymbol = "counters." + MiscUtils.uniqueMethodName(metaspaceConstant.asResolvedJavaMethod());
|
||||
targetSymbol = "counters." + JavaMethodInfo.uniqueMethodName(metaspaceConstant.asResolvedJavaMethod());
|
||||
gotName = "got." + targetSymbol;
|
||||
binaryContainer.addMetaspaceSymbol(targetSymbol);
|
||||
binaryContainer.addCountersSymbol(targetSymbol);
|
||||
}
|
||||
} else if (constant instanceof HotSpotObjectConstant) {
|
||||
// String constant.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.CompiledMethodInfo.StubInformation;
|
||||
import jdk.tools.jaotc.StubInformation;
|
||||
import jdk.tools.jaotc.amd64.AMD64ELFMacroAssembler;
|
||||
|
||||
import jdk.vm.ci.amd64.AMD64;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user