summaryrefslogtreecommitdiff
path: root/disassembler/disassembler_arm64.cc
diff options
context:
space:
mode:
author Greg Cawthorne <greg.cawthorne@linaro.org> 2021-12-21 22:01:14 +0000
committer Ulya Trofimovich <skvadrik@google.com> 2022-06-09 11:18:05 +0000
commitbb3ef5afef7c24764e37891ccba741e6e3723ced (patch)
treeba0d7dcb7a8cc9c4d029be0b418a8e8f1f38eeba /disassembler/disassembler_arm64.cc
parentb205efd45ea29a2f21489056fbb0f0309ba992d2 (diff)
VIXL Dissassembler Integration Upgrade May. 2022
This patch is needed as the VIXL disassembler visitor instrumentation interface has changed. VIXL now has all of its instruction specific instrumentation functions declared as private and therefore they cannot be overriden by the ART disassembler class as it was before. Now it is required by VIXL to override the main catch-all generic Visit function, which now passes with it a metadata object. This metadata is then used in the overriding function to select which instrumentation to perform based on the instruction type detected in the instruction sequence at runtime. This patch is tested against ART with the public VIXL tag 6.3.0 (https://github.com/Linaro/vixl/tree/6.3.0) having been merged into the AOSP ./external/vixl repo. Test: test-art-target Test: test-art-host Test: test-art-host-vixl Test: run-vixl-tests Test: art_disassembler_tests Change-Id: I9c2b936354763f0d116dfb7fe355841b9f833a34
Diffstat (limited to 'disassembler/disassembler_arm64.cc')
-rw-r--r--disassembler/disassembler_arm64.cc40
1 files changed, 32 insertions, 8 deletions
diff --git a/disassembler/disassembler_arm64.cc b/disassembler/disassembler_arm64.cc
index 0d51cfdc1a..23472a8dca 100644
--- a/disassembler/disassembler_arm64.cc
+++ b/disassembler/disassembler_arm64.cc
@@ -18,6 +18,8 @@
#include <inttypes.h>
+#include <regex>
+
#include <sstream>
#include "android-base/logging.h"
@@ -58,9 +60,34 @@ void CustomDisassembler::AppendRegisterNameToOutput(const Instruction* instr,
Disassembler::AppendRegisterNameToOutput(instr, reg);
}
-void CustomDisassembler::VisitLoadLiteral(const Instruction* instr) {
- Disassembler::VisitLoadLiteral(instr);
+void CustomDisassembler::Visit(vixl::aarch64::Metadata* metadata, const Instruction* instr) {
+ vixl::aarch64::Disassembler::Visit(metadata, instr);
+ const std::string& form = (*metadata)["form"];
+
+ // These regexs are long, but it is an attempt to match the mapping entry keys in the
+ // #define DEFAULT_FORM_TO_VISITOR_MAP(VISITORCLASS) in the file
+ // external/vixl/src/aarch64/decoder-visitor-map-aarch64.h
+ // for the ::VisitLoadLiteralInstr, ::VisitLoadStoreUnsignedOffset or ::VisitUnconditionalBranch
+ // function addresess key values.
+ // N.B. the mapping are many to one.
+ if (std::regex_match(form, std::regex("(ldrsw|ldr|prfm)_(32|64|d|b|h|q|s)_loadlit"))) {
+ VisitLoadLiteralInstr(instr);
+ return;
+ }
+ if (std::regex_match(form, std::regex(
+ "(ldrb|ldrh|ldrsb|ldrsh|ldrsw|ldr|prfm|strb|strh|str)_(32|64|d|b|h|q|s)_ldst_pos"))) {
+ VisitLoadStoreUnsignedOffsetInstr(instr);
+ return;
+ }
+
+ if (std::regex_match(form, std::regex("(bl|b)_only_branch_imm"))) {
+ VisitUnconditionalBranchInstr(instr);
+ return;
+ }
+}
+
+void CustomDisassembler::VisitLoadLiteralInstr(const Instruction* instr) {
if (!read_literals_) {
return;
}
@@ -69,6 +96,7 @@ void CustomDisassembler::VisitLoadLiteral(const Instruction* instr) {
// avoid trying to fetch invalid literals (we can encounter this when
// interpreting raw data as instructions).
void* data_address = instr->GetLiteralAddress<void*>();
+
if (data_address < base_address_ || data_address >= end_address_) {
AppendToOutput(" (?)");
return;
@@ -97,17 +125,13 @@ void CustomDisassembler::VisitLoadLiteral(const Instruction* instr) {
}
}
-void CustomDisassembler::VisitLoadStoreUnsignedOffset(const Instruction* instr) {
- Disassembler::VisitLoadStoreUnsignedOffset(instr);
-
+void CustomDisassembler::VisitLoadStoreUnsignedOffsetInstr(const Instruction* instr) {
if (instr->GetRn() == TR) {
AppendThreadOfsetName(instr);
}
}
-void CustomDisassembler::VisitUnconditionalBranch(const Instruction* instr) {
- Disassembler::VisitUnconditionalBranch(instr);
-
+void CustomDisassembler::VisitUnconditionalBranchInstr(const Instruction* instr) {
if (instr->Mask(UnconditionalBranchMask) == BL) {
const Instruction* target = instr->GetImmPCOffsetTarget();
if (target >= base_address_ &&