summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/linker/oat_writer.cc11
-rw-r--r--runtime/arch/arm/asm_support_arm.S15
-rw-r--r--runtime/arch/arm/quick_entrypoints_arm.S3
-rw-r--r--runtime/arch/arm64/asm_support_arm64.S14
-rw-r--r--runtime/arch/arm64/quick_entrypoints_arm64.S3
-rw-r--r--runtime/arch/x86/asm_support_x86.S6
-rw-r--r--runtime/arch/x86_64/asm_support_x86_64.S6
-rw-r--r--runtime/oat_quick_method_header.h4
8 files changed, 46 insertions, 16 deletions
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index 6b2388337a..3c496341f9 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -2194,7 +2194,8 @@ size_t OatWriter::InitOatCode(size_t offset) {
size_t adjusted_offset = offset;
#define DO_TRAMPOLINE(field, fn_name) \
- offset = CompiledCode::AlignCode(offset, instruction_set); \
+ /* Pad with at least four 0xFFs so we can do DCHECKs in OatQuickMethodHeader */ \
+ offset = CompiledCode::AlignCode(offset + 4, instruction_set); \
adjusted_offset = offset + CompiledCode::CodeDelta(instruction_set); \
oat_header_->Set ## fn_name ## Offset(adjusted_offset); \
(field) = compiler_driver_->Create ## fn_name(); \
@@ -3070,9 +3071,13 @@ size_t OatWriter::WriteCode(OutputStream* out, size_t file_offset, size_t relati
#define DO_TRAMPOLINE(field) \
do { \
- uint32_t aligned_offset = CompiledCode::AlignCode(relative_offset, instruction_set); \
+ /* Pad with at least four 0xFFs so we can do DCHECKs in OatQuickMethodHeader */ \
+ uint32_t aligned_offset = CompiledCode::AlignCode(relative_offset + 4, instruction_set); \
uint32_t alignment_padding = aligned_offset - relative_offset; \
- out->Seek(alignment_padding, kSeekCurrent); \
+ for (size_t i = 0; i < alignment_padding; i++) { \
+ uint8_t padding = 0xFF; \
+ out->WriteFully(&padding, 1); \
+ } \
size_trampoline_alignment_ += alignment_padding; \
if (!out->WriteFully((field)->data(), (field)->size())) { \
PLOG(ERROR) << "Failed to write " # field " to " << out->GetLocation(); \
diff --git a/runtime/arch/arm/asm_support_arm.S b/runtime/arch/arm/asm_support_arm.S
index eeac743df2..633591d6e6 100644
--- a/runtime/arch/arm/asm_support_arm.S
+++ b/runtime/arch/arm/asm_support_arm.S
@@ -54,7 +54,7 @@
// Common ENTRY declaration code for ARM and thumb, an ENTRY should always be paired with an END.
// Declares the RUNTIME_CURRENT[123] macros that can be used within an ENTRY and will have literals
// generated at END.
-.macro DEF_ENTRY thumb_or_arm, name
+.macro DEF_ENTRY thumb_or_arm, name, alignment
\thumb_or_arm
// Clang ignores .thumb_func and requires an explicit .thumb. Investigate whether we should still
// carry around the .thumb_func.
@@ -64,8 +64,12 @@
.type \name, #function
.hidden \name // Hide this as a global symbol, so we do not incur plt calls.
.global \name
+ // ART-compiled functions have OatQuickMethodHeader but assembly funtions do not.
+ // Prefix the assembly code with 0xFFs, which means there is no method header.
+ .byte 0xFF, 0xFF, 0xFF, 0xFF
// Cache alignment for function entry.
- .balign 16
+ // NB: 0xFF because there is a bug in balign where 0x00 creates nop instructions.
+ .balign \alignment, 0xFF
\name:
.cfi_startproc
.fnstart
@@ -88,12 +92,15 @@
// A thumb2 style ENTRY.
.macro ENTRY name
- DEF_ENTRY .thumb_func, \name
+ DEF_ENTRY .thumb_func, \name, 16
+.endm
+.macro ENTRY_ALIGNED name, alignment
+ DEF_ENTRY .thumb_func, \name, \alignment
.endm
// A ARM style ENTRY.
.macro ARM_ENTRY name
- DEF_ENTRY .arm, \name
+ DEF_ENTRY .arm, \name, 16
.endm
// Terminate an ENTRY and generate GOT_PREL references.
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 1153a772ee..345044448a 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -2624,8 +2624,7 @@ art_quick_read_barrier_mark_introspection_gc_roots\label_suffix:
* (6 bytes). Loads the return register and jumps to the runtime call.
*/
#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER)
- .balign 512
-ENTRY art_quick_read_barrier_mark_introspection
+ENTRY_ALIGNED art_quick_read_barrier_mark_introspection, 512
// At this point, IP contains the reference, rMR is clobbered by the thunk
// and can be freely used as it will be set back to 1 before returning.
// For heap poisoning, the reference is poisoned, so unpoison it first.
diff --git a/runtime/arch/arm64/asm_support_arm64.S b/runtime/arch/arm64/asm_support_arm64.S
index 715fc35ff4..3eb0991a63 100644
--- a/runtime/arch/arm64/asm_support_arm64.S
+++ b/runtime/arch/arm64/asm_support_arm64.S
@@ -40,16 +40,24 @@
#define wMR w20
#endif
-.macro ENTRY name
+.macro ENTRY_ALIGNED name, alignment
.type \name, #function
.hidden \name // Hide this as a global symbol, so we do not incur plt calls.
.global \name
- /* Cache alignment for function entry */
- .balign 16
+ // ART-compiled functions have OatQuickMethodHeader but assembly funtions do not.
+ // Prefix the assembly code with 0xFFs, which means there is no method header.
+ .byte 0xFF, 0xFF, 0xFF, 0xFF
+ // Cache alignment for function entry.
+ // NB: 0xFF because there is a bug in balign where 0x00 creates nop instructions.
+ .balign \alignment, 0xFF
\name:
.cfi_startproc
.endm
+.macro ENTRY name
+ ENTRY_ALIGNED \name, 16
+.endm
+
.macro END name
.cfi_endproc
.size \name, .-\name
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 9f3377ed1e..5945c45e29 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -2790,8 +2790,7 @@ READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg29, w29, x29
* art_quick_read_barrier_mark_introspection_gc_roots:
* GC root entrypoint code.
*/
- .balign 512
-ENTRY art_quick_read_barrier_mark_introspection
+ENTRY_ALIGNED art_quick_read_barrier_mark_introspection, 512
// At this point, IP0 contains the reference, IP1 can be freely used.
// For heap poisoning, the reference is poisoned, so unpoison it first.
UNPOISON_HEAP_REF wIP0
diff --git a/runtime/arch/x86/asm_support_x86.S b/runtime/arch/x86/asm_support_x86.S
index c9514f5f27..cd5ebd755c 100644
--- a/runtime/arch/x86/asm_support_x86.S
+++ b/runtime/arch/x86/asm_support_x86.S
@@ -113,7 +113,11 @@
/* Cache alignment for function entry */
MACRO0(ALIGN_FUNCTION_ENTRY)
- .balign 16
+ // ART-compiled functions have OatQuickMethodHeader but assembly funtions do not.
+ // Prefix the assembly code with 0xFFs, which means there is no method header.
+ .byte 0xFF, 0xFF, 0xFF, 0xFF
+ // Cache alignment for function entry.
+ .balign 16, 0xFF
END_MACRO
MACRO2(DEFINE_FUNCTION_CUSTOM_CFA, c_name, cfa_offset)
diff --git a/runtime/arch/x86_64/asm_support_x86_64.S b/runtime/arch/x86_64/asm_support_x86_64.S
index 28018c5f24..6b09a6e45b 100644
--- a/runtime/arch/x86_64/asm_support_x86_64.S
+++ b/runtime/arch/x86_64/asm_support_x86_64.S
@@ -109,7 +109,11 @@
/* Cache alignment for function entry */
MACRO0(ALIGN_FUNCTION_ENTRY)
- .balign 16
+ // ART-compiled functions have OatQuickMethodHeader but assembly funtions do not.
+ // Prefix the assembly code with 0xFFs, which means there is no method header.
+ .byte 0xFF, 0xFF, 0xFF, 0xFF
+ // Cache alignment for function entry.
+ .balign 16, 0xFF
END_MACRO
// TODO: we might need to use SYMBOL() here to add the underscore prefix
diff --git a/runtime/oat_quick_method_header.h b/runtime/oat_quick_method_header.h
index 8798c6968c..e41c7eef68 100644
--- a/runtime/oat_quick_method_header.h
+++ b/runtime/oat_quick_method_header.h
@@ -76,6 +76,10 @@ class PACKED(4) OatQuickMethodHeader {
}
uint32_t GetCodeSize() const {
+ // ART compiled method are prefixed with header, but we can also easily
+ // accidentally use a function pointer to one of the stubs/trampolines.
+ // We prefix those with 0xFF in the aseembly so that we can do DCHECKs.
+ CHECK_NE(code_size_, 0xFFFFFFFF) << code_;
return code_size_ & kCodeSizeMask;
}