• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011, 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 "StubLayout.h"
18 
19 #include "utils/flush_cpu_cache.h"
20 #include "utils/raw_ostream.h"
21 #include "utils/rsl_assert.h"
22 
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <sys/mman.h>
26 
StubLayout()27 StubLayout::StubLayout() : table(NULL), count(0) {
28 }
29 
initStubTable(unsigned char * table_,size_t count_)30 void StubLayout::initStubTable(unsigned char *table_, size_t count_) {
31   table = table_;
32   count = count_;
33 }
34 
allocateStub(void * addr)35 void *StubLayout::allocateStub(void *addr) {
36   // Check if we have created this stub or not.
37   std::map<void *, void *>::iterator index_iter = stub_index.find(addr);
38 
39   if (index_iter != stub_index.end()) {
40     return index_iter->second;
41   }
42 
43   // We have to create a new stub
44   if (count == 0) {
45     // No free stub slot is available
46     return NULL;
47   }
48 
49   // Initialize the stub
50   unsigned char *stub = table;
51   setStubAddress(stub, addr);
52   stub_index.insert(std::make_pair(addr, stub));
53 
54   // Increase the free stub slot pointer
55   table += getUnitStubSize();
56   count--;
57 
58   return stub;
59 }
60 
calcStubTableSize(size_t count) const61 size_t StubLayout::calcStubTableSize(size_t count) const {
62   return count * getUnitStubSize();
63 }
64 
getUnitStubSize() const65 size_t StubLayoutARM::getUnitStubSize() const {
66   return 8;
67 }
68 
setStubAddress(void * stub_,void * addr)69 void StubLayoutARM::setStubAddress(void *stub_, void *addr) {
70   uint8_t *stub = (uint8_t *)stub_;
71   stub[0] = 0x04; // ldr pc, [pc, #-4]
72   stub[1] = 0xf0; // ldr pc, [pc, #-4]
73   stub[2] = 0x1f; // ldr pc, [pc, #-4]
74   stub[3] = 0xe5; // ldr pc, [pc, #-4]
75 
76   void **target = (void **)(stub + 4);
77   *target = addr;
78 }
79 
getUnitStubSize() const80 size_t StubLayoutMIPS::getUnitStubSize() const {
81   return 16;
82 }
83 
setStubAddress(void * stub_,void * addr)84 void StubLayoutMIPS::setStubAddress(void *stub_, void *addr) {
85   uint32_t addr32 = (uint32_t)(uintptr_t)addr;
86   uint16_t addr_hi16 = (addr32 >> 16) &  0xffff;
87   uint16_t addr_lo16 = addr32 & 0xffff;
88 
89   uint32_t *stub = (uint32_t *)stub_;
90   stub[0] = 0x3c190000ul | addr_hi16; // lui
91   stub[1] = 0x37390000ul | addr_lo16; // ori
92   stub[2] = 0x03200008ul; // jr (jump register)
93   stub[3] = 0x00000000ul; // nop
94 }
95