13a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers/*
23a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * Copyright (C) 2012 The Android Open Source Project
33a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers *
43a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License");
53a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * you may not use this file except in compliance with the License.
63a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * You may obtain a copy of the License at
73a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers *
83a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers *      http://www.apache.org/licenses/LICENSE-2.0
93a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers *
103a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * Unless required by applicable law or agreed to in writing, software
113a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS,
123a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * See the License for the specific language governing permissions and
143a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers * limitations under the License.
153a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers */
163a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
1702ed4c04468ca5f5540c5b704ac3e2f30eb9e8f4Ian Rogers#ifndef ART_DISASSEMBLER_DISASSEMBLER_H_
1802ed4c04468ca5f5540c5b704ac3e2f30eb9e8f4Ian Rogers#define ART_DISASSEMBLER_DISASSEMBLER_H_
193a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
200f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include <stdint.h>
210f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes
220f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes#include <iosfwd>
230f3c55331439970e01af67f80ac117c473bc04cfElliott Hughes
24bda1d606f2d31086874b68edd9254e3817d8049cAndreas Gampe#include "android-base/macros.h"
25bda1d606f2d31086874b68edd9254e3817d8049cAndreas Gampe
26d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h"
273a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
283a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogersnamespace art {
293a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
302cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstromclass DisassemblerOptions {
312cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom public:
32372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe  using ThreadOffsetNameFunction = void (*)(std::ostream& os, uint32_t offset);
33372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe
34372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe  ThreadOffsetNameFunction thread_offset_name_function_;
352cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
36d3059e77818a058513ed92557160bdb6d5102b67Aart Bik  // Base address for calculating relative code offsets when absolute_addresses_ is false.
372cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  const uint8_t* const base_address_;
382cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
39d3059e77818a058513ed92557160bdb6d5102b67Aart Bik  // End address (exclusive);
40d3059e77818a058513ed92557160bdb6d5102b67Aart Bik  const uint8_t* const end_address_;
41d3059e77818a058513ed92557160bdb6d5102b67Aart Bik
42372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe  // Should the disassembler print absolute or relative addresses.
43372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe  const bool absolute_addresses_;
44372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe
45a37d925d405be9f589ac282869a997e73414d859Alexandre Rames  // If set, the disassembler is allowed to look at load targets in literal
46a37d925d405be9f589ac282869a997e73414d859Alexandre Rames  // pools.
47a37d925d405be9f589ac282869a997e73414d859Alexandre Rames  const bool can_read_literals_;
48a37d925d405be9f589ac282869a997e73414d859Alexandre Rames
49d3059e77818a058513ed92557160bdb6d5102b67Aart Bik  DisassemblerOptions(bool absolute_addresses,
50d3059e77818a058513ed92557160bdb6d5102b67Aart Bik                      const uint8_t* base_address,
51d3059e77818a058513ed92557160bdb6d5102b67Aart Bik                      const uint8_t* end_address,
52372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe                      bool can_read_literals,
53372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe                      ThreadOffsetNameFunction fn)
54372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe      : thread_offset_name_function_(fn),
55d3059e77818a058513ed92557160bdb6d5102b67Aart Bik        base_address_(base_address),
56d3059e77818a058513ed92557160bdb6d5102b67Aart Bik        end_address_(end_address),
57372f3a374681ef11f003460e14249adb7bc8313dAndreas Gampe        absolute_addresses_(absolute_addresses),
58a37d925d405be9f589ac282869a997e73414d859Alexandre Rames        can_read_literals_(can_read_literals) {}
592cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
602cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom private:
612cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(DisassemblerOptions);
622cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom};
632cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
643a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogersclass Disassembler {
653a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers public:
662cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  // Creates a Disassembler for the given InstructionSet with the
672cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  // non-null DisassemblerOptions which become owned by the
682cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  // Disassembler.
692cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  static Disassembler* Create(InstructionSet instruction_set, DisassemblerOptions* options);
702cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
712cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  virtual ~Disassembler() {
722cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom    delete disassembler_options_;
732cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  }
743a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
75b23a7729cf7855fa05345d03a4d84111d5ec7172Ian Rogers  // Dump a single instruction returning the length of that instruction.
76b23a7729cf7855fa05345d03a4d84111d5ec7172Ian Rogers  virtual size_t Dump(std::ostream& os, const uint8_t* begin) = 0;
77b23a7729cf7855fa05345d03a4d84111d5ec7172Ian Rogers  // Dump instructions within a range.
783a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers  virtual void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) = 0;
79105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cdElliott Hughes
80eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  const DisassemblerOptions* GetDisassemblerOptions() const {
81eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames    return disassembler_options_;
82eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames  }
83eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
84105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cdElliott Hughes protected:
85bda1d606f2d31086874b68edd9254e3817d8049cAndreas Gampe  explicit Disassembler(DisassemblerOptions* disassembler_options);
862cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom
872cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  std::string FormatInstructionPointer(const uint8_t* begin);
88105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cdElliott Hughes
89105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cdElliott Hughes private:
902cbaccb67e22c0b313a9785bfc65bcb4b25d0676Brian Carlstrom  DisassemblerOptions* disassembler_options_;
91105afd2bd8f9f0ddfcfcb4b8db9f356ee82ae8cdElliott Hughes  DISALLOW_COPY_AND_ASSIGN(Disassembler);
923a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers};
933a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
943c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffraystatic inline bool HasBitSet(uint32_t value, uint32_t bit) {
953c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray  return (value & (1 << bit)) != 0;
963c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray}
973c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray
98eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Ramesextern "C"
99eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre RamesDisassembler* create_disassembler(InstructionSet instruction_set, DisassemblerOptions* options);
100eb7b7399dbdb5e471b8ae00a567bf4f19edd3907Alexandre Rames
1013a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers}  // namespace art
1023a5c1ce3f11805a3382046f699c8fb1410a602b3Ian Rogers
10302ed4c04468ca5f5540c5b704ac3e2f30eb9e8f4Ian Rogers#endif  // ART_DISASSEMBLER_DISASSEMBLER_H_
104