diff options
-rw-r--r-- | dex2oat/linker/oat_writer.cc | 11 | ||||
-rw-r--r-- | runtime/arch/arm/asm_support_arm.S | 15 | ||||
-rw-r--r-- | runtime/arch/arm/quick_entrypoints_arm.S | 3 | ||||
-rw-r--r-- | runtime/arch/arm64/asm_support_arm64.S | 14 | ||||
-rw-r--r-- | runtime/arch/arm64/quick_entrypoints_arm64.S | 3 | ||||
-rw-r--r-- | runtime/arch/x86/asm_support_x86.S | 6 | ||||
-rw-r--r-- | runtime/arch/x86_64/asm_support_x86_64.S | 6 | ||||
-rw-r--r-- | runtime/oat_quick_method_header.h | 4 |
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; } |