michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "adreader.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: ADLog::ADLog() michael@0: : mEntryCount(0) michael@0: { michael@0: mEntries.mNext = static_cast(&mEntries); michael@0: mEntries.mPrev = static_cast(&mEntries); michael@0: } michael@0: michael@0: ADLog::~ADLog() michael@0: { michael@0: for (const_iterator entry = begin(), entry_end = end(); michael@0: entry != entry_end; ++entry) { michael@0: free((void*) (*entry)->type); michael@0: free((char*) (*entry)->data); michael@0: free((char*) (*entry)->allocation_stack); michael@0: } michael@0: michael@0: for (EntryBlock *b = mEntries.mNext, *next; b != &mEntries; b = next) { michael@0: next = b->mNext; michael@0: delete b; michael@0: } michael@0: } michael@0: michael@0: bool michael@0: ADLog::Read(const char* aFileName) michael@0: { michael@0: FILE *in = fopen(aFileName, "r"); michael@0: if (!in) { michael@0: return false; michael@0: } michael@0: michael@0: while (!feof(in)) { michael@0: unsigned int ptr; michael@0: char typebuf[256]; michael@0: int datasize; michael@0: int res = fscanf(in, "%x %s (%d)\n", &ptr, typebuf, &datasize); michael@0: if (res == EOF) michael@0: break; michael@0: if (res != 3) { michael@0: return false; michael@0: } michael@0: michael@0: size_t data_mem_size = ((datasize + sizeof(unsigned long) - 1) / michael@0: sizeof(unsigned long)) * sizeof(unsigned long); michael@0: char *data = (char*)malloc(data_mem_size); michael@0: michael@0: for (size_t *cur_data = (size_t*) data, michael@0: *cur_data_end = (size_t*) ((char*)data + data_mem_size); michael@0: cur_data != cur_data_end; ++cur_data) { michael@0: res = fscanf(in, " %zX\n", cur_data); michael@0: if (res != 1) { michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: char stackbuf[100000]; michael@0: stackbuf[0] = '\0'; michael@0: michael@0: char *stack = stackbuf; michael@0: int len; michael@0: do { michael@0: fgets(stack, sizeof(stackbuf) - (stack - stackbuf), in); michael@0: len = strlen(stack); michael@0: stack += len; michael@0: } while (len > 1); michael@0: michael@0: if (mEntryCount % ADLOG_ENTRY_BLOCK_SIZE == 0) { michael@0: EntryBlock *new_block = new EntryBlock(); michael@0: new_block->mNext = static_cast(&mEntries); michael@0: new_block->mPrev = mEntries.mPrev; michael@0: mEntries.mPrev->mNext = new_block; michael@0: mEntries.mPrev = new_block; michael@0: } michael@0: michael@0: size_t typelen = strlen(typebuf); michael@0: char *type = (char*)malloc(typelen-1); michael@0: strncpy(type, typebuf+1, typelen-2); michael@0: type[typelen-2] = '\0'; michael@0: michael@0: Entry *entry = michael@0: &mEntries.mPrev->entries[mEntryCount % ADLOG_ENTRY_BLOCK_SIZE]; michael@0: entry->address = (Pointer) (uintptr_t) ptr; michael@0: entry->type = type; michael@0: entry->datasize = datasize; michael@0: entry->data = data; michael@0: entry->allocation_stack = strdup(stackbuf); michael@0: michael@0: ++mEntryCount; michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: ADLog::const_iterator::const_iterator(ADLog::EntryBlock *aBlock, michael@0: size_t aOffset) michael@0: { michael@0: SetBlock(aBlock); michael@0: mCur = mBlockStart + aOffset; michael@0: } michael@0: michael@0: ADLog::const_iterator& michael@0: ADLog::const_iterator::operator++() michael@0: { michael@0: ++mCur; michael@0: if (mCur == mBlockEnd) { michael@0: SetBlock(mBlock->mNext); michael@0: mCur = mBlockStart; michael@0: } michael@0: michael@0: return *this; michael@0: } michael@0: michael@0: ADLog::const_iterator& michael@0: ADLog::const_iterator::operator--() michael@0: { michael@0: if (mCur == mBlockStart) { michael@0: SetBlock(mBlock->mPrev); michael@0: mCur = mBlockEnd; michael@0: } michael@0: --mCur; michael@0: michael@0: return *this; michael@0: }