1 /* 2 * Copyright (C) 2014 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 #include "berberis/assembler/machine_code.h" 18 19 #include <string> 20 21 #include "berberis/base/bit_util.h" 22 #include "berberis/base/logging.h" 23 24 namespace berberis { 25 AddrOf(uint32_t offset)26uint8_t* MachineCode::AddrOf(uint32_t offset) { 27 CHECK_LT(offset, code_.size()); 28 return &code_[offset]; 29 } 30 AddrOf(uint32_t offset) const31const uint8_t* MachineCode::AddrOf(uint32_t offset) const { 32 CHECK_LT(offset, code_.size()); 33 return &code_[offset]; 34 } 35 Grow(uint32_t count)36uint32_t MachineCode::Grow(uint32_t count) { 37 size_t old_size = code_.size(); 38 code_.resize(old_size + count); 39 return old_size; 40 } 41 print_halfbyte(uint8_t b)42inline char print_halfbyte(uint8_t b) { 43 return b < 0xa ? b + '0' : (b - 0xa) + 'a'; 44 } 45 AsString(std::string * result) const46void MachineCode::AsString(std::string* result) const { 47 for (uint8_t insn : code_) { 48 *result += print_halfbyte(insn >> 4); 49 *result += print_halfbyte(insn & 0xf); 50 *result += ' '; 51 } 52 } 53 PerformRelocations(const uint8_t * code,RecoveryMap * recovery_map)54void MachineCode::PerformRelocations(const uint8_t* code, RecoveryMap* recovery_map) { 55 for (const auto& rel : relocations_) { 56 switch (rel.type) { 57 case RelocationType::RelocAbsToDisp32: { 58 intptr_t start = reinterpret_cast<intptr_t>(code); 59 intptr_t pc = start + rel.pc; 60 intptr_t disp = rel.data - pc; 61 CHECK(IsInRange<int32_t>(disp)); 62 *AddrAs<int32_t>(rel.dst) = disp; 63 break; 64 } 65 case RelocationType::RelocRecoveryPoint: { 66 uintptr_t start = reinterpret_cast<uintptr_t>(code); 67 uintptr_t fault_addr = start + rel.pc; 68 uintptr_t recovery_addr = start + rel.data; 69 (*recovery_map)[fault_addr] = recovery_addr; 70 break; 71 } 72 } 73 } 74 } 75 DumpCode() const76void MachineCode::DumpCode() const { 77 std::string code_str; 78 AsString(&code_str); 79 ALOGE("%s\n", code_str.c_str()); 80 } 81 82 } // namespace berberis 83