summaryrefslogtreecommitdiff
path: root/disassembler
diff options
context:
space:
mode:
Diffstat (limited to 'disassembler')
-rw-r--r--disassembler/Android.bp68
-rw-r--r--disassembler/disassembler_arm.cc16
-rw-r--r--disassembler/disassembler_arm64.cc30
-rw-r--r--disassembler/disassembler_arm64.h5
4 files changed, 104 insertions, 15 deletions
diff --git a/disassembler/Android.bp b/disassembler/Android.bp
index 064aaea0e1..71ad051927 100644
--- a/disassembler/Android.bp
+++ b/disassembler/Android.bp
@@ -14,6 +14,15 @@
// limitations under the License.
//
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "art_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["art_license"],
+}
+
art_cc_defaults {
name: "libart-disassembler-defaults",
defaults: ["art_defaults"],
@@ -48,33 +57,69 @@ art_cc_defaults {
art_cc_library {
name: "libart-disassembler",
defaults: ["libart-disassembler-defaults"],
- shared_libs: [
- // For disassembler_arm*.
- "libvixl",
- ],
+ codegen: {
+ arm: {
+ static_libs: [
+ // For disassembler_arm*.
+ "libvixl",
+ ],
+ },
+ arm64: {
+ static_libs: [
+ // For disassembler_arm*.
+ "libvixl",
+ ],
+ },
+ },
apex_available: [
- "com.android.art.release",
+ "com.android.art",
"com.android.art.debug",
],
}
+cc_defaults {
+ name: "libart-disassembler_static_defaults",
+ whole_static_libs: [
+ "libart-disassembler",
+ "libvixl",
+ ],
+}
+
art_cc_library {
name: "libartd-disassembler",
defaults: [
"art_debug_defaults",
"libart-disassembler-defaults",
],
- shared_libs: [
- // For disassembler_arm*.
- "libvixld",
- ],
+ codegen: {
+ arm: {
+ static_libs: [
+ // For disassembler_arm*.
+ "libvixld",
+ ],
+ },
+ arm64: {
+ static_libs: [
+ // For disassembler_arm*.
+ "libvixld",
+ ],
+ },
+ },
apex_available: [
- "com.android.art.release",
+ "com.android.art",
"com.android.art.debug",
],
}
+cc_defaults {
+ name: "libartd-disassembler_static_defaults",
+ whole_static_libs: [
+ "libartd-disassembler",
+ "libvixld",
+ ],
+}
+
cc_library_headers {
name: "art_disassembler_headers",
host_supported: true,
@@ -84,6 +129,7 @@ cc_library_headers {
apex_available: [
"com.android.art.debug",
- "com.android.art.release",
+ "com.android.art",
],
+ min_sdk_version: "S",
}
diff --git a/disassembler/disassembler_arm.cc b/disassembler/disassembler_arm.cc
index 94ea0064e6..c2156ca5e1 100644
--- a/disassembler/disassembler_arm.cc
+++ b/disassembler/disassembler_arm.cc
@@ -68,6 +68,22 @@ class DisassemblerArm::CustomDisassembler final : public PrintDisassembler {
PrintLiteral(type, offset);
return *this;
}
+ case kCodeLocation:
+ DisassemblerStream::operator<<(label);
+ // Improve the disassembly of branch to thunk jumping to pointer from thread entrypoint.
+ if (disasm_->GetIsT32() && GetCurrentInstructionType() == vixl::aarch32::kBl) {
+ const uintptr_t begin = reinterpret_cast<uintptr_t>(options_->base_address_);
+ const uintptr_t end = reinterpret_cast<uintptr_t>(options_->end_address_);
+ uintptr_t address = label.GetLocation() + (options_->absolute_addresses_ ? 0u : begin);
+ if ((address >= begin && address < end && end - address >= 4u) &&
+ reinterpret_cast<const uint16_t*>(address)[0] == 0xf8d9 && // LDR Rt, [tr, #imm12]
+ (reinterpret_cast<const uint16_t*>(address)[1] >> 12) == 0xf) { // Rt == PC
+ uint32_t imm12 = reinterpret_cast<const uint16_t*>(address)[1] & 0xfffu;
+ os() << " ; ";
+ options_->thread_offset_name_function_(os(), imm12);
+ }
+ }
+ return *this;
default:
return DisassemblerStream::operator<<(label);
}
diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc
index 49b9623f4f..0d51cfdc1a 100644
--- a/disassembler/disassembler_arm64.cc
+++ b/disassembler/disassembler_arm64.cc
@@ -101,13 +101,35 @@ void CustomDisassembler::VisitLoadStoreUnsignedOffset(const Instruction* instr)
Disassembler::VisitLoadStoreUnsignedOffset(instr);
if (instr->GetRn() == TR) {
- int64_t offset = instr->GetImmLSUnsigned() << instr->GetSizeLS();
- std::ostringstream tmp_stream;
- options_->thread_offset_name_function_(tmp_stream, static_cast<uint32_t>(offset));
- AppendToOutput(" ; %s", tmp_stream.str().c_str());
+ AppendThreadOfsetName(instr);
}
}
+void CustomDisassembler::VisitUnconditionalBranch(const Instruction* instr) {
+ Disassembler::VisitUnconditionalBranch(instr);
+
+ if (instr->Mask(UnconditionalBranchMask) == BL) {
+ const Instruction* target = instr->GetImmPCOffsetTarget();
+ if (target >= base_address_ &&
+ target < end_address_ &&
+ target->Mask(LoadStoreMask) == LDR_x &&
+ target->GetRn() == TR &&
+ target->GetRt() == IP0 &&
+ target->GetNextInstruction() < end_address_ &&
+ target->GetNextInstruction()->Mask(UnconditionalBranchToRegisterMask) == BR &&
+ target->GetNextInstruction()->GetRn() == IP0) {
+ AppendThreadOfsetName(target);
+ }
+ }
+}
+
+void CustomDisassembler::AppendThreadOfsetName(const vixl::aarch64::Instruction* instr) {
+ int64_t offset = instr->GetImmLSUnsigned() << instr->GetSizeLS();
+ std::ostringstream tmp_stream;
+ options_->thread_offset_name_function_(tmp_stream, static_cast<uint32_t>(offset));
+ AppendToOutput(" ; %s", tmp_stream.str().c_str());
+}
+
size_t DisassemblerArm64::Dump(std::ostream& os, const uint8_t* begin) {
const Instruction* instr = reinterpret_cast<const Instruction*>(begin);
decoder.Decode(instr);
diff --git a/disassembler/disassembler_arm64.h b/disassembler/disassembler_arm64.h
index 89beaa927b..a895dfe823 100644
--- a/disassembler/disassembler_arm64.h
+++ b/disassembler/disassembler_arm64.h
@@ -53,7 +53,12 @@ class CustomDisassembler final : public vixl::aarch64::Disassembler {
// Improve the disassembly of thread offset.
void VisitLoadStoreUnsignedOffset(const vixl::aarch64::Instruction* instr) override;
+ // Improve the disassembly of branch to thunk jumping to pointer from thread entrypoint.
+ void VisitUnconditionalBranch(const vixl::aarch64::Instruction* instr) override;
+
private:
+ void AppendThreadOfsetName(const vixl::aarch64::Instruction* instr);
+
// Indicate if the disassembler should read data loaded from literal pools.
// This should only be enabled if reading the target of literal loads is safe.
// Here are possible outputs when the option is on or off: