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