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 // Forward declarations.
     25 class Memory;
     26 class RegsArm;
     27 
     28 enum ArmStatus : size_t {
     29   ARM_STATUS_NONE = 0,
     30   ARM_STATUS_NO_UNWIND,
     31   ARM_STATUS_FINISH,
     32   ARM_STATUS_RESERVED,
     33   ARM_STATUS_SPARE,
     34   ARM_STATUS_TRUNCATED,
     35   ARM_STATUS_READ_FAILED,
     36   ARM_STATUS_MALFORMED,
     37   ARM_STATUS_INVALID_ALIGNMENT,
     38   ARM_STATUS_INVALID_PERSONALITY,
     39 };
     40 
     41 enum ArmOp : uint8_t {
     42   ARM_OP_FINISH = 0xb0,
     43 };
     44 
     45 class ArmExidx {
     46  public:
     47   ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory)
     48       : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {}
     49   virtual ~ArmExidx() {}
     50 
     51   void LogRawData();
     52 
     53   bool ExtractEntryData(uint32_t entry_offset);
     54 
     55   bool Eval();
     56 
     57   bool Decode();
     58 
     59   std::deque<uint8_t>* data() { return &data_; }
     60 
     61   ArmStatus status() { return status_; }
     62 
     63   RegsArm* regs() { return regs_; }
     64 
     65   uint32_t cfa() { return cfa_; }
     66   void set_cfa(uint32_t cfa) { cfa_ = cfa; }
     67 
     68   bool pc_set() { return pc_set_; }
     69   void set_pc_set(bool pc_set) { pc_set_ = pc_set; }
     70 
     71   void set_log(bool log) { log_ = log; }
     72   void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; }
     73   void set_log_indent(uint8_t indent) { log_indent_ = indent; }
     74 
     75  private:
     76   bool GetByte(uint8_t* byte);
     77 
     78   bool DecodePrefix_10_00(uint8_t byte);
     79   bool DecodePrefix_10_01(uint8_t byte);
     80   bool DecodePrefix_10_10(uint8_t byte);
     81   bool DecodePrefix_10_11_0000();
     82   bool DecodePrefix_10_11_0001();
     83   bool DecodePrefix_10_11_0010();
     84   bool DecodePrefix_10_11_0011();
     85   bool DecodePrefix_10_11_01nn();
     86   bool DecodePrefix_10_11_1nnn(uint8_t byte);
     87   bool DecodePrefix_10(uint8_t byte);
     88 
     89   bool DecodePrefix_11_000(uint8_t byte);
     90   bool DecodePrefix_11_001(uint8_t byte);
     91   bool DecodePrefix_11_010(uint8_t byte);
     92   bool DecodePrefix_11(uint8_t byte);
     93 
     94   RegsArm* regs_ = nullptr;
     95   uint32_t cfa_ = 0;
     96   std::deque<uint8_t> data_;
     97   ArmStatus status_ = ARM_STATUS_NONE;
     98 
     99   Memory* elf_memory_;
    100   Memory* process_memory_;
    101 
    102   bool log_ = false;
    103   uint8_t log_indent_ = 0;
    104   bool log_skip_execution_ = false;
    105   bool pc_set_ = false;
    106 };
    107 
    108 #endif  // _LIBUNWINDSTACK_ARM_EXIDX_H
    109