Home | History | Annotate | Download | only in libunwindstack
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _LIBUNWINDSTACK_ARM_EXIDX_H
     18 #define _LIBUNWINDSTACK_ARM_EXIDX_H
     19 
     20 #include <stdint.h>
     21 
     22 #include <deque>
     23 
     24 namespace unwindstack {
     25 
     26 // Forward declarations.
     27 class Memory;
     28 class RegsArm;
     29 
     30 enum ArmStatus : size_t {
     31   ARM_STATUS_NONE = 0,
     32   ARM_STATUS_NO_UNWIND,
     33   ARM_STATUS_FINISH,
     34   ARM_STATUS_RESERVED,
     35   ARM_STATUS_SPARE,
     36   ARM_STATUS_TRUNCATED,
     37   ARM_STATUS_READ_FAILED,
     38   ARM_STATUS_MALFORMED,
     39   ARM_STATUS_INVALID_ALIGNMENT,
     40   ARM_STATUS_INVALID_PERSONALITY,
     41 };
     42 
     43 enum ArmOp : uint8_t {
     44   ARM_OP_FINISH = 0xb0,
     45 };
     46 
     47 class ArmExidx {
     48  public:
     49   ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory)
     50       : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {}
     51   virtual ~ArmExidx() {}
     52 
     53   void LogRawData();
     54 
     55   bool ExtractEntryData(uint32_t entry_offset);
     56 
     57   bool Eval();
     58 
     59   bool Decode();
     60 
     61   std::deque<uint8_t>* data() { return &data_; }
     62 
     63   ArmStatus status() { return status_; }
     64   uint64_t status_address() { return status_address_; }
     65 
     66   RegsArm* regs() { return regs_; }
     67 
     68   uint32_t cfa() { return cfa_; }
     69   void set_cfa(uint32_t cfa) { cfa_ = cfa; }
     70 
     71   bool pc_set() { return pc_set_; }
     72   void set_pc_set(bool pc_set) { pc_set_ = pc_set; }
     73 
     74   void set_log(bool log) { log_ = log; }
     75   void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; }
     76   void set_log_indent(uint8_t indent) { log_indent_ = indent; }
     77 
     78  private:
     79   bool GetByte(uint8_t* byte);
     80 
     81   bool DecodePrefix_10_00(uint8_t byte);
     82   bool DecodePrefix_10_01(uint8_t byte);
     83   bool DecodePrefix_10_10(uint8_t byte);
     84   bool DecodePrefix_10_11_0000();
     85   bool DecodePrefix_10_11_0001();
     86   bool DecodePrefix_10_11_0010();
     87   bool DecodePrefix_10_11_0011();
     88   bool DecodePrefix_10_11_01nn();
     89   bool DecodePrefix_10_11_1nnn(uint8_t byte);
     90   bool DecodePrefix_10(uint8_t byte);
     91 
     92   bool DecodePrefix_11_000(uint8_t byte);
     93   bool DecodePrefix_11_001(uint8_t byte);
     94   bool DecodePrefix_11_010(uint8_t byte);
     95   bool DecodePrefix_11(uint8_t byte);
     96 
     97   RegsArm* regs_ = nullptr;
     98   uint32_t cfa_ = 0;
     99   std::deque<uint8_t> data_;
    100   ArmStatus status_ = ARM_STATUS_NONE;
    101   uint64_t status_address_ = 0;
    102 
    103   Memory* elf_memory_;
    104   Memory* process_memory_;
    105 
    106   bool log_ = false;
    107   uint8_t log_indent_ = 0;
    108   bool log_skip_execution_ = false;
    109   bool pc_set_ = false;
    110 };
    111 
    112 }  // namespace unwindstack
    113 
    114 #endif  // _LIBUNWINDSTACK_ARM_EXIDX_H
    115