1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Declaration of register map data structure and related functions. 1999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 2099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * These structures should be treated as opaque through most of the VM. 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef _DALVIK_REGISTERMAP 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define _DALVIK_REGISTERMAP 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#include "analysis/VerifySubs.h" 2699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project#include "analysis/CodeVerify.h" 2799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Format enumeration for RegisterMap data area. 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum RegisterMapFormat { 3299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project kRegMapFormatUnknown = 0, 3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project kRegMapFormatNone, /* indicates no map data follows */ 3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project kRegMapFormatCompact8, /* compact layout, 8-bit addresses */ 3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project kRegMapFormatCompact16, /* compact layout, 16-bit addresses */ 36d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden kRegMapFormatDifferential, /* compressed, differential encoding */ 3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project kRegMapFormatOnHeap = 0x80, /* bit flag, indicates allocation on heap */ 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} RegisterMapFormat; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is a single variable-size structure. It may be allocated on the 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * heap or mapped out of a (post-dexopt) DEX file. 4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 32-bit alignment of the structure is NOT guaranteed. This makes it a 4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * little awkward to deal with as a structure; to avoid accidents we use 4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * only byte types. Multi-byte values are little-endian. 4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Size of (format==FormatNone): 1 byte 5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Size of (format==FormatCompact8): 4 + (1 + regWidth) * numEntries 5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Size of (format==FormatCompact16): 4 + (2 + regWidth) * numEntries 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstruct RegisterMap { 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* header */ 5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u1 format; /* enum RegisterMapFormat; MUST be first entry */ 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 regWidth; /* bytes per register line, 1+ */ 5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u1 numEntries[2]; /* number of entries */ 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* raw data starts here; need not be aligned */ 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1 data[1]; 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectbool dvmRegisterMapStartup(void); 6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectvoid dvmRegisterMapShutdown(void); 6599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the format. 6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 691d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFaddenINLINE RegisterMapFormat dvmRegisterMapGetFormat(const RegisterMap* pMap) { 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return pMap->format & ~(kRegMapFormatOnHeap); 7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} 7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 74d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Set the format. 75d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */ 76d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE void dvmRegisterMapSetFormat(RegisterMap* pMap, RegisterMapFormat format) 77d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden{ 78d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden pMap->format &= kRegMapFormatOnHeap; 79d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden pMap->format |= format; 80d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden} 81d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden 82d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/* 8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the "on heap" flag. 8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 85d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE bool dvmRegisterMapGetOnHeap(const RegisterMap* pMap) { 8699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return (pMap->format & kRegMapFormatOnHeap) != 0; 8799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} 8899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 8999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 90d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Get the register bit vector width, in bytes. 91d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */ 92d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE u1 dvmRegisterMapGetRegWidth(const RegisterMap* pMap) { 93d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden return pMap->regWidth; 94d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden} 95d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden 96d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/* 97d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Set the register bit vector width, in bytes. 98d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */ 99d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE void dvmRegisterMapSetRegWidth(RegisterMap* pMap, int regWidth) { 100d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden pMap->regWidth = regWidth; 101d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden} 102d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden 103d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/* 10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Set the "on heap" flag. 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 106d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE void dvmRegisterMapSetOnHeap(RegisterMap* pMap, bool val) { 10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (val) 10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pMap->format |= kRegMapFormatOnHeap; 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project else 11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pMap->format &= ~(kRegMapFormatOnHeap); 11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} 11299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 11399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the number of entries in this map. 11599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 11699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectINLINE u2 dvmRegisterMapGetNumEntries(const RegisterMap* pMap) { 11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return pMap->numEntries[0] | (pMap->numEntries[1] << 8); 11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} 11999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 12199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Set the number of entries in this map. 12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectINLINE void dvmRegisterMapSetNumEntries(RegisterMap* pMap, u2 numEntries) { 12499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pMap->numEntries[0] = (u1) numEntries; 12599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project pMap->numEntries[1] = numEntries >> 8; 12699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} 12799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 12899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 12999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Retrieve the bit vector for the specified address. This is a pointer 13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * to the bit data from an uncompressed map, or to a temporary copy of 13199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * data from a compressed map. 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The caller must call dvmReleaseRegisterMapLine() with the result. 13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns NULL if not found. 13699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 137d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst u1* dvmRegisterMapGetLine(const RegisterMap* pMap, int addr); 13899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 13999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Release "data". 14199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 1421d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * If "pMap" points to a compressed map from which we have expanded a 1431d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * single line onto the heap, this will free "data"; otherwise, it does 1441d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * nothing. 1451d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * 1461d47a87b38e41f9957849ba685af1f41e53f8a05Andy McFadden * TODO: decide if this is still a useful concept. 14799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 14899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectINLINE void dvmReleaseRegisterMapLine(const RegisterMap* pMap, const u1* data) 14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project{} 15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 15199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * A pool of register maps for methods associated with a single class. 15499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 15599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Each entry is a 4-byte method index followed by the 32-bit-aligned 15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * RegisterMap. The size of the RegisterMap is determined by parsing 15799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the map. The lack of an index reduces random access speed, but we 15899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * should be doing that rarely (during class load) and it saves space. 15999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * These structures are 32-bit aligned. 16199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 16299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projecttypedef struct RegisterMapMethodPool { 16399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u2 methodCount; /* chiefly used as a sanity check */ 16499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 16599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* stream of per-method data starts here */ 16699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u4 methodData[1]; 16799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} RegisterMapMethodPool; 16899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 16999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Header for the memory-mapped RegisterMap pool in the DEX file. 17199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 17299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The classDataOffset table provides offsets from the start of the 17399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * RegisterMapPool structure. There is one entry per class (including 17499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * interfaces, which can have static initializers). 17599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 17699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The offset points to a RegisterMapMethodPool. 17799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 17899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * These structures are 32-bit aligned. 17999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 18099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projecttypedef struct RegisterMapClassPool { 18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u4 numClasses; 18299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 18399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* offset table starts here, 32-bit aligned; offset==0 means no data */ 18499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u4 classDataOffset[1]; 18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} RegisterMapClassPool; 18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 18799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 18899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Find the register maps for this class. (Used during class loading.) 18999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * If "pNumMaps" is non-NULL, it will return the number of maps in the set. 19099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 19199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns NULL if none is available. 19299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 193d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst void* dvmRegisterMapGetClassData(const DexFile* pDexFile, u4 classIdx, 19499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project u4* pNumMaps); 19599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 19699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 19799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Get the register map for the next method. "*pPtr" will be advanced past 19899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the end of the map. (Used during class loading.) 19999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * This should initially be called with the result from 201d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * dvmRegisterMapGetClassData(). 20299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 203d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst RegisterMap* dvmRegisterMapGetNext(const void** pPtr); 20499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 20599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 20699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * This holds some meta-data while we construct the set of register maps 20799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * for a DEX file. 20899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * 20999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * In particular, it keeps track of our temporary mmap region so we can 21099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * free it later. 21199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projecttypedef struct RegisterMapBuilder { 21399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* public */ 21499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project void* data; 21599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project size_t size; 21699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 21799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /* private */ 21899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project MemMapping memMap; 21999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project} RegisterMapBuilder; 22099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 22199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 22299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Generate a register map set for all verified classes in "pDvmDex". 22399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 22499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source ProjectRegisterMapBuilder* dvmGenerateRegisterMaps(DvmDex* pDvmDex); 22599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 22699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* 22799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Free the builder. 22899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 22999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectvoid dvmFreeRegisterMapBuilder(RegisterMapBuilder* pBuilder); 23099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 23199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate the register map for a previously-verified method. 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a pointer to a newly-allocated RegisterMap. 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//RegisterMap* dvmGenerateRegisterMap(const Method* meth); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Various bits of data generated by the verifier, wrapped up in a package 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for ease of use by the register map generator. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct VerifierData { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The method we're working on. 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const Method* method; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Number of instructions in the method. 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnsSize; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Number of registers we track for each instruction. This is equal 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to the method's declared "registersSize". (Does not include the 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pending return value.) 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int insnRegCount; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Instruction widths and flags, one entry per code unit. 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project InsnFlags* insnFlags; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Array of SRegType arrays, one entry per code unit. We only need 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * entries for code units that hold the start of an "interesting" 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction. For register map generation, we're only interested 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in GC points. 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegType** addrRegs; 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} VerifierData; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate the register map for a method that has just been verified 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (i.e. we're doing this as part of verification). 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure. 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectRegisterMap* dvmGenerateRegisterMapV(VerifierData* vdata); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 283d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden/* 284d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Get the expanded form of the register map associated with the specified 285d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * method. May update method->registerMap, possibly freeing the previous 286d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * map. 287d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * 288d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * Returns NULL on failure (e.g. unable to expand map). 289d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * 290d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * NOTE: this function is not synchronized; external locking is mandatory. 291d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden * (This is expected to be called at GC time.) 292d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden */ 293d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenconst RegisterMap* dvmGetExpandedRegisterMap0(Method* method); 294d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFaddenINLINE const RegisterMap* dvmGetExpandedRegisterMap(Method* method) 295d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden{ 296d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden const RegisterMap* curMap = method->registerMap; 297d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden if (curMap == NULL) 298d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden return NULL; 299d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden RegisterMapFormat format = dvmRegisterMapGetFormat(curMap); 300d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden if (format == kRegMapFormatCompact8 || format == kRegMapFormatCompact16) { 301d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden return curMap; 302d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden } else { 303d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden return dvmGetExpandedRegisterMap0(method); 304d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden } 305d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden} 306d45a88794c6470d96e2139cbe803002d9d5d3a6cAndy McFadden 30799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project/* dump stats gathered during register map creation process */ 30899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Projectvoid dvmRegisterMapDumpStats(void); 30999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /*_DALVIK_REGISTERMAP*/ 311