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 * Strip Android-specific records out of hprof data, back-converting from 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1.0.3 to 1.0.2. This removes some useful information, but allows 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Android hprof data to be handled by widely-available tools (like "jhat"). 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdint.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <assert.h> 283db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey#include <unistd.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//#define VERBOSE_DEBUG 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef VERBOSE_DEBUG 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define DBUG(...) fprintf(stderr, __VA_ARGS__) 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define DBUG(...) 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef FALSE 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define FALSE 0 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project# define TRUE (!FALSE) 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum HprofBasicType { 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_OBJECT = 2, 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_BOOLEAN = 4, 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_CHAR = 5, 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_FLOAT = 6, 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_DOUBLE = 7, 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_BYTE = 8, 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_SHORT = 9, 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_INT = 10, 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_BASIC_LONG = 11, 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} HprofBasicType; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum HprofTag { 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* tags we must handle specially */ 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_TAG_HEAP_DUMP = 0x0c, 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1c, 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} HprofTag; 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef enum HprofHeapTag { 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1.0.2 tags */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_UNKNOWN = 0xff, 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_JNI_GLOBAL = 0x01, 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_JNI_LOCAL = 0x02, 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_JAVA_FRAME = 0x03, 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_NATIVE_STACK = 0x04, 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_STICKY_CLASS = 0x05, 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_THREAD_BLOCK = 0x06, 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_MONITOR_USED = 0x07, 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_THREAD_OBJECT = 0x08, 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_CLASS_DUMP = 0x20, 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_INSTANCE_DUMP = 0x21, 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_OBJECT_ARRAY_DUMP = 0x22, 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_PRIMITIVE_ARRAY_DUMP = 0x23, 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Android 1.0.3 tags */ 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_HEAP_DUMP_INFO = 0xfe, 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_INTERNED_STRING = 0x89, 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_FINALIZING = 0x8a, 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_DEBUGGER = 0x8b, 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_VM_INTERNAL = 0x8d, 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_ROOT_JNI_MONITOR = 0x8e, 8498740d6436340f17f5427d5923184fcace0e38ccCarl Shapiro HPROF_UNREACHABLE = 0x90, /* deprecated */ 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3, 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} HprofHeapTag; 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 883db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeytypedef enum HprofHeapId { 893db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey HPROF_HEAP_DEFAULT = 0, 903db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey HPROF_HEAP_ZYGOTE = 'Z', 913db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey HPROF_HEAP_APP = 'A', 923db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey HPROF_HEAP_IMAGE = 'I', 933db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey} HprofHeapId; 943db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kIdentSize 4 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kRecHdrLen 9 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 983db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey#define kFlagAppOnly 1 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Expanding buffer 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* simple struct */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct { 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char* storage; 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t curLen; 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t maxLen; 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} ExpandBuf; 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an ExpandBuf. 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic ExpandBuf* ebAlloc(void) 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const int kInitialSize = 64; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* newBuf = (ExpandBuf*) malloc(sizeof(ExpandBuf)); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newBuf == NULL) 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newBuf->storage = (unsigned char*) malloc(kInitialSize); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newBuf->curLen = 0; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project newBuf->maxLen = kInitialSize; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newBuf; 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Release the storage associated with an ExpandBuf. 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void ebFree(ExpandBuf* pBuf) 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pBuf != NULL) { 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pBuf->storage); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pBuf); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return a pointer to the data buffer. 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The pointer may change as data is added to the buffer, so this value 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should not be cached. 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline unsigned char* ebGetBuffer(ExpandBuf* pBuf) 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pBuf->storage; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the amount of data currently in the buffer. 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline size_t ebGetLength(ExpandBuf* pBuf) 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pBuf->curLen; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Empty the buffer. 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void ebClear(ExpandBuf* pBuf) 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->curLen = 0; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Ensure that the buffer can hold at least "size" additional bytes. 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int ebEnsureCapacity(ExpandBuf* pBuf, int size) 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(size > 0); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pBuf->curLen + size > pBuf->maxLen) { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int newSize = pBuf->curLen + size + 128; /* oversize slightly */ 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char* newStorage = realloc(pBuf->storage, newSize); 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (newStorage == NULL) { 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: realloc failed on size=%d\n", newSize); 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->storage = newStorage; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->maxLen = newSize; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pBuf->curLen + size <= pBuf->maxLen); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add data to the buffer after ensuring it can hold it. 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int ebAddData(ExpandBuf* pBuf, const void* data, size_t count) 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebEnsureCapacity(pBuf, count); 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(pBuf->storage + pBuf->curLen, data, count); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->curLen += count; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read a NULL-terminated string from the input. 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int ebReadString(ExpandBuf* pBuf, FILE* in) 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ic; 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebEnsureCapacity(pBuf, 1); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ic = getc(in); 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (feof(in) || ferror(in)) { 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: failed reading input\n"); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->storage[pBuf->curLen++] = (unsigned char) ic; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (ic != 0); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read some data, adding it to the expanding buffer. 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This will ensure that the buffer has enough space to hold the new data 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (plus the previous contents). 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int ebReadData(ExpandBuf* pBuf, FILE* in, size_t count, int eofExpected) 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t actual; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(count > 0); 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebEnsureCapacity(pBuf, count); 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actual = fread(pBuf->storage + pBuf->curLen, 1, count, in); 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actual != count) { 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (eofExpected && feof(in) && !ferror(in)) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* return without reporting an error */ 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: read %d of %d bytes\n", actual, count); 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->curLen += count; 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pBuf->curLen <= pBuf->maxLen); 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Write the data from the buffer. Resets the data count to zero. 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int ebWriteData(ExpandBuf* pBuf, FILE* out) 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t actual; 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pBuf->curLen > 0); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pBuf->curLen <= pBuf->maxLen); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actual = fwrite(pBuf->storage, 1, pBuf->curLen, out); 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actual != pBuf->curLen) { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: write %d of %d bytes\n", actual, pBuf->curLen); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf->curLen = 0; 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Hprof stuff 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * =========================================================================== 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a 2-byte value, in big-endian order, from memory. 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic uint16_t get2BE(const unsigned char* buf) 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint16_t val; 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = (buf[0] << 8) | buf[1]; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get a 4-byte value, in big-endian order, from memory. 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic uint32_t get4BE(const unsigned char* buf) 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint32_t val; 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set a 4-byte value, in big-endian order. 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void set4BE(unsigned char* buf, uint32_t val) 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = val >> 24; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[1] = val >> 16; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[2] = val >> 8; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[3] = val; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the size, in bytes, of one of the "basic types". 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int computeBasicLen(HprofBasicType basicType) 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const int sizes[] = { -1, -1, 4, -1, 1, 2, 4, 8, 1, 2, 4, 8 }; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const size_t maxSize = sizeof(sizes) / sizeof(sizes[0]); 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(basicType >= 0); 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (basicType >= maxSize) 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sizes[basicType]; 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the length of a HPROF_CLASS_DUMP block. 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int computeClassDumpLen(const unsigned char* origBuf, int len) 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const unsigned char* buf = origBuf; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int blockLen = 0; 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, count; 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project blockLen += kIdentSize * 7 + 8; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += blockLen; 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= blockLen; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len < 0) 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = get2BE(buf); 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += 2; 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= 2; 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("CDL: 1st count is %d\n", count); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HprofBasicType basicType; 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int basicLen; 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basicType = buf[2]; 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basicLen = computeBasicLen(basicType); 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (basicLen < 0) { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("ERROR: invalid basicType %d\n", basicType); 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += 2 + 1 + basicLen; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= 2 + 1 + basicLen; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len < 0) 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = get2BE(buf); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += 2; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= 2; 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("CDL: 2nd count is %d\n", count); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HprofBasicType basicType; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int basicLen; 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basicType = buf[kIdentSize]; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basicLen = computeBasicLen(basicType); 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (basicLen < 0) { 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: invalid basicType %d\n", basicType); 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += kIdentSize + 1 + basicLen; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= kIdentSize + 1 + basicLen; 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len < 0) 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = get2BE(buf); 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += 2; 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= 2; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("CDL: 3rd count is %d\n", count); 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += kIdentSize + 1; 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= kIdentSize + 1; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len < 0) 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("Total class dump len: %d\n", buf - origBuf); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return buf - origBuf; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the length of a HPROF_INSTANCE_DUMP block. 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int computeInstanceDumpLen(const unsigned char* origBuf, int len) 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int extraCount = get4BE(origBuf + kIdentSize * 2 + 4); 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kIdentSize * 2 + 8 + extraCount; 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the length of a HPROF_OBJECT_ARRAY_DUMP block. 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int computeObjectArrayDumpLen(const unsigned char* origBuf, int len) 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int arrayCount = get4BE(origBuf + kIdentSize + 4); 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kIdentSize * 2 + 8 + arrayCount * kIdentSize; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Compute the length of a HPROF_PRIMITIVE_ARRAY_DUMP block. 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int computePrimitiveArrayDumpLen(const unsigned char* origBuf, int len) 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int arrayCount = get4BE(origBuf + kIdentSize + 4); 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project HprofBasicType basicType = origBuf[kIdentSize + 8]; 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int basicLen = computeBasicLen(basicType); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return kIdentSize + 9 + arrayCount * basicLen; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Crunch through a heap dump record, writing the original or converted 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data to "out". 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4353db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeystatic int processHeapDump(ExpandBuf* pBuf, FILE* out, int flags) 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pOutBuf = ebAlloc(); 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char* origBuf = ebGetBuffer(pBuf); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char* buf = origBuf; 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = ebGetLength(pBuf); 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 4423db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey int heapType = HPROF_HEAP_DEFAULT; 4433db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey int heapIgnore = FALSE; 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf = NULL; /* we just use the raw pointer from here forward */ 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* copy the original header to the output buffer */ 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebAddData(pOutBuf, buf, kRecHdrLen) != 0) 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += kRecHdrLen; /* skip past record header */ 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= kRecHdrLen; 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (len > 0) { 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char subType = buf[0]; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int justCopy = TRUE; 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int subLen; 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("--- 0x%02x ", subType); 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (subType) { 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1.0.2 types */ 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_UNKNOWN: 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JNI_GLOBAL: 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize * 2; 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JNI_LOCAL: 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 8; 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JAVA_FRAME: 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 8; 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_NATIVE_STACK: 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 4; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_STICKY_CLASS: 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_THREAD_BLOCK: 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 4; 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_MONITOR_USED: 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_THREAD_OBJECT: 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 8; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_CLASS_DUMP: 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = computeClassDumpLen(buf+1, len-1); 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_INSTANCE_DUMP: 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = computeInstanceDumpLen(buf+1, len-1); 4943db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (heapIgnore) { 4953db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey justCopy = FALSE; 4963db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_OBJECT_ARRAY_DUMP: 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = computeObjectArrayDumpLen(buf+1, len-1); 5003db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (heapIgnore) { 5013db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey justCopy = FALSE; 5023db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_PRIMITIVE_ARRAY_DUMP: 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = computePrimitiveArrayDumpLen(buf+1, len-1); 5063db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (heapIgnore) { 5073db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey justCopy = FALSE; 5083db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* these were added for Android in 1.0.3 */ 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_HEAP_DUMP_INFO: 5123db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey heapType = get4BE(buf+1); 5133db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if ((flags & kFlagAppOnly) != 0 5143db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey && (heapType == HPROF_HEAP_ZYGOTE || heapType == HPROF_HEAP_IMAGE)) { 5153db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey heapIgnore = TRUE; 5163db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } else { 5173db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey heapIgnore = FALSE; 5183db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justCopy = FALSE; 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 4; 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // no 1.0.2 equivalent for this 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_INTERNED_STRING: 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_FINALIZING: 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_DEBUGGER: 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_REFERENCE_CLEANUP: 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_VM_INTERNAL: 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_ROOT_JNI_MONITOR: 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* keep the ident, drop the next 8 bytes */ 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project justCopy = FALSE; 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebAddData(pOutBuf, buf, 1 + kIdentSize); 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 8; 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_UNREACHABLE: 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_ROOT_UNKNOWN; 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize; 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case HPROF_PRIMITIVE_ARRAY_NODATA_DUMP: 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[0] = HPROF_PRIMITIVE_ARRAY_DUMP; 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf[5] = buf[6] = buf[7] = buf[8] = 0; /* set array len to 0 */ 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subLen = kIdentSize + 9; 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* shouldn't get here */ 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: unexpected subtype 0x%02x at offset %d\n", 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project subType, buf - origBuf); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (justCopy) { 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* copy source data */ 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("(%d)\n", 1 + subLen); 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebAddData(pOutBuf, buf, 1 + subLen); 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* other data has been written, or the sub-record omitted */ 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("(adv %d)\n", 1 + subLen); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* advance to next entry */ 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf += 1 + subLen; 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= 1 + subLen; 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Update the record length. 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(ebGetBuffer(pOutBuf) + 5, ebGetLength(pOutBuf) - kRecHdrLen); 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebWriteData(pOutBuf, out) != 0) 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebFree(pOutBuf); 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Filter an hprof data file. 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5993db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeystatic int filterData(FILE* in, FILE* out, int flags) 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 6014e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy const char *magicString; 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pBuf; 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result = -1; 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pBuf = ebAlloc(); 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pBuf == NULL) 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Start with the header. 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebReadString(pBuf, in) != 0) 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6154e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy magicString = (const char*)ebGetBuffer(pBuf); 6164e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy if (strcmp(magicString, "JAVA PROFILE 1.0.3") != 0) { 6174e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy if (strcmp(magicString, "JAVA PROFILE 1.0.2") == 0) { 6184e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy fprintf(stderr, "ERROR: HPROF file already in 1.0.2 format.\n"); 6194e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy } else { 6204e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy fprintf(stderr, "ERROR: expecting HPROF file format 1.0.3\n"); 6214e1205528c6047cd000b6c5617f8ea8ae3ede82aSiva Velusamy } 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* downgrade to 1.0.2 */ 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (ebGetBuffer(pBuf))[17] = '2'; 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebWriteData(pBuf, out) != 0) 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copy: 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (4b) identifier size, always 4 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (8b) file creation date 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebReadData(pBuf, in, 12, FALSE) != 0) 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebWriteData(pBuf, out) != 0) 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read records until we hit EOF. Each record begins with: 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (1b) type 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (4b) timestamp 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (4b) length of data that follows 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(ebGetLength(pBuf) == 0); 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read type char */ 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebReadData(pBuf, in, 1, TRUE) != 0) 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (feof(in)) 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read the rest of the header */ 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebReadData(pBuf, in, kRecHdrLen-1, FALSE) != 0) 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char* buf = ebGetBuffer(pBuf); 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned char type; 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int timestamp, length; 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type = buf[0]; 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project timestamp = get4BE(buf + 1); 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = get4BE(buf + 5); 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf = NULL; /* ptr invalid after next read op */ 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* read the record data */ 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length != 0) { 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebReadData(pBuf, in, length, FALSE) != 0) 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6743db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (type == HPROF_TAG_HEAP_DUMP 6753db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey || type == HPROF_TAG_HEAP_DUMP_SEGMENT) { 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("Processing heap dump 0x%02x (%d bytes)\n", 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project type, length); 6783db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (processHeapDump(pBuf, out, flags) != 0) 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebClear(pBuf); 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* keep */ 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DBUG("Keeping 0x%02x (%d bytes)\n", type, length); 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ebWriteData(pBuf, out) != 0) 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = 0; 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ebFree(pBuf); 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6963db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeystatic FILE* fopen_or_default(const char* path, const char* mode, FILE* def) { 6973db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (!strcmp(path, "-")) { 6983db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey return def; 6993db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } else { 7003db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey return fopen(path, mode); 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 7023db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey} 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7043db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeyint main(int argc, char** argv) 7053db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey{ 7063db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey FILE* in = NULL; 7073db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey FILE* out = NULL; 7083db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey int flags = 0; 7093db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey int res = 1; 7103db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey 7113db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey int opt; 7123db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey while ((opt = getopt(argc, argv, "z")) != -1) { 7133db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey switch (opt) { 7143db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey case 'z': 7153db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey flags |= kFlagAppOnly; 7163db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey break; 7173db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey case '?': 7183db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey default: 7193db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey goto usage; 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 7223db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey 7233db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey int i; 7243db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey for (i = optind; i < argc; i++) { 7253db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey char* arg = argv[i]; 7263db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (!in) { 7273db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey in = fopen_or_default(arg, "rb", stdin); 7283db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } else if (!out) { 7293db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey out = fopen_or_default(arg, "wb", stdout); 7303db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } else { 7313db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey goto usage; 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7353db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey if (in == NULL || out == NULL) { 7363db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey goto usage; 7373db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey } 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7393db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey res = filterData(in, out, flags); 7403db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey goto finish; 7413db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey 7423db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeyusage: 7433db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, "Usage: hprof-conf [-z] infile outfile\n"); 7443db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, "\n"); 7453db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, " -z: exclude non-app heaps, such as Zygote\n"); 7463db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, "\n"); 7473db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, "Specify '-' for either or both files to use stdin/stdout.\n"); 7483db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, "\n"); 7493db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey 7503db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey fprintf(stderr, 7513db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "Copyright (C) 2009 The Android Open Source Project\n\n" 7523db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "This software is built from source code licensed under the " 7533db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "Apache License,\n" 7543db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "Version 2.0 (the \"License\"). You may obtain a copy of the " 7553db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "License at\n\n" 7563db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey " http://www.apache.org/licenses/LICENSE-2.0\n\n" 7573db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "See the associated NOTICE file for this software for further " 7583db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey "details.\n"); 7593db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey res = 2; 7603db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey 7613db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkeyfinish: 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (in != stdin) 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(in); 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (out != stdout) 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(out); 7663db80b5708eeae9194ff5dc44005efc8b2a726f1Jeff Sharkey return res; 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 768