8206992: Update Graal
Reviewed-by: kvn
This commit is contained in:
parent
2788ddc4eb
commit
4dfa58d553
@ -511,6 +511,10 @@ jdk.aot_ADD_JAVAC_FLAGS += -parameters -XDstringConcat=inline \
|
||||
--add-exports jdk.internal.vm.ci/jdk.vm.ci.sparc=jdk.internal.vm.compiler,jdk.aot \
|
||||
#
|
||||
|
||||
jdk.aot_EXCLUDES += \
|
||||
jdk.tools.jaotc.test
|
||||
#
|
||||
|
||||
################################################################################
|
||||
|
||||
sun.charsets_COPY += .dat
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
import static org.graalvm.compiler.hotspot.meta.HotSpotAOTProfilingPlugin.Options.TieredAOT;
|
||||
@ -137,23 +139,23 @@ public final class BinaryContainer implements SymbolTable {
|
||||
*/
|
||||
private static final HashMap<String, String> functionNamesToAOTSymbols = new HashMap<>();
|
||||
|
||||
//@formatter:off
|
||||
private static final String[][] map = {
|
||||
//@formatter:off
|
||||
{"CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", "_aot_deopt_blob_unpack"},
|
||||
{"CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap", "_aot_deopt_blob_uncommon_trap"},
|
||||
{"CompilerToVM::Data::SharedRuntime_ic_miss_stub", "_aot_ic_miss_stub"},
|
||||
{"CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", "_aot_handle_wrong_method_stub"},
|
||||
{"SharedRuntime::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"},
|
||||
{"SharedRuntime::register_finalizer", "_aot_register_finalizer"},
|
||||
{"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"},
|
||||
{"SharedRuntime::enable_stack_reserved_zone", "_aot_enable_stack_reserved_zone"},
|
||||
{"CompilerRuntime::resolve_dynamic_invoke", "_aot_resolve_dynamic_invoke"},
|
||||
{"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"},
|
||||
{"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_by_symbol"},
|
||||
{"CompilerRuntime::resolve_method_by_symbol_and_load_counters","_aot_resolve_method_by_symbol_and_load_counters"},
|
||||
{"CompilerRuntime::initialize_klass_by_symbol", "_aot_initialize_klass_by_symbol"},
|
||||
{"CompilerRuntime::invocation_event", "_aot_invocation_event"},
|
||||
{"CompilerRuntime::backedge_event", "_aot_backedge_event"},
|
||||
{"CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", "_aot_deopt_blob_unpack"},
|
||||
{"CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap", "_aot_deopt_blob_uncommon_trap"},
|
||||
{"CompilerToVM::Data::SharedRuntime_ic_miss_stub", "_aot_ic_miss_stub"},
|
||||
{"CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub", "_aot_handle_wrong_method_stub"},
|
||||
{"SharedRuntime::exception_handler_for_return_address", "_aot_exception_handler_for_return_address"},
|
||||
{"SharedRuntime::register_finalizer", "_aot_register_finalizer"},
|
||||
{"SharedRuntime::OSR_migration_end", "_aot_OSR_migration_end"},
|
||||
{"SharedRuntime::enable_stack_reserved_zone", "_aot_enable_stack_reserved_zone"},
|
||||
{"CompilerRuntime::resolve_dynamic_invoke", "_aot_resolve_dynamic_invoke"},
|
||||
{"CompilerRuntime::resolve_string_by_symbol", "_aot_resolve_string_by_symbol"},
|
||||
{"CompilerRuntime::resolve_klass_by_symbol", "_aot_resolve_klass_by_symbol"},
|
||||
{"CompilerRuntime::resolve_method_by_symbol_and_load_counters", "_aot_resolve_method_by_symbol_and_load_counters"},
|
||||
{"CompilerRuntime::initialize_klass_by_symbol", "_aot_initialize_klass_by_symbol"},
|
||||
{"CompilerRuntime::invocation_event", "_aot_invocation_event"},
|
||||
{"CompilerRuntime::backedge_event", "_aot_backedge_event"},
|
||||
|
||||
{"CompilerToVM::Data::dpow", "_aot_shared_runtime_dpow"},
|
||||
{"CompilerToVM::Data::dexp", "_aot_shared_runtime_dexp"},
|
||||
@ -256,8 +258,8 @@ public final class BinaryContainer implements SymbolTable {
|
||||
|
||||
{"JVMCIRuntime::vm_error", "_aot_jvmci_runtime_vm_error"},
|
||||
{"JVMCIRuntime::new_array", "_aot_jvmci_runtime_new_array"}
|
||||
//@formatter:on
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
static {
|
||||
for (String[] entry : map) {
|
||||
@ -320,6 +322,7 @@ public final class BinaryContainer implements SymbolTable {
|
||||
}
|
||||
|
||||
private void recordConfiguration(GraalHotSpotVMConfig graalHotSpotVMConfig, GraphBuilderConfiguration graphBuilderConfig, int gc) {
|
||||
// @Checkstyle: stop
|
||||
// @formatter:off
|
||||
boolean[] booleanFlags = { graalHotSpotVMConfig.cAssertions, // Debug VM
|
||||
graalHotSpotVMConfig.useCompressedOops,
|
||||
@ -343,6 +346,7 @@ public final class BinaryContainer implements SymbolTable {
|
||||
gc
|
||||
};
|
||||
// @formatter:on
|
||||
// @Checkstyle: resume
|
||||
|
||||
byte[] booleanFlagsAsBytes = flagsToByteArray(booleanFlags);
|
||||
int size0 = configContainer.getByteStreamSize();
|
||||
@ -447,7 +451,6 @@ public final class BinaryContainer implements SymbolTable {
|
||||
return threadLocalHandshakes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the global AOT symbol associated with the function name.
|
||||
*
|
||||
@ -542,8 +545,9 @@ public final class BinaryContainer implements SymbolTable {
|
||||
JPECoffRelocObject pecoffobj = new JPECoffRelocObject(this, outputFileName);
|
||||
pecoffobj.createPECoffRelocObject(relocationTable, symbolTable.values());
|
||||
break;
|
||||
} else
|
||||
} else {
|
||||
throw new InternalError("Unsupported platform: " + osName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -553,6 +557,7 @@ public final class BinaryContainer implements SymbolTable {
|
||||
*
|
||||
* @param symInfo symbol information to be added
|
||||
*/
|
||||
@Override
|
||||
public void addSymbol(Symbol symInfo) {
|
||||
if (symInfo.getName().startsWith("got.") && !(symInfo instanceof GotSymbol)) {
|
||||
throw new InternalError("adding got. without being GotSymbol");
|
||||
@ -578,7 +583,8 @@ public final class BinaryContainer implements SymbolTable {
|
||||
* @param info relocation information to be added
|
||||
*/
|
||||
public void addRelocation(Relocation info) {
|
||||
// System.out.println("# Relocation [" + info.getSymbol() + "] [" + info.getOffset() + "] [" +
|
||||
// System.out.println("# Relocation [" + info.getSymbol() + "] [" + info.getOffset() + "] ["
|
||||
// +
|
||||
// info.getSection().getContainerName() + "] [" + info.getSymbol().getName() + "] [" +
|
||||
// info.getSymbol().getOffset() + " @ " + info.getSymbol().getSection().getContainerName() +
|
||||
// "]");
|
||||
|
@ -21,11 +21,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
import jdk.tools.jaotc.binformat.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
import jdk.tools.jaotc.binformat.Container;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -184,6 +185,7 @@ public class ByteContainer implements Container {
|
||||
*
|
||||
* @return string containing name
|
||||
*/
|
||||
@Override
|
||||
public String getContainerName() {
|
||||
return containerName;
|
||||
}
|
||||
@ -218,6 +220,7 @@ public class ByteContainer implements Container {
|
||||
sectionId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSectionId() {
|
||||
if (sectionId == -1) {
|
||||
throw new InternalError("Using sectionId before assigned");
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
interface Container {
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public final class GotSymbol extends Symbol {
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -21,10 +21,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
/**
|
||||
* This class represents ia native OS specific Symbol
|
||||
* This class represents a native OS specific Symbol.
|
||||
*/
|
||||
public abstract class NativeSymbol {
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public final class ReadOnlyDataContainer extends ByteContainer {
|
||||
|
@ -21,10 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public final class Relocation {
|
||||
|
||||
// @formatter:off (workaround for Eclipse formatting bug)
|
||||
public enum RelocType {
|
||||
UNDEFINED,
|
||||
JAVA_CALL_INDIRECT,
|
||||
@ -35,6 +38,7 @@ public final class Relocation {
|
||||
EXTERNAL_GOT_TO_PLT,
|
||||
EXTERNAL_PLT_TO_GOT
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
private final RelocType type;
|
||||
|
||||
|
@ -21,14 +21,15 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
|
||||
public class Symbol {
|
||||
|
||||
// @formatter:off (workaround for Eclipse formatting bug)
|
||||
public enum Binding {
|
||||
UNDEFINED,
|
||||
LOCAL,
|
||||
@ -42,6 +43,7 @@ public class Symbol {
|
||||
OBJECT,
|
||||
NOTYPE
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
private final String name;
|
||||
private final int size;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat;
|
||||
|
||||
public interface SymbolTable {
|
||||
|
@ -22,39 +22,24 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
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.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.ByteContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
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.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
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_Rela;
|
||||
|
||||
|
||||
public class AArch64JELFRelocObject extends JELFRelocObject {
|
||||
|
||||
AArch64JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
|
||||
super(binContainer, outputFileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
|
||||
RelocType relocType = reloc.getType();
|
||||
|
||||
@ -66,38 +51,38 @@ public class AArch64JELFRelocObject extends JELFRelocObject {
|
||||
int addend = 0;
|
||||
|
||||
switch (relocType) {
|
||||
case STUB_CALL_DIRECT:
|
||||
case JAVA_CALL_DIRECT: {
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_PLT_TO_GOT:
|
||||
offset -= 16;
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend);
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend);
|
||||
return;
|
||||
case STUB_CALL_DIRECT:
|
||||
case JAVA_CALL_DIRECT: {
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_PLT_TO_GOT:
|
||||
offset -= 16;
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend);
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend);
|
||||
return;
|
||||
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
break;
|
||||
}
|
||||
case METASPACE_GOT_REFERENCE: {
|
||||
offset -= 4;
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
break;
|
||||
}
|
||||
case METASPACE_GOT_REFERENCE: {
|
||||
offset -= 4;
|
||||
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend);
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend);
|
||||
return;
|
||||
}
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset, symno, Elf64_Rela.R_AARCH64_ADR_PREL_PG_HI21, addend);
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset + 4, symno, Elf64_Rela.R_AARCH64_ADD_ABS_LO12_NC, addend);
|
||||
return;
|
||||
}
|
||||
// break;
|
||||
case JAVA_CALL_INDIRECT: {
|
||||
addend = -4;
|
||||
offset = offset + addend;
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_GOT_TO_PLT: {
|
||||
// this is load time relocations
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InternalError("Unhandled relocation type: " + relocType);
|
||||
case JAVA_CALL_INDIRECT: {
|
||||
addend = -4;
|
||||
offset = offset + addend;
|
||||
break;
|
||||
}
|
||||
case EXTERNAL_GOT_TO_PLT: {
|
||||
// this is load time relocations
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InternalError("Unhandled relocation type: " + relocType);
|
||||
}
|
||||
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend);
|
||||
@ -109,14 +94,14 @@ public class AArch64JELFRelocObject extends JELFRelocObject {
|
||||
case Elf64_Ehdr.EM_AARCH64:
|
||||
// Return R_X86_64_* entries based on relocType
|
||||
if (relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
elfRelocType = Elf64_Rela.R_AARCH64_CALL26;
|
||||
} else if (relocType == RelocType.STUB_CALL_DIRECT) {
|
||||
elfRelocType = Elf64_Rela.R_AARCH64_CALL26;
|
||||
} else if (relocType == RelocType.JAVA_CALL_INDIRECT) {
|
||||
elfRelocType = Elf64_Rela.R_AARCH64_CALL26;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
elfRelocType = Elf64_Rela.R_AARCH64_NONE;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
elfRelocType = Elf64_Rela.R_AARCH64_ABS64;
|
||||
@ -126,8 +111,7 @@ public class AArch64JELFRelocObject extends JELFRelocObject {
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("Relocation Type mapping: Unhandled architecture: "
|
||||
+ ElfTargetInfo.getElfArch());
|
||||
System.out.println("Relocation Type mapping: Unhandled architecture: " + ElfTargetInfo.getElfArch());
|
||||
}
|
||||
return elfRelocType;
|
||||
}
|
||||
|
@ -21,39 +21,24 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
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.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.ByteContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
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.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
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_Rela;
|
||||
|
||||
|
||||
public class AMD64JELFRelocObject extends JELFRelocObject {
|
||||
|
||||
AMD64JELFRelocObject(BinaryContainer binContainer, String outputFileName) {
|
||||
super(binContainer, outputFileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createRelocation(Symbol symbol, Relocation reloc, ElfRelocTable elfRelocTable) {
|
||||
RelocType relocType = reloc.getType();
|
||||
|
||||
@ -65,62 +50,61 @@ public class AMD64JELFRelocObject extends JELFRelocObject {
|
||||
int addend = 0;
|
||||
|
||||
switch (relocType) {
|
||||
case JAVA_CALL_DIRECT:
|
||||
case STUB_CALL_DIRECT:
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
// Create relocation entry
|
||||
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 JAVA_CALL_INDIRECT:
|
||||
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.
|
||||
* 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: {
|
||||
// this is load time relocations
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InternalError("Unhandled relocation type: " + relocType);
|
||||
case JAVA_CALL_DIRECT:
|
||||
case STUB_CALL_DIRECT:
|
||||
case FOREIGN_CALL_INDIRECT_GOT: {
|
||||
// Create relocation entry
|
||||
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 JAVA_CALL_INDIRECT:
|
||||
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.
|
||||
* 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: {
|
||||
// this is load time relocations
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new InternalError("Unhandled relocation type: " + relocType);
|
||||
}
|
||||
elfRelocTable.createRelocationEntry(sectindex, offset, symno, elfRelocType, addend);
|
||||
}
|
||||
|
||||
private int getELFRelocationType(RelocType relocType) {
|
||||
private static int getELFRelocationType(RelocType relocType) {
|
||||
int elfRelocType = 0; // R_<ARCH>_NONE if #define'd to 0 for all values of ARCH
|
||||
switch (ElfTargetInfo.getElfArch()) {
|
||||
case Elf64_Ehdr.EM_X86_64:
|
||||
// Return R_X86_64_* entries based on relocType
|
||||
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.JAVA_CALL_INDIRECT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_NONE;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_PC32;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_64;
|
||||
} else {
|
||||
assert false : "Unhandled relocation type: " + relocType;
|
||||
}
|
||||
break;
|
||||
case Elf64_Ehdr.EM_X86_64:
|
||||
// Return R_X86_64_* entries based on relocType
|
||||
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.JAVA_CALL_INDIRECT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_NONE;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_PC32;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
elfRelocType = Elf64_Rela.R_X86_64_64;
|
||||
} else {
|
||||
assert false : "Unhandled relocation type: " + relocType;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("Relocation Type mapping: Unhandled architecture: "
|
||||
+ ElfTargetInfo.getElfArch());
|
||||
default:
|
||||
System.out.println("Relocation Type mapping: Unhandled architecture: " + ElfTargetInfo.getElfArch());
|
||||
}
|
||||
return elfRelocType;
|
||||
}
|
||||
|
@ -22,18 +22,19 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for the creation of Elf Object files. Current support is limited to 64 bit x86_64.
|
||||
*
|
||||
*/
|
||||
//@Checkstyle: stop
|
||||
//@formatter:off
|
||||
|
||||
/**
|
||||
* Support for the creation of Elf Object files. Current support is limited to 64 bit x86_64.
|
||||
*/
|
||||
final class Elf {
|
||||
//@formatter:off
|
||||
/**
|
||||
* Elf64_Ehdr structure defines
|
||||
* Elf64_Ehdr structure defines.
|
||||
*/
|
||||
enum Elf64_Ehdr {
|
||||
e_ident( 0,16),
|
||||
@ -103,7 +104,7 @@ final class Elf {
|
||||
}
|
||||
|
||||
/**
|
||||
* Elf64_Shdr structure defines
|
||||
* Elf64_Shdr structure defines.
|
||||
*/
|
||||
enum Elf64_Shdr {
|
||||
sh_name( 0, 4),
|
||||
@ -190,7 +191,7 @@ final class Elf {
|
||||
}
|
||||
|
||||
/**
|
||||
* Elf64_Rel structure defines
|
||||
* Elf64_Rel structure defines.
|
||||
*/
|
||||
enum Elf64_Rel {
|
||||
r_offset( 0, 8),
|
||||
@ -207,7 +208,7 @@ final class Elf {
|
||||
static int totalsize = 16;
|
||||
|
||||
/**
|
||||
* Relocation types
|
||||
* Relocation types.
|
||||
*/
|
||||
|
||||
static final int R_X86_64_NONE = 0x0;
|
||||
@ -270,9 +271,7 @@ final class Elf {
|
||||
static final int R_AARCH64_LDST64_ABS_LO12_NC = 286;
|
||||
|
||||
static long ELF64_R_INFO(int symidx, int type) {
|
||||
return (((long)symidx << 32) + type);
|
||||
return (((long) symidx << 32) + type);
|
||||
}
|
||||
|
||||
}
|
||||
//@formatter:on
|
||||
}
|
||||
|
@ -21,12 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
final class ElfByteBuffer {
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -21,14 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
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;
|
||||
|
||||
final class ElfHeader {
|
||||
private final ByteBuffer header;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
final class ElfRelocEntry {
|
||||
private final ByteBuffer entry;
|
||||
|
@ -21,14 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.ElfRelocEntry;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Rela;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
final class ElfRelocTable {
|
||||
private final ArrayList<ArrayList<ElfRelocEntry>> relocEntries;
|
||||
@ -45,14 +45,14 @@ final class ElfRelocTable {
|
||||
relocEntries.get(sectindex).add(entry);
|
||||
}
|
||||
|
||||
int getNumRelocs(int section_index) {
|
||||
return relocEntries.get(section_index).size();
|
||||
int getNumRelocs(int sectionIndex) {
|
||||
return relocEntries.get(sectionIndex).size();
|
||||
}
|
||||
|
||||
// Return the relocation entries for a single section
|
||||
// or null if no entries added to section
|
||||
byte[] getRelocData(int section_index) {
|
||||
ArrayList<ElfRelocEntry> entryList = relocEntries.get(section_index);
|
||||
byte[] getRelocData(int sectionIndex) {
|
||||
ArrayList<ElfRelocEntry> entryList = relocEntries.get(sectionIndex);
|
||||
|
||||
if (entryList.size() == 0) {
|
||||
return null;
|
||||
|
@ -21,15 +21,16 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
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_Shdr;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
final class ElfSection {
|
||||
private final String name;
|
||||
@ -39,9 +40,9 @@ final class ElfSection {
|
||||
private final int sectionIndex;
|
||||
|
||||
/**
|
||||
* String holding section name strings
|
||||
* String holding section name strings.
|
||||
*/
|
||||
private final static StringBuilder sectNameTab = new StringBuilder();
|
||||
private static final StringBuilder sectNameTab = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Keeps track of bytes in section string table since strTabContent.length() is number of chars,
|
||||
@ -50,7 +51,7 @@ final class ElfSection {
|
||||
private static int shStrTabNrOfBytes = 0;
|
||||
|
||||
ElfSection(String sectName, byte[] sectData, int sectFlags, int sectType,
|
||||
boolean hasRelocations, int align, int sectIndex) {
|
||||
boolean hasRelocations, int align, int sectIndex) {
|
||||
|
||||
section = ElfByteBuffer.allocate(Elf64_Shdr.totalsize);
|
||||
name = sectName;
|
||||
|
@ -21,13 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
final class ElfSymbol extends NativeSymbol {
|
||||
private final ByteBuffer sym;
|
||||
|
@ -21,14 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.elf.Elf.Elf64_Sym;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfSymbol;
|
||||
import jdk.tools.jaotc.binformat.elf.ElfByteBuffer;
|
||||
|
||||
final class ElfSymtab {
|
||||
|
||||
@ -36,12 +36,12 @@ final class ElfSymtab {
|
||||
private final ArrayList<ElfSymbol> globalSymbols = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* number of symbols added
|
||||
* Number of symbols added.
|
||||
*/
|
||||
private int symbolCount;
|
||||
|
||||
/**
|
||||
* String holding symbol table strings
|
||||
* String holding symbol table strings.
|
||||
*/
|
||||
private final StringBuilder strTabContent = new StringBuilder();
|
||||
|
||||
@ -77,10 +77,11 @@ final class ElfSymtab {
|
||||
strTabNrOfBytes += (name.getBytes().length + 1);
|
||||
|
||||
sym = new ElfSymbol(symbolCount, index, type, bind, secHdrIndex, offset, size);
|
||||
if ((bind & Elf64_Sym.STB_GLOBAL) != 0)
|
||||
if ((bind & Elf64_Sym.STB_GLOBAL) != 0) {
|
||||
globalSymbols.add(sym);
|
||||
else
|
||||
} else {
|
||||
localSymbols.add(sym);
|
||||
}
|
||||
}
|
||||
symbolCount++;
|
||||
return (sym);
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.elf;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -34,17 +36,12 @@ import jdk.tools.jaotc.binformat.ByteContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
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.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
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_Rela;
|
||||
|
||||
public abstract class JELFRelocObject {
|
||||
|
||||
@ -64,22 +61,22 @@ public abstract class JELFRelocObject {
|
||||
String archStr = System.getProperty("os.arch").toLowerCase();
|
||||
if (archStr.equals("amd64") || archStr.equals("x86_64")) {
|
||||
return new AMD64JELFRelocObject(binContainer, outputFileName);
|
||||
} else if (archStr.equals("aarch64")) {
|
||||
} else if (archStr.equals("aarch64")) {
|
||||
return new AArch64JELFRelocObject(binContainer, outputFileName);
|
||||
}
|
||||
throw new InternalError("Unsupported platform: " + archStr);
|
||||
}
|
||||
|
||||
private static ElfSection createByteSection(ArrayList<ElfSection> sections,
|
||||
String sectName,
|
||||
byte[] scnData,
|
||||
boolean hasRelocs,
|
||||
int align,
|
||||
int scnFlags,
|
||||
int scnType) {
|
||||
String sectName,
|
||||
byte[] scnData,
|
||||
boolean hasRelocs,
|
||||
int align,
|
||||
int scnFlags,
|
||||
int scnType) {
|
||||
|
||||
ElfSection sect = new ElfSection(sectName, scnData, scnFlags, scnType,
|
||||
hasRelocs, align, sections.size());
|
||||
hasRelocs, align, sections.size());
|
||||
// Add this section to our list
|
||||
sections.add(sect);
|
||||
|
||||
@ -87,7 +84,7 @@ public abstract class JELFRelocObject {
|
||||
}
|
||||
|
||||
private void createByteSection(ArrayList<ElfSection> sections,
|
||||
ByteContainer c, int scnFlags) {
|
||||
ByteContainer c, int scnFlags) {
|
||||
ElfSection sect;
|
||||
boolean hasRelocs = c.hasRelocations();
|
||||
byte[] scnData = c.getByteArray();
|
||||
@ -107,8 +104,8 @@ public abstract class JELFRelocObject {
|
||||
}
|
||||
|
||||
sect = createByteSection(sections, c.getContainerName(),
|
||||
scnData, hasRelocs, segmentSize,
|
||||
scnFlags, scnType);
|
||||
scnData, hasRelocs, segmentSize,
|
||||
scnFlags, scnType);
|
||||
c.setSectionId(sect.getSectionId());
|
||||
}
|
||||
|
||||
@ -125,7 +122,7 @@ public abstract class JELFRelocObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ELF relocatable object
|
||||
* Creates an ELF relocatable object.
|
||||
*
|
||||
* @param relocationTable
|
||||
* @param symbols
|
||||
@ -166,18 +163,18 @@ public abstract class JELFRelocObject {
|
||||
// that order since symtab section needs to set the index of
|
||||
// strtab in sh_link field
|
||||
ElfSection strTabSection = createByteSection(sections, ".strtab",
|
||||
symtab.getStrtabArray(),
|
||||
false, 1, 0,
|
||||
Elf64_Shdr.SHT_STRTAB);
|
||||
symtab.getStrtabArray(),
|
||||
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);
|
||||
symtab.getSymtabArray(),
|
||||
false, 8, 0,
|
||||
Elf64_Shdr.SHT_SYMTAB);
|
||||
symTabSection.setLink(strTabSection.getSectionId());
|
||||
symTabSection.setInfo(symtab.getNumLocalSyms());
|
||||
|
||||
@ -187,35 +184,35 @@ public abstract class JELFRelocObject {
|
||||
|
||||
// Now, finally, after creating all sections, create shstrtab section
|
||||
ElfSection shStrTabSection = createByteSection(sections, ".shstrtab",
|
||||
null, false, 1, 0,
|
||||
Elf64_Shdr.SHT_STRTAB);
|
||||
null, false, 1, 0,
|
||||
Elf64_Shdr.SHT_STRTAB);
|
||||
eh.setSectionStrNdx(shStrTabSection.getSectionId());
|
||||
|
||||
// Update all section offsets and the Elf header section offset
|
||||
// Write the Header followed by the contents of each section
|
||||
// and then the section structures (section table).
|
||||
int file_offset = Elf64_Ehdr.totalsize;
|
||||
int fileOffset = Elf64_Ehdr.totalsize;
|
||||
|
||||
// and round it up
|
||||
file_offset = (file_offset + (sections.get(1).getDataAlign() - 1)) &
|
||||
~((sections.get(1).getDataAlign() - 1));
|
||||
fileOffset = (fileOffset + (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));
|
||||
sect.setOffset(file_offset);
|
||||
file_offset += sect.getSize();
|
||||
fileOffset = (fileOffset + (sect.getDataAlign() - 1)) &
|
||||
~((sect.getDataAlign() - 1));
|
||||
sect.setOffset(fileOffset);
|
||||
fileOffset += sect.getSize();
|
||||
}
|
||||
|
||||
// Align the section table
|
||||
file_offset = (file_offset + (ElfSection.getShdrAlign() - 1)) &
|
||||
~((ElfSection.getShdrAlign() - 1));
|
||||
fileOffset = (fileOffset + (ElfSection.getShdrAlign() - 1)) &
|
||||
~((ElfSection.getShdrAlign() - 1));
|
||||
|
||||
// Update the Elf Header with the offset of the first Elf64_Shdr
|
||||
// and the number of sections.
|
||||
eh.setSectionOff(file_offset);
|
||||
eh.setSectionOff(fileOffset);
|
||||
eh.setSectionNum(sections.size());
|
||||
|
||||
// Write out the Header
|
||||
@ -237,8 +234,8 @@ public abstract class JELFRelocObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -283,11 +280,12 @@ public abstract class JELFRelocObject {
|
||||
* @param relocationTable
|
||||
*/
|
||||
private ElfRelocTable createElfRelocTable(ArrayList<ElfSection> sections,
|
||||
Map<Symbol, List<Relocation>> relocationTable) {
|
||||
Map<Symbol, List<Relocation>> relocationTable) {
|
||||
|
||||
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();
|
||||
@ -306,8 +304,8 @@ public abstract class JELFRelocObject {
|
||||
}
|
||||
|
||||
private static void createElfRelocSections(ArrayList<ElfSection> sections,
|
||||
ElfRelocTable elfRelocTable,
|
||||
int symtabsectidx) {
|
||||
ElfRelocTable elfRelocTable,
|
||||
int symtabsectidx) {
|
||||
|
||||
// Grab count before we create new sections
|
||||
int count = sections.size();
|
||||
@ -317,8 +315,8 @@ public abstract class JELFRelocObject {
|
||||
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);
|
||||
elfRelocTable.getRelocData(i),
|
||||
false, 8, 0, Elf64_Shdr.SHT_RELA);
|
||||
relocSection.setLink(symtabsectidx);
|
||||
relocSection.setInfo(sect.getSectionId());
|
||||
}
|
||||
|
@ -38,6 +38,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -54,19 +56,14 @@ import jdk.tools.jaotc.binformat.Relocation;
|
||||
import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
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;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.version_min_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.symtab_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.dysymtab_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.nlist_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.reloc_info;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOContainer;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOSymtab;
|
||||
import jdk.tools.jaotc.binformat.macho.MachORelocTable;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.section_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.symtab_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.version_min_command;
|
||||
|
||||
public class JMachORelocObject {
|
||||
|
||||
@ -83,18 +80,18 @@ public class JMachORelocObject {
|
||||
}
|
||||
|
||||
private void createByteSection(ArrayList<MachOSection> sections,
|
||||
ByteContainer c, String sectName, String segName, int scnFlags) {
|
||||
ByteContainer c, String sectName, String segName, int scnFlags) {
|
||||
|
||||
if (c.getByteArray().length == 0) {
|
||||
// System.out.println("Skipping creation of " + sectName + " section, no data\n");
|
||||
}
|
||||
|
||||
MachOSection sect = new MachOSection(sectName,
|
||||
segName,
|
||||
c.getByteArray(),
|
||||
scnFlags,
|
||||
c.hasRelocations(),
|
||||
segmentSize);
|
||||
segName,
|
||||
c.getByteArray(),
|
||||
scnFlags,
|
||||
c.hasRelocations(),
|
||||
segmentSize);
|
||||
// Add this section to our list
|
||||
sections.add(sect);
|
||||
|
||||
@ -107,13 +104,13 @@ public class JMachORelocObject {
|
||||
|
||||
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);
|
||||
section_64.S_ATTR_PURE_INSTRUCTIONS |
|
||||
section_64.S_ATTR_SOME_INSTRUCTIONS);
|
||||
}
|
||||
|
||||
private void createReadOnlySection(ArrayList<MachOSection> sections, ReadOnlyDataContainer c) {
|
||||
createByteSection(sections, c, c.getContainerName(), "__TEXT",
|
||||
section_64.S_ATTR_SOME_INSTRUCTIONS);
|
||||
section_64.S_ATTR_SOME_INSTRUCTIONS);
|
||||
}
|
||||
|
||||
private void createReadWriteSection(ArrayList<MachOSection> sections, ByteContainer c) {
|
||||
@ -121,7 +118,7 @@ public class JMachORelocObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an MachO relocatable object
|
||||
* Creates an MachO relocatable object.
|
||||
*
|
||||
* @param relocationTable
|
||||
* @param symbols
|
||||
@ -130,10 +127,10 @@ public class JMachORelocObject {
|
||||
public void createMachORelocObject(Map<Symbol, List<Relocation>> relocationTable, Collection<Symbol> symbols) throws IOException {
|
||||
// Allocate MachO Header
|
||||
// with 4 load commands
|
||||
// LC_SEGMENT_64
|
||||
// LC_VERSION_MIN_MACOSX
|
||||
// LC_SYMTAB
|
||||
// LC_DYSYMTAB
|
||||
// LC_SEGMENT_64
|
||||
// LC_VERSION_MIN_MACOSX
|
||||
// LC_SYMTAB
|
||||
// LC_DYSYMTAB
|
||||
|
||||
MachOHeader mh = new MachOHeader();
|
||||
|
||||
@ -162,37 +159,37 @@ public class JMachORelocObject {
|
||||
// Update the Header sizeofcmds size.
|
||||
// This doesn't include the Header struct size
|
||||
mh.setCmdSizes(4, segment_command_64.totalsize +
|
||||
(section_64.totalsize * sections.size()) +
|
||||
version_min_command.totalsize +
|
||||
symtab_command.totalsize +
|
||||
dysymtab_command.totalsize);
|
||||
(section_64.totalsize * sections.size()) +
|
||||
version_min_command.totalsize +
|
||||
symtab_command.totalsize +
|
||||
dysymtab_command.totalsize);
|
||||
|
||||
// Initialize file offset for data past commands
|
||||
int file_offset = mach_header_64.totalsize + mh.getCmdSize();
|
||||
int fileOffset = mach_header_64.totalsize + mh.getCmdSize();
|
||||
// and round it up
|
||||
file_offset = (file_offset + (sections.get(0).getAlign() - 1)) & ~((sections.get(0).getAlign() - 1));
|
||||
fileOffset = (fileOffset + (sections.get(0).getAlign() - 1)) & ~((sections.get(0).getAlign() - 1));
|
||||
long address = 0;
|
||||
int segment_offset = file_offset;
|
||||
int segmentOffset = fileOffset;
|
||||
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
MachOSection sect = sections.get(i);
|
||||
file_offset = (file_offset + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1));
|
||||
fileOffset = (fileOffset + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1));
|
||||
address = (address + (sect.getAlign() - 1)) & ~((sect.getAlign() - 1));
|
||||
sect.setOffset(file_offset);
|
||||
sect.setOffset(fileOffset);
|
||||
sect.setAddr(address);
|
||||
file_offset += sect.getSize();
|
||||
fileOffset += sect.getSize();
|
||||
address += sect.getSize();
|
||||
}
|
||||
|
||||
// File size for Segment data
|
||||
int segment_size = file_offset - segment_offset;
|
||||
int segSize = fileOffset - segmentOffset;
|
||||
|
||||
// Create the LC_SEGMENT_64 Segment which contains the MachOSections
|
||||
MachOSegment seg = new MachOSegment(segment_command_64.totalsize +
|
||||
(section_64.totalsize * sections.size()),
|
||||
segment_offset,
|
||||
segment_size,
|
||||
sections.size());
|
||||
(section_64.totalsize * sections.size()),
|
||||
segmentOffset,
|
||||
segSize,
|
||||
sections.size());
|
||||
|
||||
MachOVersion vers = new MachOVersion();
|
||||
|
||||
@ -201,28 +198,28 @@ public class JMachORelocObject {
|
||||
|
||||
// Create LC_DYSYMTAB command
|
||||
MachODySymtab dysymtab = new MachODySymtab(symtab.getNumLocalSyms(),
|
||||
symtab.getNumGlobalSyms(),
|
||||
symtab.getNumUndefSyms());
|
||||
symtab.getNumGlobalSyms(),
|
||||
symtab.getNumUndefSyms());
|
||||
|
||||
// Create the Relocation Tables
|
||||
MachORelocTable machORelocs = createMachORelocTable(sections, relocationTable, symtab);
|
||||
// Calculate file offset for relocation data
|
||||
file_offset = (file_offset + (MachORelocTable.getAlign() - 1)) & ~((MachORelocTable.getAlign() - 1));
|
||||
fileOffset = (fileOffset + (MachORelocTable.getAlign() - 1)) & ~((MachORelocTable.getAlign() - 1));
|
||||
|
||||
// Update relocation sizing information in each section
|
||||
for (int i = 0; i < sections.size(); i++) {
|
||||
MachOSection sect = sections.get(i);
|
||||
if (sect.hasRelocations()) {
|
||||
int nreloc = machORelocs.getNumRelocs(i);
|
||||
sect.setReloff(file_offset);
|
||||
sect.setReloff(fileOffset);
|
||||
sect.setRelcount(nreloc);
|
||||
file_offset += (nreloc * reloc_info.totalsize);
|
||||
fileOffset += (nreloc * reloc_info.totalsize);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate and set file offset for symbol table data
|
||||
file_offset = (file_offset + (MachOSymtab.getAlign() - 1)) & ~((MachOSymtab.getAlign() - 1));
|
||||
symtab.setOffset(file_offset);
|
||||
fileOffset = (fileOffset + (MachOSymtab.getAlign() - 1)) & ~((MachOSymtab.getAlign() - 1));
|
||||
symtab.setOffset(fileOffset);
|
||||
|
||||
// Write Out Header
|
||||
machoContainer.writeBytes(mh.getArray());
|
||||
@ -271,7 +268,7 @@ public class JMachORelocObject {
|
||||
* @param symbols
|
||||
*/
|
||||
private static MachOSymtab createMachOSymbolTables(ArrayList<MachOSection> sections,
|
||||
Collection<Symbol> symbols) {
|
||||
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, 0);
|
||||
@ -284,9 +281,9 @@ public class JMachORelocObject {
|
||||
long sectionAddr = sections.get(sectionId).getAddr();
|
||||
|
||||
MachOSymbol machoSymbol = symtab.addSymbolEntry(symbol.getName(),
|
||||
getMachOTypeOf(symbol),
|
||||
(byte) sectionId,
|
||||
symbol.getOffset() + sectionAddr);
|
||||
getMachOTypeOf(symbol),
|
||||
(byte) sectionId,
|
||||
symbol.getOffset() + sectionAddr);
|
||||
symbol.setNativeSymbol(machoSymbol);
|
||||
}
|
||||
|
||||
@ -308,8 +305,8 @@ public class JMachORelocObject {
|
||||
}
|
||||
// If Function or Data, add section type
|
||||
if (kind == Symbol.Kind.NATIVE_FUNCTION ||
|
||||
kind == Symbol.Kind.JAVA_FUNCTION ||
|
||||
kind == Symbol.Kind.OBJECT) {
|
||||
kind == Symbol.Kind.JAVA_FUNCTION ||
|
||||
kind == Symbol.Kind.OBJECT) {
|
||||
type |= (nlist_64.N_SECT);
|
||||
}
|
||||
|
||||
@ -324,12 +321,13 @@ public class JMachORelocObject {
|
||||
* @param symtab
|
||||
*/
|
||||
private MachORelocTable createMachORelocTable(ArrayList<MachOSection> sections,
|
||||
Map<Symbol, List<Relocation>> relocationTable,
|
||||
MachOSymtab symtab) {
|
||||
Map<Symbol, List<Relocation>> relocationTable,
|
||||
MachOSymtab symtab) {
|
||||
|
||||
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();
|
||||
@ -380,8 +378,8 @@ public class JMachORelocObject {
|
||||
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.
|
||||
* 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;
|
||||
@ -398,8 +396,8 @@ public class JMachORelocObject {
|
||||
throw new InternalError("Unhandled relocation type: " + relocType);
|
||||
}
|
||||
machORelocTable.createRelocationEntry(sectindex, offset, symno,
|
||||
pcrel, length, isextern,
|
||||
machORelocType);
|
||||
pcrel, length, isextern,
|
||||
machORelocType);
|
||||
}
|
||||
|
||||
private static int getMachORelocationType(RelocType relocType) {
|
||||
@ -408,14 +406,14 @@ public class JMachORelocObject {
|
||||
case mach_header_64.CPU_TYPE_X86_64:
|
||||
// Return X86_64_RELOC_* entries based on relocType
|
||||
if (relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
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.JAVA_CALL_INDIRECT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_NONE;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_BRANCH;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
machORelocType = reloc_info.X86_64_RELOC_UNSIGNED;
|
||||
|
@ -21,9 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
//@formatter:off
|
||||
//@Checkstyle: stop
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for the creation of Mach-o Object files. Current support is limited to 64 bit x86_64.
|
||||
@ -305,4 +309,3 @@ final class MachO {
|
||||
static final int X86_64_RELOC_UNSIGNED = 0x0;
|
||||
}
|
||||
}
|
||||
//@formatter:on
|
||||
|
@ -21,11 +21,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOTargetInfo;
|
||||
|
||||
final class MachOByteBuffer {
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.dysymtab_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachODySymtab {
|
||||
private final ByteBuffer dysymtab;
|
||||
|
@ -21,13 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.mach_header_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachOHeader {
|
||||
private final ByteBuffer header;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.reloc_info;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachORelocEntry {
|
||||
private final ByteBuffer entry;
|
||||
|
@ -21,14 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachORelocEntry;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.reloc_info;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachORelocTable {
|
||||
private final ArrayList<ArrayList<MachORelocEntry>> relocEntries;
|
||||
@ -50,14 +50,14 @@ final class MachORelocTable {
|
||||
return (4);
|
||||
}
|
||||
|
||||
int getNumRelocs(int section_index) {
|
||||
return relocEntries.get(section_index).size();
|
||||
int getNumRelocs(int sectionIndex) {
|
||||
return relocEntries.get(sectionIndex).size();
|
||||
}
|
||||
|
||||
// Return the relocation entries for a single section
|
||||
// or null if no entries added to section
|
||||
byte[] getRelocData(int section_index) {
|
||||
ArrayList<MachORelocEntry> entryList = relocEntries.get(section_index);
|
||||
byte[] getRelocData(int sectionIndex) {
|
||||
ArrayList<MachORelocEntry> entryList = relocEntries.get(sectionIndex);
|
||||
|
||||
if (entryList.size() == 0) {
|
||||
return null;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.section_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachOSection {
|
||||
private final ByteBuffer section;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.segment_command_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
public class MachOSegment {
|
||||
ByteBuffer segment;
|
||||
|
@ -21,13 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.nlist_64;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachOSymbol extends NativeSymbol {
|
||||
private final ByteBuffer sym;
|
||||
|
@ -21,20 +21,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
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;
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.symtab_command;
|
||||
|
||||
final class MachOSymtab {
|
||||
|
||||
/**
|
||||
* ByteBuffer holding the LC_SYMTAB command contents
|
||||
* ByteBuffer holding the LC_SYMTAB command contents.
|
||||
*/
|
||||
private final ByteBuffer symtabCmd;
|
||||
|
||||
@ -45,17 +45,18 @@ final class MachOSymtab {
|
||||
private final ArrayList<MachOSymbol> undefSymbols = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* number of symbols added
|
||||
* Number of symbols added.
|
||||
*/
|
||||
private int symbolCount;
|
||||
|
||||
/**
|
||||
* String holding symbol table strings
|
||||
* String holding symbol table strings.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.macho;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.macho.MachO.version_min_command;
|
||||
import jdk.tools.jaotc.binformat.macho.MachOByteBuffer;
|
||||
|
||||
final class MachOVersion {
|
||||
private final ByteBuffer version;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -38,13 +40,10 @@ 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.binformat.pecoff.PECoffSymbol;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffTargetInfo;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION;
|
||||
|
||||
public class JPECoffRelocObject {
|
||||
|
||||
@ -102,7 +101,7 @@ public class JPECoffRelocObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an PECoff relocatable object
|
||||
* Creates a PECoff relocatable object.
|
||||
*
|
||||
* @param relocationTable
|
||||
* @param symbols
|
||||
@ -138,7 +137,11 @@ public class JPECoffRelocObject {
|
||||
|
||||
// Add Linker Directives Section
|
||||
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 */);
|
||||
createByteSection(sections, ".drectve", symtab.getDirectiveArray(), false, scnFlags, 1 /*
|
||||
* 1
|
||||
* byte
|
||||
* alignment
|
||||
*/);
|
||||
|
||||
// Create the Relocation Tables
|
||||
PECoffRelocTable pecoffRelocs = createPECoffRelocTable(sections, relocationTable);
|
||||
@ -154,28 +157,28 @@ public class JPECoffRelocObject {
|
||||
// RELOCATION TABLE
|
||||
|
||||
// Calculate Offset for Symbol table
|
||||
int file_offset = IMAGE_FILE_HEADER.totalsize +
|
||||
int fileOffset = IMAGE_FILE_HEADER.totalsize +
|
||||
(IMAGE_SECTION_HEADER.totalsize * sections.size());
|
||||
|
||||
// Update Header fields
|
||||
header.setSectionCount(sections.size());
|
||||
header.setSymbolCount(symtab.getSymtabCount());
|
||||
header.setSymbolOff(file_offset);
|
||||
header.setSymbolOff(fileOffset);
|
||||
|
||||
// Calculate file offset for first section
|
||||
file_offset += ((symtab.getSymtabCount() * IMAGE_SYMBOL.totalsize) +
|
||||
fileOffset += ((symtab.getSymtabCount() * IMAGE_SYMBOL.totalsize) +
|
||||
symtab.getStrtabSize());
|
||||
// And round it up
|
||||
file_offset = (file_offset + (sections.get(0).getDataAlign() - 1)) &
|
||||
fileOffset = (fileOffset + (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)) &
|
||||
fileOffset = (fileOffset + (sect.getDataAlign() - 1)) &
|
||||
~((sect.getDataAlign() - 1));
|
||||
sect.setOffset(file_offset);
|
||||
file_offset += sect.getSize();
|
||||
sect.setOffset(fileOffset);
|
||||
fileOffset += sect.getSize();
|
||||
}
|
||||
|
||||
// Update relocation sizing information in each section
|
||||
@ -183,13 +186,13 @@ public class JPECoffRelocObject {
|
||||
PECoffSection sect = sections.get(i);
|
||||
if (sect.hasRelocations()) {
|
||||
int nreloc = pecoffRelocs.getNumRelocs(i);
|
||||
sect.setReloff(file_offset);
|
||||
sect.setReloff(fileOffset);
|
||||
sect.setRelcount(nreloc);
|
||||
// extended relocations add an addition entry
|
||||
if (nreloc > 0xFFFF) {
|
||||
nreloc++;
|
||||
}
|
||||
file_offset += (nreloc * IMAGE_RELOCATION.totalsize);
|
||||
fileOffset += (nreloc * IMAGE_RELOCATION.totalsize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +272,8 @@ public class JPECoffRelocObject {
|
||||
|
||||
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();
|
||||
@ -316,8 +320,8 @@ public class JPECoffRelocObject {
|
||||
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.
|
||||
* 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;
|
||||
@ -338,14 +342,14 @@ public class JPECoffRelocObject {
|
||||
switch (PECoffTargetInfo.getPECoffArch()) {
|
||||
case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64:
|
||||
if (relocType == RelocType.JAVA_CALL_DIRECT ||
|
||||
relocType == RelocType.FOREIGN_CALL_INDIRECT_GOT) {
|
||||
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.JAVA_CALL_INDIRECT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ABSOLUTE;
|
||||
} else if (relocType == RelocType.METASPACE_GOT_REFERENCE ||
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
relocType == RelocType.EXTERNAL_PLT_TO_GOT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_REL32;
|
||||
} else if (relocType == RelocType.EXTERNAL_GOT_TO_PLT) {
|
||||
pecoffRelocType = IMAGE_RELOCATION.IMAGE_REL_AMD64_ADDR64;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
/**
|
||||
@ -32,13 +34,13 @@ package jdk.tools.jaotc.binformat.pecoff;
|
||||
final class PECoff {
|
||||
//@formatter:off
|
||||
/**
|
||||
* IMAGE_FILE_HEADER structure defines
|
||||
* IMAGE_FILE_HEADER structure defines.
|
||||
*/
|
||||
enum IMAGE_FILE_HEADER {
|
||||
Machine( 0, 2),
|
||||
NumberOfSections( 2, 2),
|
||||
TimeDateStamp( 4, 4),
|
||||
PointerToSymbolTable( 8, 4),
|
||||
Machine(0, 2),
|
||||
NumberOfSections(2, 2),
|
||||
TimeDateStamp(4, 4),
|
||||
PointerToSymbolTable(8, 4),
|
||||
NumberOfSymbols(12, 4),
|
||||
SizeOfOptionalHeader(16, 2),
|
||||
Characteristics(18, 2);
|
||||
@ -58,7 +60,7 @@ final class PECoff {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Machine
|
||||
* Machine.
|
||||
*/
|
||||
static final char IMAGE_FILE_MACHINE_UNKNOWN = 0x0;
|
||||
static final char IMAGE_FILE_MACHINE_AMD64 = 0x8664;
|
||||
@ -66,12 +68,12 @@ final class PECoff {
|
||||
}
|
||||
|
||||
/**
|
||||
* IMAGE_SECTION_HEADER structure defines
|
||||
* IMAGE_SECTION_HEADER structure defines.
|
||||
*/
|
||||
enum IMAGE_SECTION_HEADER {
|
||||
Name( 0, 8),
|
||||
PhysicalAddress( 8, 4),
|
||||
VirtualSize( 8, 4),
|
||||
Name(0, 8),
|
||||
PhysicalAddress(8, 4),
|
||||
VirtualSize(8, 4),
|
||||
VirtualAddress(12, 4),
|
||||
SizeOfRawData(16, 4),
|
||||
PointerToRawData(20, 4),
|
||||
@ -96,7 +98,7 @@ final class PECoff {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Characteristics
|
||||
* Characteristics.
|
||||
*/
|
||||
static final int IMAGE_SCN_CNT_CODE = 0x20;
|
||||
static final int IMAGE_SCN_CNT_INITIALIZED_DATA = 0x40;
|
||||
@ -129,15 +131,15 @@ final class PECoff {
|
||||
}
|
||||
|
||||
/**
|
||||
* Symbol table entry definitions
|
||||
* Symbol table entry definitions.
|
||||
*
|
||||
* IMAGE_SYMBOL structure defines
|
||||
*/
|
||||
enum IMAGE_SYMBOL {
|
||||
ShortName( 0, 8),
|
||||
Short( 0, 4),
|
||||
Long( 4, 4),
|
||||
Value( 8, 4),
|
||||
ShortName(0, 8),
|
||||
Short(0, 4),
|
||||
Long(4, 4),
|
||||
Value(8, 4),
|
||||
SectionNumber(12, 2),
|
||||
Type(14, 2),
|
||||
StorageClass(16, 1),
|
||||
@ -154,13 +156,13 @@ final class PECoff {
|
||||
static int totalsize = 18;
|
||||
|
||||
/**
|
||||
* Type
|
||||
* Type.
|
||||
*/
|
||||
static final int IMAGE_SYM_DTYPE_NONE = 0x0;
|
||||
static final int IMAGE_SYM_DTYPE_FUNCTION = 0x20;
|
||||
|
||||
/**
|
||||
* StorageClass
|
||||
* StorageClass.
|
||||
*/
|
||||
static final int IMAGE_SYM_CLASS_NULL = 0x0;
|
||||
static final int IMAGE_SYM_CLASS_EXTERNAL = 0x2;
|
||||
@ -170,12 +172,12 @@ final class PECoff {
|
||||
}
|
||||
|
||||
/**
|
||||
* IMAGE_RELOCATION structure defines
|
||||
* IMAGE_RELOCATION structure defines.
|
||||
*/
|
||||
enum IMAGE_RELOCATION {
|
||||
VirtualAddress( 0, 4),
|
||||
SymbolTableIndex( 4, 4),
|
||||
Type( 8, 2);
|
||||
VirtualAddress(0, 4),
|
||||
SymbolTableIndex(4, 4),
|
||||
Type(8, 2);
|
||||
|
||||
final int off;
|
||||
final int sz;
|
||||
@ -188,7 +190,7 @@ final class PECoff {
|
||||
static int totalsize = 10;
|
||||
|
||||
/**
|
||||
* Relocation types
|
||||
* Relocation types.
|
||||
*/
|
||||
static final int IMAGE_REL_AMD64_ABSOLUTE = 0x0;
|
||||
static final int IMAGE_REL_AMD64_ADDR32 = 0x2;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_FILE_HEADER;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
final class PECoffHeader {
|
||||
private final ByteBuffer header;
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
final class PECoffRelocEntry {
|
||||
private final ByteBuffer entry;
|
||||
|
@ -21,14 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_RELOCATION;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffRelocEntry;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
final class PECoffRelocTable {
|
||||
ArrayList<ArrayList<PECoffRelocEntry>> relocEntries;
|
||||
@ -49,14 +49,14 @@ final class PECoffRelocTable {
|
||||
return (4);
|
||||
}
|
||||
|
||||
int getNumRelocs(int section_index) {
|
||||
return relocEntries.get(section_index).size();
|
||||
int getNumRelocs(int sectionIndex) {
|
||||
return relocEntries.get(sectionIndex).size();
|
||||
}
|
||||
|
||||
// Return the relocation entries for a single section
|
||||
// or null if no entries added to section
|
||||
byte[] getRelocData(int section_index) {
|
||||
ArrayList<PECoffRelocEntry> entryList = relocEntries.get(section_index);
|
||||
byte[] getRelocData(int sectionIndex) {
|
||||
ArrayList<PECoffRelocEntry> entryList = relocEntries.get(sectionIndex);
|
||||
int entryCount = entryList.size();
|
||||
int allocCount = entryCount;
|
||||
|
||||
|
@ -21,12 +21,13 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SECTION_HEADER;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
final class PECoffSection {
|
||||
private final ByteBuffer section;
|
||||
@ -47,8 +48,8 @@ final class PECoffSection {
|
||||
}
|
||||
|
||||
// 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;
|
||||
@ -58,7 +59,7 @@ final class PECoffSection {
|
||||
// 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);
|
||||
section.put(name, IMAGE_SECTION_HEADER.Name.off, max);
|
||||
|
||||
section.putInt(IMAGE_SECTION_HEADER.VirtualSize.off, 0);
|
||||
section.putInt(IMAGE_SECTION_HEADER.VirtualAddress.off, 0);
|
||||
|
@ -21,13 +21,14 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import jdk.tools.jaotc.binformat.NativeSymbol;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
final class PECoffSymbol extends NativeSymbol {
|
||||
private final ByteBuffer sym;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -28,19 +30,17 @@ import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoff.IMAGE_SYMBOL;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffSymbol;
|
||||
import jdk.tools.jaotc.binformat.pecoff.PECoffByteBuffer;
|
||||
|
||||
final class PECoffSymtab {
|
||||
ArrayList<PECoffSymbol> symbols = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* number of symbols added
|
||||
* Number of symbols added.
|
||||
*/
|
||||
private int symbolCount;
|
||||
|
||||
/**
|
||||
* String holding symbol table strings
|
||||
* String holding symbol table strings.
|
||||
*/
|
||||
private final StringBuilder strTabContent;
|
||||
|
||||
@ -51,7 +51,7 @@ final class PECoffSymtab {
|
||||
private int strTabNrOfBytes;
|
||||
|
||||
/**
|
||||
* String holding Linker Directives
|
||||
* String holding Linker Directives.
|
||||
*/
|
||||
private final StringBuilder directives;
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.binformat.pecoff;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,19 +22,10 @@
|
||||
*/
|
||||
|
||||
|
||||
package org.graalvm.compiler.jtt.hotspot;
|
||||
package jdk.tools.jaotc.test;
|
||||
|
||||
import org.junit.rules.DisableOnDebug;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
public final class NotOnDebug {
|
||||
public static TestRule create(Timeout seconds) {
|
||||
try {
|
||||
return new DisableOnDebug(seconds);
|
||||
} catch (LinkageError ex) {
|
||||
return null;
|
||||
}
|
||||
public class HelloWorld {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc.utils
|
||||
* @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI jdk.tools.jaotc.test.NativeOrderOutputStreamTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test;
|
||||
|
||||
import jdk.tools.jaotc.utils.NativeOrderOutputStream;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class NativeOrderOutputStreamTest {
|
||||
|
||||
private NativeOrderOutputStream target;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
target = new NativeOrderOutputStream();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAdd4BytesForInt() {
|
||||
target.putInt(5);
|
||||
Assert.assertEquals(4, target.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAdd8BytesForLong() {
|
||||
target.putLong(8);
|
||||
Assert.assertEquals(8, target.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveCorrectSizeBeforePatch() {
|
||||
target.patchableInt();
|
||||
Assert.assertEquals(4, target.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHaveCorrectSizeAfterPatch() {
|
||||
NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt();
|
||||
patchableInt.set(12);
|
||||
Assert.assertEquals(4, target.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSetCorrectValueInPatch() {
|
||||
NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt();
|
||||
patchableInt.set(42);
|
||||
Assert.assertEquals(42, getInt(0));
|
||||
}
|
||||
|
||||
private int getInt(int pos) {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(target.array());
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
return buffer.getInt(pos);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPutArrayCorrectly() {
|
||||
target.put(new byte[]{42, 5, 43, 44});
|
||||
Assert.assertEquals(4, target.position());
|
||||
Assert.assertEquals(42, target.array()[0]);
|
||||
Assert.assertEquals(4, target.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldOnlyPatchSlot() {
|
||||
NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt();
|
||||
target.putInt(7);
|
||||
patchableInt.set(39);
|
||||
Assert.assertEquals(39, getInt(0));
|
||||
Assert.assertEquals(7, getInt(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldBeAbleToPatchAnywhere() {
|
||||
target.putInt(19);
|
||||
NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt();
|
||||
patchableInt.set(242);
|
||||
|
||||
Assert.assertEquals(19, getInt(0));
|
||||
Assert.assertEquals(242, getInt(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHavePatchableAtRightOffset() {
|
||||
target.putInt(27);
|
||||
Assert.assertEquals(4, target.position());
|
||||
NativeOrderOutputStream.PatchableInt patchableInt = target.patchableInt();
|
||||
Assert.assertEquals(4, patchableInt.position());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAlign() {
|
||||
target.putInt(9);
|
||||
target.align(16);
|
||||
target.put(new byte[]{3});
|
||||
target.align(8);
|
||||
Assert.assertEquals(24, target.position());
|
||||
}
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.ClassSearchTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.tools.jaotc.LoadedClass;
|
||||
import jdk.tools.jaotc.collect.ClassSearch;
|
||||
import jdk.tools.jaotc.collect.ClassSource;
|
||||
import jdk.tools.jaotc.collect.SearchFor;
|
||||
import jdk.tools.jaotc.collect.SearchPath;
|
||||
import jdk.tools.jaotc.collect.SourceProvider;
|
||||
|
||||
public class ClassSearchTest {
|
||||
@Test(expected = InternalError.class)
|
||||
public void itShouldThrowExceptionIfNoProvidersAvailable() {
|
||||
ClassSearch target = new ClassSearch();
|
||||
SearchPath searchPath = new SearchPath();
|
||||
target.search(list(new SearchFor("foo")), searchPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldFindAProviderForEachEntry() {
|
||||
Set<String> searched = new HashSet<>();
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(provider("", (name, searchPath) -> {
|
||||
searched.add(name);
|
||||
return new NoopSource();
|
||||
}));
|
||||
target.search(searchForList("foo", "bar", "foobar"), null);
|
||||
Assert.assertEquals(hashset("foo", "bar", "foobar"), searched);
|
||||
}
|
||||
|
||||
private static SourceProvider provider(String supports, BiFunction<String, SearchPath, ClassSource> fn) {
|
||||
return new SourceProvider() {
|
||||
@Override
|
||||
public ClassSource findSource(String name, SearchPath searchPath) {
|
||||
return fn.apply(name, searchPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(String type) {
|
||||
return supports.equals(type);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldOnlySearchSupportedProvidersForKnownType() {
|
||||
Set<String> visited = new HashSet<>();
|
||||
ClassSearch target = new ClassSearch();
|
||||
|
||||
target.addProvider(provider("jar", (name, searchPath) -> {
|
||||
visited.add("jar");
|
||||
return null;
|
||||
}));
|
||||
|
||||
target.addProvider(provider("dir", (name, searchPath) -> {
|
||||
visited.add("dir");
|
||||
return null;
|
||||
}));
|
||||
|
||||
try {
|
||||
target.search(list(new SearchFor("some", "dir")), null);
|
||||
} catch (InternalError e) {
|
||||
// throws because no provider gives a source
|
||||
}
|
||||
|
||||
Assert.assertEquals(hashset("dir"), visited);
|
||||
}
|
||||
|
||||
@Test(expected = InternalError.class)
|
||||
public void itShouldThrowErrorIfMultipleSourcesAreAvailable() {
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(provider("", (name, searchPath) -> consumer -> Assert.fail()));
|
||||
target.addProvider(provider("", (name, searchPath) -> consumer -> Assert.fail()));
|
||||
|
||||
target.search(searchForList("somethign"), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldSearchAllProvidersForUnknownType() {
|
||||
Set<String> visited = new HashSet<>();
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(provider("", (name, searchPath) -> {
|
||||
visited.add("1");
|
||||
return null;
|
||||
}));
|
||||
target.addProvider(provider("", (name, searchPath) -> {
|
||||
visited.add("2");
|
||||
return null;
|
||||
}));
|
||||
|
||||
try {
|
||||
target.search(searchForList("foo"), null);
|
||||
} catch (InternalError e) {
|
||||
// throws because no provider gives a source
|
||||
}
|
||||
|
||||
Assert.assertEquals(hashset("1", "2"), visited);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldTryToLoadSaidClassFromClassLoader() {
|
||||
Set<String> loaded = new HashSet<>();
|
||||
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(new SourceProvider() {
|
||||
@Override
|
||||
public boolean supports(String type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassSource findSource(String name, SearchPath searchPath) {
|
||||
return new ClassSource() {
|
||||
@Override
|
||||
public void eachClass(BiConsumer<String, ClassLoader> consumer) {
|
||||
consumer.accept("foo.Bar", new ClassLoader() {
|
||||
@Override
|
||||
public Class<?> loadClass(String nm) throws ClassNotFoundException {
|
||||
loaded.add(nm);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
java.util.List<LoadedClass> search = target.search(searchForList("/tmp/something"), null);
|
||||
Assert.assertEquals(list(new LoadedClass("foo.Bar", null)), search);
|
||||
}
|
||||
|
||||
@Test(expected = InternalError.class)
|
||||
public void itShouldThrowInternalErrorWhenClassLoaderFails() {
|
||||
ClassLoader classLoader = new ClassLoader() {
|
||||
@Override
|
||||
public Class<?> loadClass(String name1) throws ClassNotFoundException {
|
||||
throw new ClassNotFoundException("failed to find " + name1);
|
||||
}
|
||||
};
|
||||
|
||||
ClassSearch target = new ClassSearch();
|
||||
target.addProvider(provider("", (name, searchPath) -> consumer -> consumer.accept("foo.Bar", classLoader)));
|
||||
target.search(searchForList("foobar"), null);
|
||||
}
|
||||
|
||||
private static List<SearchFor> searchForList(String... entries) {
|
||||
List<SearchFor> list = new ArrayList<>();
|
||||
for (String entry : entries) {
|
||||
list.add(new SearchFor(entry));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <T> List<T> list(T... entries) {
|
||||
List<T> list = new ArrayList<>();
|
||||
for (T entry : entries) {
|
||||
list.add(entry);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static <T> Set<T> hashset(T... entries) {
|
||||
Set<T> set = new HashSet<>();
|
||||
for (T entry : entries) {
|
||||
set.add(entry);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
private static class NoopSource implements ClassSource {
|
||||
@Override
|
||||
public void eachClass(BiConsumer<String, ClassLoader> consumer) {
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* @build jdk.tools.jaotc.test.collect.Utils
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.ClassSourceTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static jdk.tools.jaotc.collect.ClassSource.makeClassName;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.getpath;
|
||||
|
||||
public class ClassSourceTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void itShouldThrowExceptionIfPathDoesntEndWithClass() {
|
||||
makeClassName(Paths.get("Bar.clazz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReplaceSlashesWithDots() {
|
||||
Assert.assertEquals("foo.Bar", makeClassName(getpath("foo/Bar.class")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldStripLeadingSlash() {
|
||||
Assert.assertEquals("Hello", makeClassName(getpath("/Hello.class")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReplaceMultipleDots() {
|
||||
Assert.assertEquals("some.foo.bar.FooBar", makeClassName(getpath("/some/foo/bar/FooBar.class")));
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.test.collect;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
|
||||
public class FakeFileSupport extends FileSupport {
|
||||
private final Set<String> exists = new HashSet<>();
|
||||
private final Set<String> directories = new HashSet<>();
|
||||
|
||||
private final Set<String> checkedExists = new HashSet<>();
|
||||
private final Set<String> checkedDirectory = new HashSet<>();
|
||||
private final Set<String> checkedJarFileSystemRoots = new HashSet<>();
|
||||
private final Set<String> classloaderPaths = new HashSet<>();
|
||||
|
||||
private Path jarFileSystemRoot = null;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
public FakeFileSupport(Set<String> existing, Set<String> directories) {
|
||||
this.exists.addAll(existing);
|
||||
this.directories.addAll(directories);
|
||||
|
||||
classLoader = new ClassLoader() {
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setJarFileSystemRoot(Path path) {
|
||||
jarFileSystemRoot = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(Path path) {
|
||||
checkedExists.add(path.toString());
|
||||
return exists.contains(path.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory(Path path) {
|
||||
checkedDirectory.add(path.toString());
|
||||
return directories.contains(path.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader createClassLoader(Path path) throws MalformedURLException {
|
||||
classloaderPaths.add(path.toString());
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getJarFileSystemRoot(Path jarFile) {
|
||||
checkedJarFileSystemRoots.add(jarFile.toString());
|
||||
return jarFileSystemRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbsolute(Path entry) {
|
||||
return entry.toString().startsWith("/");
|
||||
}
|
||||
|
||||
public void addExist(String name) {
|
||||
exists.add(name);
|
||||
}
|
||||
|
||||
public void addDirectory(String name) {
|
||||
directories.add(name);
|
||||
}
|
||||
|
||||
public Set<String> getCheckedExists() {
|
||||
return checkedExists;
|
||||
}
|
||||
|
||||
public Set<String> getCheckedDirectory() {
|
||||
return checkedDirectory;
|
||||
}
|
||||
|
||||
public Set<String> getCheckedJarFileSystemRoots() {
|
||||
return checkedJarFileSystemRoots;
|
||||
}
|
||||
|
||||
public Set<String> getClassloaderPaths() {
|
||||
return classloaderPaths;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.test.collect;
|
||||
|
||||
import jdk.tools.jaotc.collect.SearchPath;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Set;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.set;
|
||||
|
||||
public class FakeSearchPath extends SearchPath {
|
||||
private Path path = null;
|
||||
public Set<String> entries = set();
|
||||
|
||||
public FakeSearchPath(String name) {
|
||||
if (name != null) {
|
||||
path = Paths.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path find(FileSystem fileSystem, Path entry, String... defaults) {
|
||||
entries.add(entry.toString());
|
||||
return path;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
*
|
||||
* @build jdk.tools.jaotc.test.collect.Utils
|
||||
* @build jdk.tools.jaotc.test.collect.FakeFileSupport
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.SearchPathTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test.collect;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.mkpath;
|
||||
import static jdk.tools.jaotc.test.collect.Utils.mkpaths;
|
||||
import static jdk.tools.jaotc.test.collect.Utils.set;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.tools.jaotc.collect.SearchPath;
|
||||
|
||||
public class SearchPathTest {
|
||||
private FakeFileSupport fileSupport;
|
||||
private FileSystem fs;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
fs = FileSystems.getDefault();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldUsePathIfPathIsAbsoluteAndExisting() {
|
||||
fileSupport = new FakeFileSupport(mkpaths("/foo"), set());
|
||||
SearchPath target = new SearchPath(fileSupport);
|
||||
Path foo = Paths.get(mkpath("/foo"));
|
||||
Path result = target.find(fs, foo);
|
||||
assertSame(result, foo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfPathIsAbsoluteAndNonExisting() {
|
||||
fileSupport = new FakeFileSupport(set(), set());
|
||||
SearchPath target = new SearchPath(fileSupport);
|
||||
Path result = target.find(fs, Paths.get(mkpath("/bar")));
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldUseRelativeExisting() {
|
||||
fileSupport = new FakeFileSupport(mkpaths("hello", "tmp/hello", "search/hello"), set());
|
||||
SearchPath target = new SearchPath(fileSupport);
|
||||
target.add("search");
|
||||
Path hello = Paths.get("hello");
|
||||
Path result = target.find(fs, hello, "tmp");
|
||||
assertSame(result, hello);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldSearchDefaultsBeforeSearchPaths() {
|
||||
fileSupport = new FakeFileSupport(mkpaths("bar/foobar"), set());
|
||||
SearchPath target = new SearchPath(fileSupport);
|
||||
Path result = target.find(fs, Paths.get("foobar"), "default1", "bar");
|
||||
assertEquals(mkpath("bar/foobar"), result.toString());
|
||||
assertEquals(mkpaths("foobar", "default1/foobar", "bar/foobar"), fileSupport.getCheckedExists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldUseSearchPathsIfNotInDefaults() {
|
||||
fileSupport = new FakeFileSupport(mkpaths("bar/tmp/foobar"), set());
|
||||
SearchPath target = new SearchPath(fileSupport);
|
||||
target.add("foo/tmp", "bar/tmp");
|
||||
|
||||
Path result = target.find(fs, Paths.get("foobar"), "foo", "bar");
|
||||
assertEquals(mkpath("bar/tmp/foobar"), result.toString());
|
||||
assertEquals(mkpaths("foobar", "foo/foobar", "bar/foobar", "bar/tmp/foobar", "foo/tmp/foobar"), fileSupport.getCheckedExists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfNoExistingPathIsFound() {
|
||||
fileSupport = new FakeFileSupport(set(), set());
|
||||
SearchPath target = new SearchPath(fileSupport);
|
||||
target.add("dir1", "dir2");
|
||||
|
||||
Path result = target.find(fs, Paths.get("entry"), "dir3", "dir4");
|
||||
assertNull(result);
|
||||
assertEquals(mkpaths("entry", "dir1/entry", "dir2/entry", "dir3/entry", "dir4/entry"), fileSupport.getCheckedExists());
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.test.collect;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class Utils {
|
||||
@SafeVarargs
|
||||
public static <T> Set<T> set(T... entries) {
|
||||
Set<T> set = new HashSet<>();
|
||||
for (T entry : entries) {
|
||||
set.add(entry);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static String mkpath(String path) {
|
||||
return getpath(path).toString();
|
||||
}
|
||||
|
||||
public static Set<String> mkpaths(String... paths) {
|
||||
Set<String> set = new HashSet<>();
|
||||
for (String entry : paths) {
|
||||
set.add(mkpath(entry));
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public static Path getpath(String path) {
|
||||
if (path.startsWith("/") && System.getProperty("os.name").startsWith("Windows")) {
|
||||
return Paths.get(new File(path).getAbsolutePath());
|
||||
} else {
|
||||
return Paths.get(path);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* jdk.aot/jdk.tools.jaotc.collect.directory
|
||||
* @compile ../Utils.java
|
||||
* @compile ../FakeFileSupport.java
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.directory.DirectorySourceProviderTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test.collect.directory;
|
||||
|
||||
import jdk.tools.jaotc.collect.ClassSource;
|
||||
import jdk.tools.jaotc.collect.directory.DirectorySourceProvider;
|
||||
import jdk.tools.jaotc.test.collect.FakeFileSupport;
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.set;
|
||||
|
||||
public class DirectorySourceProviderTest {
|
||||
@Test
|
||||
public void itShouldReturnNullForNonExistantPath() {
|
||||
DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set(), set()));
|
||||
ClassSource result = target.findSource("hello", null);
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullForNonDirectory() {
|
||||
DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set()));
|
||||
ClassSource result = target.findSource("foobar", null);
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullForMalformedURI() {
|
||||
Set<String> visited = set();
|
||||
DirectorySourceProvider target = new DirectorySourceProvider(new FakeFileSupport(set("foobar"), set("foobar")) {
|
||||
@Override
|
||||
public ClassLoader createClassLoader(Path path) throws MalformedURLException {
|
||||
visited.add("1");
|
||||
throw new MalformedURLException("...");
|
||||
}
|
||||
});
|
||||
ClassSource result = target.findSource("foobar", null);
|
||||
Assert.assertNull(result);
|
||||
Assert.assertEquals(set("1"), visited);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldCreateSourceIfNameExistsAndIsADirectory() {
|
||||
FileSupport fileSupport = new FakeFileSupport(set("foo"), set("foo"));
|
||||
DirectorySourceProvider target = new DirectorySourceProvider(fileSupport);
|
||||
ClassSource foo = target.findSource("foo", null);
|
||||
Assert.assertNotNull(foo);
|
||||
Assert.assertEquals("directory:foo", foo.toString());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* jdk.aot/jdk.tools.jaotc.collect.jar
|
||||
* @compile ../Utils.java
|
||||
* @compile ../FakeFileSupport.java
|
||||
* @compile ../FakeSearchPath.java
|
||||
*
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.jar.JarSourceProviderTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test.collect.jar;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.mkpath;
|
||||
import static jdk.tools.jaotc.test.collect.Utils.set;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.ProviderNotFoundException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.tools.jaotc.collect.ClassSource;
|
||||
import jdk.tools.jaotc.collect.jar.JarSourceProvider;
|
||||
import jdk.tools.jaotc.test.collect.FakeFileSupport;
|
||||
import jdk.tools.jaotc.test.collect.FakeSearchPath;
|
||||
|
||||
public class JarSourceProviderTest {
|
||||
|
||||
private FakeFileSupport fileSupport;
|
||||
private JarSourceProvider target;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
fileSupport = new FakeFileSupport(set(), set());
|
||||
target = new JarSourceProvider(fileSupport);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldUseSearchPathToFindPath() {
|
||||
FakeSearchPath searchPath = new FakeSearchPath(null);
|
||||
target.findSource("hello", searchPath);
|
||||
|
||||
Assert.assertEquals(set("hello"), searchPath.entries);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfPathIsNull() {
|
||||
ClassSource source = target.findSource("foobar", new FakeSearchPath(null));
|
||||
Assert.assertNull(source);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfPathIsDirectory() {
|
||||
fileSupport.addDirectory("hello/foobar");
|
||||
ClassSource source = target.findSource("foobar", new FakeSearchPath("hello/foobar"));
|
||||
|
||||
Assert.assertNull(source);
|
||||
Assert.assertEquals(set(mkpath("hello/foobar")), fileSupport.getCheckedDirectory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfUnableToMakeJarFileSystem() {
|
||||
fileSupport.setJarFileSystemRoot(null);
|
||||
ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar"));
|
||||
|
||||
Assert.assertEquals(set(mkpath("foo/bar")), fileSupport.getCheckedJarFileSystemRoots());
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnNullIfNotValidJarProvider() {
|
||||
fileSupport = new FakeFileSupport(set(), set()) {
|
||||
|
||||
@Override
|
||||
public Path getJarFileSystemRoot(Path jarFile) {
|
||||
super.getJarFileSystemRoot(jarFile);
|
||||
throw new ProviderNotFoundException();
|
||||
}
|
||||
};
|
||||
fileSupport.setJarFileSystemRoot(null);
|
||||
target = new JarSourceProvider(fileSupport);
|
||||
|
||||
ClassSource result = target.findSource("foobar", new FakeSearchPath("foo/bar"));
|
||||
|
||||
Assert.assertEquals(set(mkpath("foo/bar")), fileSupport.getCheckedJarFileSystemRoots());
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldReturnSourceWhenAllIsValid() {
|
||||
fileSupport.setJarFileSystemRoot(Paths.get("some/bar"));
|
||||
ClassSource result = target.findSource("foobar", new FakeSearchPath("this/bar"));
|
||||
|
||||
Assert.assertEquals(set(mkpath("this/bar")), fileSupport.getClassloaderPaths());
|
||||
Assert.assertEquals("jar:" + mkpath("this/bar"), result.toString());
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.aot
|
||||
* @modules jdk.aot/jdk.tools.jaotc
|
||||
* jdk.aot/jdk.tools.jaotc.collect
|
||||
* jdk.aot/jdk.tools.jaotc.collect.module
|
||||
* @compile ../Utils.java
|
||||
* @run junit/othervm jdk.tools.jaotc.test.collect.module.ModuleSourceProviderTest
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.test.collect.module;
|
||||
|
||||
import static jdk.tools.jaotc.test.collect.Utils.mkpath;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.tools.jaotc.collect.FileSupport;
|
||||
import jdk.tools.jaotc.collect.module.ModuleSource;
|
||||
import jdk.tools.jaotc.collect.module.ModuleSourceProvider;
|
||||
|
||||
public class ModuleSourceProviderTest {
|
||||
private ClassLoader classLoader;
|
||||
private ModuleSourceProvider target;
|
||||
private FileSupport fileSupport;
|
||||
private BiFunction<Path, Path, Path> getSubDirectory = null;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
classLoader = new FakeClassLoader();
|
||||
fileSupport = new FileSupport() {
|
||||
|
||||
@Override
|
||||
public boolean isDirectory(Path path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getSubDirectory(FileSystem fileSystem, Path root, Path path) throws IOException {
|
||||
if (getSubDirectory == null) {
|
||||
throw new IOException("Nope");
|
||||
}
|
||||
return getSubDirectory.apply(root, path);
|
||||
}
|
||||
};
|
||||
target = new ModuleSourceProvider(FileSystems.getDefault(), classLoader, fileSupport);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void itShouldUseFileSupport() {
|
||||
getSubDirectory = (root, path) -> {
|
||||
if (root.toString().equals("modules") && path.toString().equals("test.module")) {
|
||||
return Paths.get("modules/test.module");
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
ModuleSource source = (ModuleSource) target.findSource("test.module", null);
|
||||
assertEquals(mkpath("modules/test.module"), source.getModulePath().toString());
|
||||
assertEquals("module:" + mkpath("modules/test.module"), source.toString());
|
||||
}
|
||||
|
||||
private static class FakeClassLoader extends ClassLoader {
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.ListIterator;
|
||||
@ -28,7 +30,6 @@ import java.util.ListIterator;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.core.GraalCompiler;
|
||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||
import org.graalvm.compiler.core.common.CompilationIdentifier.Verbosity;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.hotspot.HotSpotBackend;
|
||||
import org.graalvm.compiler.hotspot.HotSpotCompiledCodeBuilder;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -87,6 +89,7 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
/**
|
||||
* Compile a method or a constructor.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("try")
|
||||
public void run() {
|
||||
// Ensure a JVMCI runtime is initialized prior to Debug being initialized as the former
|
||||
@ -186,12 +189,15 @@ final class AOTCompilationTask implements Runnable, Comparable<Object> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (obj == null)
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AOTCompilationTask other = (AOTCompilationTask) obj;
|
||||
return (this.id == other.id);
|
||||
}
|
||||
|
@ -21,27 +21,27 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.tools.jaotc.AOTDynamicTypeStore.AdapterLocation;
|
||||
import jdk.tools.jaotc.AOTDynamicTypeStore.AppendixLocation;
|
||||
import jdk.tools.jaotc.AOTDynamicTypeStore.Location;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Binding;
|
||||
import jdk.tools.jaotc.binformat.Symbol.Kind;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
import jdk.vm.ci.meta.ResolvedJavaField;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
|
||||
import jdk.tools.jaotc.AOTDynamicTypeStore.AdapterLocation;
|
||||
import jdk.tools.jaotc.AOTDynamicTypeStore.AppendixLocation;
|
||||
import jdk.tools.jaotc.AOTDynamicTypeStore.Location;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -74,7 +74,7 @@ final class AOTCompiledClass {
|
||||
this.dependentMethods = new ArrayList<>();
|
||||
this.classId = classId;
|
||||
this.type = type;
|
||||
this.metadataName = type.isAnonymous() ? "anon<"+ classId + ">": type.getName();
|
||||
this.metadataName = type.isAnonymous() ? "anon<" + classId + ">" : type.getName();
|
||||
this.gotIndex = binaryContainer.addTwoSlotKlassSymbol(metadataName);
|
||||
this.compiledMethodsOffset = -1; // Not compiled classes do not have compiled methods.
|
||||
this.dependentMethodsOffset = -1;
|
||||
@ -84,9 +84,9 @@ final class AOTCompiledClass {
|
||||
String name = metadataName;
|
||||
Set<Location> locs = dynoStore.getDynamicClassLocationsForType(type);
|
||||
if (locs == null) {
|
||||
return new String[] {name};
|
||||
return new String[]{name};
|
||||
} else {
|
||||
ArrayList<String> names = new ArrayList<String>();
|
||||
ArrayList<String> names = new ArrayList<>();
|
||||
names.add(name);
|
||||
for (Location l : locs) {
|
||||
HotSpotResolvedObjectType cpType = l.getHolder();
|
||||
@ -95,14 +95,14 @@ final class AOTCompiledClass {
|
||||
// may record types that don't make it into the final graph.
|
||||
// We can safely ignore those here.
|
||||
if (data == null) {
|
||||
// Not a compiled or inlined method
|
||||
continue;
|
||||
// Not a compiled or inlined method
|
||||
continue;
|
||||
}
|
||||
int cpi = l.getCpi();
|
||||
String location = "<"+ data.classId + ":" + cpi + ">";
|
||||
String location = "<" + data.classId + ":" + cpi + ">";
|
||||
if (l instanceof AdapterLocation) {
|
||||
names.add("adapter" + location);
|
||||
AdapterLocation a = (AdapterLocation)l;
|
||||
AdapterLocation a = (AdapterLocation) l;
|
||||
names.add("adapter:" + a.getMethodId() + location);
|
||||
} else {
|
||||
assert l instanceof AppendixLocation;
|
||||
@ -319,26 +319,23 @@ final class AOTCompiledClass {
|
||||
/**
|
||||
* Add a klass data.
|
||||
*/
|
||||
synchronized static AOTKlassData addAOTKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
String name = type.getName();
|
||||
AOTKlassData data = klassData.get(name);
|
||||
if (data != null) {
|
||||
assert data.getType() == type : "duplicate classes for name " + name;
|
||||
} else {
|
||||
static synchronized AOTKlassData addAOTKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
AOTKlassData data = getAOTKlassData(type);
|
||||
if (data == null) {
|
||||
data = new AOTKlassData(binaryContainer, type, classesCount++);
|
||||
klassData.put(name, data);
|
||||
klassData.put(type.getName(), data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private synchronized static AOTKlassData getAOTKlassData(String name) {
|
||||
return klassData.get(name);
|
||||
}
|
||||
|
||||
synchronized static AOTKlassData getAOTKlassData(HotSpotResolvedObjectType type) {
|
||||
static synchronized AOTKlassData getAOTKlassData(HotSpotResolvedObjectType type) {
|
||||
String name = type.getName();
|
||||
AOTKlassData data = getAOTKlassData(name);
|
||||
assert data == null || data.getType() == type : "duplicate classes for name " + name;
|
||||
AOTKlassData data = klassData.get(name);
|
||||
if (data != null) {
|
||||
HotSpotResolvedObjectType oldType = data.getType();
|
||||
assert oldType == type : "duplicate classes for name " + type.getName() + ", fingerprints old: " + oldType.getFingerprint() + ", new: " + type.getFingerprint() +
|
||||
", klass pointers old: " + oldType.klass() + ", new: " + type.klass();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -363,17 +360,14 @@ final class AOTCompiledClass {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized static AOTKlassData addFingerprintKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
static synchronized AOTKlassData addFingerprintKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
|
||||
if (type.isArray()) {
|
||||
return addAOTKlassData(binaryContainer, type);
|
||||
}
|
||||
assert type.getFingerprint() != 0 : "no fingerprint for " + type.getName();
|
||||
AOTKlassData old = getAOTKlassData(type);
|
||||
if (old != null) {
|
||||
boolean assertsEnabled = false;
|
||||
// Next assignment will be executed when asserts are enabled.
|
||||
assert assertsEnabled = true;
|
||||
if (assertsEnabled) {
|
||||
if (areAssertionsEnabled()) {
|
||||
HotSpotResolvedObjectType s = type.getSuperclass();
|
||||
if (s != null) {
|
||||
assert getAOTKlassData(s) != null : "fingerprint for super " + s.getName() + " needed for " + type.getName();
|
||||
@ -397,6 +391,14 @@ final class AOTCompiledClass {
|
||||
return addAOTKlassData(binaryContainer, type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
private static boolean areAssertionsEnabled() {
|
||||
boolean assertsEnabled = false;
|
||||
// Next assignment will be executed when asserts are enabled.
|
||||
assert assertsEnabled = true;
|
||||
return assertsEnabled;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put methods data to contained.
|
||||
*/
|
||||
@ -431,9 +433,7 @@ final class AOTCompiledClass {
|
||||
}
|
||||
|
||||
static HotSpotResolvedObjectType getType(Object ref) {
|
||||
return (ref instanceof HotSpotResolvedObjectType) ?
|
||||
(HotSpotResolvedObjectType)ref :
|
||||
((HotSpotResolvedJavaMethod)ref).getDeclaringClass();
|
||||
return (ref instanceof HotSpotResolvedObjectType) ? (HotSpotResolvedObjectType) ref : ((HotSpotResolvedJavaMethod) ref).getDeclaringClass();
|
||||
}
|
||||
|
||||
static String metadataName(HotSpotResolvedObjectType type) {
|
||||
@ -448,11 +448,11 @@ final class AOTCompiledClass {
|
||||
|
||||
static String metadataName(Object ref) {
|
||||
if (ref instanceof HotSpotResolvedJavaMethod) {
|
||||
HotSpotResolvedJavaMethod m = (HotSpotResolvedJavaMethod)ref;
|
||||
HotSpotResolvedJavaMethod m = (HotSpotResolvedJavaMethod) ref;
|
||||
return metadataName(m);
|
||||
} else {
|
||||
assert ref instanceof HotSpotResolvedObjectType : "unexpected object type " + ref.getClass().getName();
|
||||
HotSpotResolvedObjectType type = (HotSpotResolvedObjectType)ref;
|
||||
HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ref;
|
||||
return metadataName(type);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -20,32 +20,23 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin.DynamicTypeStore;
|
||||
import org.graalvm.compiler.nodes.ConstantNode;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
import org.graalvm.compiler.nodes.ValueNode;
|
||||
import org.graalvm.compiler.nodes.graphbuilderconf.InvokeDynamicPlugin;
|
||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantPool;
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantPoolObject;
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
|
||||
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
import jdk.vm.ci.meta.ConstantPool;
|
||||
import jdk.vm.ci.meta.ConstantReflectionProvider;
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin.DynamicTypeStore;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantPool;
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantPoolObject;
|
||||
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
import jdk.vm.ci.meta.JavaConstant;
|
||||
|
||||
final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
|
||||
public static class Location {
|
||||
@ -60,15 +51,22 @@ final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
public HotSpotResolvedObjectType getHolder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
public int getCpi() {
|
||||
return cpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getHolder().getName() + "@" + cpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return holder.hashCode() + getClass().hashCode() + cpi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
@ -76,7 +74,7 @@ final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
if (getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Location l = (Location)o;
|
||||
Location l = (Location) o;
|
||||
return cpi == l.cpi && holder.equals(l.holder);
|
||||
}
|
||||
}
|
||||
@ -88,9 +86,12 @@ final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
super(holder, cpi);
|
||||
this.methodId = methodId;
|
||||
}
|
||||
|
||||
public int getMethodId() {
|
||||
return methodId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "adapter:" + methodId + "@" + super.toString();
|
||||
}
|
||||
@ -100,6 +101,8 @@ final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
AppendixLocation(HotSpotResolvedObjectType holder, int cpi) {
|
||||
super(holder, cpi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "appendix@" + super.toString();
|
||||
}
|
||||
@ -122,7 +125,7 @@ final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
|
||||
@Override
|
||||
public void recordAdapter(int opcode, HotSpotResolvedObjectType holder, int index, HotSpotResolvedJavaMethod adapter) {
|
||||
int cpi = ((HotSpotConstantPool)holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode);
|
||||
int cpi = ((HotSpotConstantPool) holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode);
|
||||
int methodId = adapter.methodIdnum();
|
||||
HotSpotResolvedObjectType adapterType = adapter.getDeclaringClass();
|
||||
recordDynamicTypeLocation(new AdapterLocation(holder, cpi, methodId), adapterType);
|
||||
@ -130,8 +133,8 @@ final class AOTDynamicTypeStore implements DynamicTypeStore {
|
||||
|
||||
@Override
|
||||
public JavaConstant recordAppendix(int opcode, HotSpotResolvedObjectType holder, int index, JavaConstant appendix) {
|
||||
int cpi = ((HotSpotConstantPool)holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode);
|
||||
HotSpotResolvedObjectType appendixType = ((HotSpotObjectConstant)appendix).getType();
|
||||
int cpi = ((HotSpotConstantPool) holder.getConstantPool()).rawIndexToConstantPoolIndex(index, opcode);
|
||||
HotSpotResolvedObjectType appendixType = ((HotSpotObjectConstant) appendix).getType();
|
||||
recordDynamicTypeLocation(new AppendixLocation(holder, cpi), appendixType);
|
||||
// Make the constant locatable
|
||||
return HotSpotConstantPoolObject.forObject(holder, cpi, appendix);
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
@ -39,15 +41,18 @@ final class AOTHotSpotResolvedJavaMethod implements JavaMethodInfo {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSymbolName() {
|
||||
return JavaMethodInfo.uniqueMethodName(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameAndSignature() {
|
||||
String className = method.getDeclaringClass().getName();
|
||||
return className + "." + method.getName() + method.getSignature().toMethodDescriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HotSpotCompiledCode compiledCode(CompilationResult result) {
|
||||
return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), method, null, result);
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
@ -40,14 +42,17 @@ final class AOTStub implements JavaMethodInfo {
|
||||
this.backend = backend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSymbolName() {
|
||||
return stub.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameAndSignature() {
|
||||
return stub.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HotSpotCompiledCode compiledCode(CompilationResult result) {
|
||||
return HotSpotCompiledCodeBuilder.createCompiledCode(backend.getCodeCache(), null, null, result);
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import org.graalvm.compiler.bytecode.Bytecodes;
|
||||
@ -33,7 +35,7 @@ import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
final class CallInfo {
|
||||
|
||||
static boolean isStaticTarget(Call call) {
|
||||
return !((HotSpotResolvedJavaMethod)call.target).hasReceiver();
|
||||
return !((HotSpotResolvedJavaMethod) call.target).hasReceiver();
|
||||
}
|
||||
|
||||
private static boolean isStaticOpcode(Call call) {
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -21,18 +21,18 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
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.StubInformation;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
|
||||
|
||||
import jdk.vm.ci.aarch64.AArch64;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.CodeContainer;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.vm.ci.amd64.AMD64;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
import jdk.vm.ci.code.site.Call;
|
||||
@ -75,7 +75,7 @@ final class CodeSectionProcessor {
|
||||
if (infopoint.reason == InfopointReason.CALL) {
|
||||
final Call callInfopoint = (Call) infopoint;
|
||||
if (callInfopoint.target instanceof HotSpotForeignCallLinkage &&
|
||||
target.arch instanceof AMD64) {
|
||||
target.arch instanceof AMD64) {
|
||||
// TODO 4 is x86 size of relative displacement.
|
||||
// For SPARC need something different.
|
||||
int destOffset = infopoint.pcOffset + callInfopoint.size - 4;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -147,7 +149,7 @@ final class CompiledMethodInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method name
|
||||
* Method name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -21,21 +21,22 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
import org.graalvm.compiler.code.DataSection;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.Relocation;
|
||||
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;
|
||||
import org.graalvm.compiler.code.DataSection;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotConstantLoadAction;
|
||||
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
import jdk.vm.ci.code.site.ConstantReference;
|
||||
import jdk.vm.ci.code.site.DataPatch;
|
||||
@ -97,7 +98,7 @@ final class DataPatchProcessor {
|
||||
} else if (constant instanceof HotSpotObjectConstant) {
|
||||
HotSpotObjectConstant oopConstant = (HotSpotObjectConstant) constant;
|
||||
if (oopConstant instanceof HotSpotConstantPoolObject) {
|
||||
HotSpotConstantPoolObject cpo = (HotSpotConstantPoolObject)oopConstant;
|
||||
HotSpotConstantPoolObject cpo = (HotSpotConstantPoolObject) oopConstant;
|
||||
// Even if two locations use the same object, resolve separately
|
||||
targetSymbol = "ldc." + cpo.getCpType().getName() + cpo.getCpi();
|
||||
} else {
|
||||
|
@ -21,20 +21,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.StubInformation;
|
||||
import jdk.tools.jaotc.amd64.AMD64ELFMacroAssembler;
|
||||
import jdk.tools.jaotc.aarch64.AArch64ELFMacroAssembler;
|
||||
|
||||
import jdk.vm.ci.amd64.AMD64;
|
||||
import jdk.tools.jaotc.amd64.AMD64ELFMacroAssembler;
|
||||
import jdk.vm.ci.aarch64.AArch64;
|
||||
import jdk.vm.ci.amd64.AMD64;
|
||||
import jdk.vm.ci.code.Architecture;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
|
||||
public interface ELFMacroAssembler {
|
||||
|
||||
public static ELFMacroAssembler getELFMacroAssembler(TargetDescription target) {
|
||||
static ELFMacroAssembler getELFMacroAssembler(TargetDescription target) {
|
||||
Architecture architecture = target.arch;
|
||||
if (architecture instanceof AMD64) {
|
||||
return new AMD64ELFMacroAssembler(target);
|
||||
@ -45,12 +45,12 @@ public interface ELFMacroAssembler {
|
||||
}
|
||||
}
|
||||
|
||||
public int currentEndOfInstruction();
|
||||
int currentEndOfInstruction();
|
||||
|
||||
public byte[] getPLTJumpCode();
|
||||
byte[] getPLTJumpCode();
|
||||
|
||||
public byte[] getPLTStaticEntryCode(StubInformation stub);
|
||||
byte[] getPLTStaticEntryCode(StubInformation stub);
|
||||
|
||||
public byte[] getPLTVirtualEntryCode(StubInformation stub);
|
||||
byte[] getPLTVirtualEntryCode(StubInformation stub);
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
@ -30,12 +32,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantPool;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
|
||||
import org.graalvm.compiler.api.directives.GraalDirectives;
|
||||
import org.graalvm.compiler.api.replacements.ClassSubstitution;
|
||||
import org.graalvm.compiler.api.replacements.MethodSubstitution;
|
||||
@ -47,6 +43,12 @@ import org.graalvm.compiler.hotspot.word.MetaspacePointer;
|
||||
import org.graalvm.compiler.replacements.Snippets;
|
||||
import jdk.internal.vm.compiler.word.WordBase;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
|
||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.meta.ResolvedJavaType;
|
||||
import jdk.vm.ci.hotspot.HotSpotConstantPool;
|
||||
|
||||
final class GraalFilters {
|
||||
private List<ResolvedJavaType> specialClasses;
|
||||
private List<ResolvedJavaType> specialArgumentAndReturnTypes;
|
||||
@ -90,7 +92,7 @@ final class GraalFilters {
|
||||
return false;
|
||||
}
|
||||
// Skip klass with Condy until Graal is fixed.
|
||||
if (((HotSpotConstantPool)((HotSpotResolvedObjectType) klass).getConstantPool()).hasDynamicConstant()) {
|
||||
if (((HotSpotConstantPool) ((HotSpotResolvedObjectType) klass).getConstantPool()).hasDynamicConstant()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.amd64.AMD64InstructionDecoder;
|
||||
@ -38,13 +40,13 @@ public abstract class InstructionDecoder {
|
||||
if (architecture instanceof AMD64) {
|
||||
return new AMD64InstructionDecoder(target);
|
||||
} else if (architecture instanceof AArch64) {
|
||||
return new AArch64InstructionDecoder(target);
|
||||
return new AArch64InstructionDecoder();
|
||||
} else {
|
||||
throw new InternalError("Unsupported architecture " + architecture);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void decodePosition(final byte[] code, int pcOffset);
|
||||
public abstract void decodePosition(byte[] code, int pcOffset);
|
||||
|
||||
public abstract int currentEndOfInstruction();
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.Relocation.RelocType;
|
||||
|
@ -21,12 +21,12 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.binformat.Symbol;
|
||||
import jdk.tools.jaotc.StubInformation;
|
||||
|
||||
import jdk.vm.ci.code.site.Call;
|
||||
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
|
||||
|
||||
@ -44,11 +44,11 @@ final class JavaCallSiteRelocationSymbol extends CallSiteRelocationSymbol {
|
||||
String archStr = System.getProperty("os.arch").toLowerCase();
|
||||
if (archStr.equals("aarch64")) {
|
||||
// AArch64 is a special case: it uses 48-bit addresses.
|
||||
byte[] non_oop_word = {-1, -1, -1, -1, -1, -1, 0, 0};
|
||||
minusOneSlot = non_oop_word;
|
||||
byte[] nonOopWord = {-1, -1, -1, -1, -1, -1, 0, 0};
|
||||
minusOneSlot = nonOopWord;
|
||||
} else {
|
||||
byte[] non_oop_word = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
minusOneSlot = non_oop_word;
|
||||
byte[] nonOopWord = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
minusOneSlot = nonOopWord;
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +135,6 @@ final class JavaCallSiteRelocationSymbol extends CallSiteRelocationSymbol {
|
||||
*/
|
||||
private static String getResolveSymbolName(CompiledMethodInfo mi, Call call) {
|
||||
String resolveSymbolName;
|
||||
String name = call.target.toString();
|
||||
if (CallInfo.isStaticCall(call)) {
|
||||
assert mi.hasMark(call, MarkId.INVOKESTATIC);
|
||||
resolveSymbolName = BinaryContainer.getResolveStaticEntrySymbolName();
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -148,32 +150,7 @@ final class Linker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Visual Studio supported versions Search Order is: VS2013, VS2015, VS2012
|
||||
*/
|
||||
public enum VSVERSIONS {
|
||||
VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"),
|
||||
VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"),
|
||||
VS2012("VS110COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe");
|
||||
|
||||
private final String envvariable;
|
||||
private final String wkp;
|
||||
|
||||
VSVERSIONS(String envvariable, String wellknownpath) {
|
||||
this.envvariable = envvariable;
|
||||
this.wkp = wellknownpath;
|
||||
}
|
||||
|
||||
String EnvVariable() {
|
||||
return envvariable;
|
||||
}
|
||||
|
||||
String WellKnownPath() {
|
||||
return wkp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for Visual Studio link.exe Search Order is: VS2013, VS2015, VS2012
|
||||
* Search for Visual Studio link.exe Search Order is: VS2013, VS2015, VS2012.
|
||||
*/
|
||||
private static String getWindowsLinkPath() {
|
||||
String link = "\\VC\\bin\\amd64\\link.exe";
|
||||
@ -182,7 +159,7 @@ final class Linker {
|
||||
* First try searching the paths pointed to by the VS environment variables.
|
||||
*/
|
||||
for (VSVERSIONS vs : VSVERSIONS.values()) {
|
||||
String vspath = System.getenv(vs.EnvVariable());
|
||||
String vspath = System.getenv(vs.getEnvVariable());
|
||||
if (vspath != null) {
|
||||
File commonTools = new File(vspath);
|
||||
File vsRoot = commonTools.getParentFile().getParentFile();
|
||||
@ -197,7 +174,7 @@ final class Linker {
|
||||
* If we didn't find via the VS environment variables, try the well known paths
|
||||
*/
|
||||
for (VSVERSIONS vs : VSVERSIONS.values()) {
|
||||
String wkp = vs.WellKnownPath();
|
||||
String wkp = vs.getWellKnownPath();
|
||||
if (new File(wkp).exists()) {
|
||||
return wkp;
|
||||
}
|
||||
@ -206,4 +183,30 @@ final class Linker {
|
||||
return null;
|
||||
}
|
||||
|
||||
// @formatter:off (workaround for Eclipse formatting bug)
|
||||
/**
|
||||
* Visual Studio supported versions Search Order is: VS2013, VS2015, VS2012.
|
||||
*/
|
||||
enum VSVERSIONS {
|
||||
VS2013("VS120COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64\\link.exe"),
|
||||
VS2015("VS140COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\bin\\amd64\\link.exe"),
|
||||
VS2012("VS110COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\bin\\amd64\\link.exe");
|
||||
|
||||
private final String envvariable;
|
||||
private final String wkp;
|
||||
|
||||
VSVERSIONS(String envvariable, String wellknownpath) {
|
||||
this.envvariable = envvariable;
|
||||
this.wkp = wellknownpath;
|
||||
}
|
||||
|
||||
String getEnvVariable() {
|
||||
return envvariable;
|
||||
}
|
||||
|
||||
String getWellKnownPath() {
|
||||
return wkp;
|
||||
}
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
public class LoadedClass {
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.io.FileWriter;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
||||
@ -33,9 +35,6 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.tools.jaotc.Options.Option;
|
||||
|
||||
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
|
||||
import org.graalvm.compiler.api.runtime.GraalJVMCICompiler;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
@ -45,7 +44,6 @@ import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalCompilerFactory;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalOptionValues;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntime.HotSpotGC;
|
||||
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotInvokeDynamicPlugin;
|
||||
import org.graalvm.compiler.java.GraphBuilderPhase;
|
||||
@ -57,6 +55,8 @@ import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||
import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
|
||||
import org.graalvm.compiler.runtime.RuntimeProvider;
|
||||
|
||||
import jdk.tools.jaotc.Options.Option;
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
import jdk.vm.ci.meta.MetaAccessProvider;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import jdk.vm.ci.runtime.JVMCI;
|
||||
@ -182,7 +182,7 @@ public final class Main {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
int gc = runtime.getGarbageCollector().ordinal()+1;
|
||||
int gc = runtime.getGarbageCollector().ordinal() + 1;
|
||||
BinaryContainer binaryContainer = new BinaryContainer(graalOptions, graalHotSpotVMConfig, graphBuilderConfig, gc, JVM_VERSION);
|
||||
DataBuilder dataBuilder = new DataBuilder(this, backend, classes, binaryContainer);
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||
@ -55,7 +57,7 @@ enum MarkId {
|
||||
|
||||
private final int value;
|
||||
|
||||
private MarkId(String name) {
|
||||
MarkId(String name) {
|
||||
this.value = (int) (long) HotSpotJVMCIRuntime.runtime().getConfigStore().getConstants().get(name);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -33,7 +35,6 @@ import jdk.tools.jaotc.utils.NativeOrderOutputStream;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
|
||||
|
||||
|
||||
import jdk.vm.ci.code.StackSlot;
|
||||
import jdk.vm.ci.code.site.DataPatch;
|
||||
import jdk.vm.ci.code.site.Infopoint;
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
@ -255,7 +257,8 @@ final class Options {
|
||||
}
|
||||
|
||||
// Make checkstyle happy.
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
int i = 0;
|
||||
while (i < args.length) {
|
||||
String arg = args[i];
|
||||
|
||||
if (arg.charAt(0) == '-') {
|
||||
@ -282,6 +285,7 @@ final class Options {
|
||||
} else {
|
||||
task.options.files.add(new SearchFor(arg));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
import jdk.tools.jaotc.binformat.BinaryContainer;
|
||||
|
@ -21,15 +21,20 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
public final class StubInformation {
|
||||
private int stubOffset; // the offset inside the code (text + stubOffset)
|
||||
private int stubSize; // the stub size
|
||||
private int dispatchJumpOffset; // offset after main dispatch jump instruction
|
||||
private int resolveJumpOffset; // offset after jump instruction to runtime call resolution function.
|
||||
private int resolveJumpStart; // offset of jump instruction to VM runtime call resolution function.
|
||||
private int c2iJumpOffset; // offset after jump instruction to c2i adapter for static calls.
|
||||
private int resolveJumpOffset; // offset after jump instruction to runtime call resolution
|
||||
// function.
|
||||
private int resolveJumpStart; // offset of jump instruction to VM runtime call resolution
|
||||
// function.
|
||||
private int c2iJumpOffset; // offset after jump instruction to c2i adapter for static
|
||||
// calls.
|
||||
private int movOffset; // offset after move instruction which loads from got cell:
|
||||
// - Method* for static call
|
||||
// - Klass* for virtual call
|
||||
|
@ -21,6 +21,8 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc;
|
||||
|
||||
final class Timer implements AutoCloseable {
|
||||
@ -34,6 +36,7 @@ final class Timer implements AutoCloseable {
|
||||
main.printer.printInfo(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
final long end = System.currentTimeMillis();
|
||||
main.printer.printlnInfo(" (" + (end - start) + " ms)");
|
||||
|
@ -22,19 +22,21 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package jdk.tools.jaotc.aarch64;
|
||||
|
||||
import jdk.tools.jaotc.StubInformation;
|
||||
import jdk.tools.jaotc.ELFMacroAssembler;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r12;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r16;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r17;
|
||||
import static jdk.vm.ci.aarch64.AArch64.r9;
|
||||
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64Address;
|
||||
import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
|
||||
|
||||
|
||||
import jdk.tools.jaotc.ELFMacroAssembler;
|
||||
import jdk.tools.jaotc.StubInformation;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
import jdk.vm.ci.code.Register;
|
||||
|
||||
import static jdk.vm.ci.aarch64.AArch64.*;
|
||||
|
||||
public final class AArch64ELFMacroAssembler extends AArch64MacroAssembler implements ELFMacroAssembler {
|
||||
|
||||
@ -71,7 +73,7 @@ public final class AArch64ELFMacroAssembler extends AArch64MacroAssembler implem
|
||||
jmp(r16);
|
||||
stub.setDispatchJumpOffset(position());
|
||||
|
||||
// C2I stub used to call interpreter. First load r12
|
||||
// C2I stub used to call interpreter. First load r12
|
||||
// (i.e. rmethod) with a pointer to the Method structure ...
|
||||
addressOf(r12);
|
||||
ldr(64, r12, AArch64Address.createBaseRegisterOnlyAddress(r12));
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user