/* Metallurgy - Higher Level Interface to Chordata * Copyright (C) 2001-2002 Jay Freeman (saurik) */ /* * Redistribution and use in source and binary * forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the * above copyright notice, this list of conditions * and the following disclaimer. * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions * and the following disclaimer in the documentation * and/or other materials provided with the * distribution. * 3. The name of the author may not be used to endorse * or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "stdafx.h" #include "metallurgy/Method.h" #include "metallurgy/ILMethodImpl.h" #include "chordata/ILMethod.h" using namespace Chordata::ILMethod; #include "filet/Utils.h" namespace Metallurgy { ILMethodImpl::ILMethodImpl(const Method *method, uint32_t coderva, uint32_t flags) : MethodImpl(method, coderva, flags), locals(NULL) { if (getCodeRVA() != 0) { offset = (uint8_t *) module->FindRVA(getCodeRVA()); switch (*offset & Flags::FormatMask) { case Flags::TinyFormat: case Flags::TinyFormat1: length = ((Tiny *) offset++)->size; break; case Flags::FatFormat: { // Oh come now... don't tell me you don't know Fat Tony! Fat *tony = (Fat *) offset; length = tony->CodeSize; locals = dynamic_cast(module->ResolveToken(tony->LocalVarSigTok)); uint32_t distance(length); uint8_t *section = offset += tony->Size * 4; if (tony->Flags & Flags::MoreSects) { do { section = Filet::Utils::AlignPointer(section + distance); bool isFat; if (*section & Section::Flags::FatFormat) { distance = ((Section::Fat *) section)->DataSize; isFat = true; } else { distance = ((Section::Small *) section)->DataSize; isFat = false; } switch (*section & (uint8_t) Section::Flags::KindMask) { case Section::Flags::EHTable: uint8_t *end = distance + (uint8_t *) section; if (isFat) { Section::Exception::FatHandler *sect = (Section::Exception::FatHandler *) section; for (Section::Exception::FatHandlerClause *clause = sect->Clauses; (uint8_t *) clause < end; clause++) m_Exceptions.push_back(Exception(offset, clause)); } else { Section::Exception::SmallHandler *sect = (Section::Exception::SmallHandler *) section; for (Section::Exception::SmallHandlerClause *clause = sect->Clauses; (uint8_t *) clause < end; clause++) m_Exceptions.push_back(Exception(offset, clause)); } break; } } while (*section & (uint8_t) Section::Flags::MoreSects); } } break; default: std::cerr << "Unsupported method format." << std::endl ; break; } data.assign(reinterpret_cast(offset), length); } } uint8_t *ILMethodImpl::getOffset() const { return offset; } uint32_t ILMethodImpl::getLength() const { return length; } StandAlone *ILMethodImpl::getLocals() const { return locals; } menes::bytebuf ILMethodImpl::getData() const { return data; } const ILMethodImpl::ExceptionVector &ILMethodImpl::getExceptions() const { return m_Exceptions; } }