1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
|
/*
Title: scanaddrs.h - Scan addresses in objects
Copyright (c) 2006-8 David C.J. Matthews
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SCANADDRS_H_INCLUDED
#define SCANADDRS_H_INCLUDED
#include "globals.h"
// Type of relocations. N.B. These values are built into saved states. Either add
// new entries to the end or update the saved state version number.
typedef enum {
PROCESS_RELOC_DIRECT = 0, // 32 or 64 bit address of target
PROCESS_RELOC_I386RELATIVE, // 32 or 64 bit relative address
PROCESS_RELOC_PPCDUAL16SIGNED, // Power PC - two consecutive words - second is signed.
PROCESS_RELOC_PPCDUAL16UNSIGNED, // Power PC - two consecutive words - second is unsigned
PROCESS_RELOC_SPARCDUAL, // SPARC - two consecutive words
PROCESS_RELOC_SPARCRELATIVE // Sparc - 30 bit relative address
} ScanRelocationKind;
class ScanAddress {
public:
virtual ~ScanAddress() {} // Keeps gcc happy
protected:
// Scan an address in the memory. "pt" always points into an object.
// It is not called with pt pointing at a C++ automatic variable.
// Tagged integers have already been filtered out.
// The result is the length word of the object to use if the object
// is to be processed recursively or 0 if it should not be.
// Default action - call ScanObjectAddress for the base object address of
// the address.
virtual POLYUNSIGNED ScanAddressAt(PolyWord *pt);
public:
// The fundamental overridable for this class. Takes the object address and returns
// the updated address. If nothing else is overridden everything eventually comes here.
virtual PolyObject *ScanObjectAddress(PolyObject *base) = 0;// { return base; }
typedef enum { STRENGTH_STRONG = 0, STRENGTH_WEAK = 1 } RtsStrength;
// Scan an address in the run-time system. This normally just applies ScanObjectAddress
// but if this is a weak reference it can set *pt to NULL
virtual void ScanRuntimeAddress(PolyObject **pt, RtsStrength weak)
{ *pt = ScanObjectAddress(*pt); }
// Process a constant within the code.
// The default action is to call the DEFAULT ScanAddressAt NOT the virtual which means that it calls
// ScanObjectAddress for the base address of the object referred to.
virtual void ScanConstant(byte *addressOfConstant, ScanRelocationKind code);
// Scan the objects in the region and process their addresses. Applies ScanAddressesInObject
// to each of the objects. The "region" argument points AT the first length word.
// Typically used to scan or update addresses in the mutable area.
void ScanAddressesInRegion(PolyWord *region, PolyWord *endOfRegion);
protected:
// General object processor.
// If the object is a word object calls ScanAddressesAt for all the addresses.
//
// If the object is a code object calls ScanAddressesAt for the constant area and
// calls (indirectly) ScanConstant, and by default ScanObjectAddress for addresses within
// the code
//
// If the object is a stack calls ScanStackAddress which calls ScanObjectAddress for
// addresses within the code.
virtual void ScanAddressesInObject(PolyObject *base, POLYUNSIGNED lengthWord);
void ScanAddressesInObject(PolyObject *base) { ScanAddressesInObject(base, base->LengthWord()); }
// Process a word found on the stack and return the (updated) value. Stacks may contain
// code addresses and addresses within the current stack. "isCode" is set to true for
// the program counter which may be a code address but not satisfy IsCodeObject.
// The default action is to ignore integers and addresses within the stack and to call
// ScanObjectAddress for the base addresses of all other addresses.
PolyWord ScanStackAddress(PolyWord val, StackObject *base, bool isCode);
// Extract a constant from the code.
static PolyWord GetConstantValue(byte *addressOfConstant, ScanRelocationKind code);
public:
// Store a constant in the code.
static void SetConstantValue(byte *addressOfConstant, PolyWord p, ScanRelocationKind code);
};
#endif
|