1/* 2 Title: scanaddrs.h - Scan addresses in objects 3 4 Copyright (c) 2006-8, 2012, 2015, 2018 David C.J. Matthews 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License version 2.1 as published by the Free Software Foundation. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19*/ 20 21#ifndef SCANADDRS_H_INCLUDED 22#define SCANADDRS_H_INCLUDED 23 24#include "globals.h" 25 26// Type of relocations. 27typedef enum { 28 PROCESS_RELOC_DIRECT = 0, // 32 or 64 bit address of target 29 PROCESS_RELOC_I386RELATIVE // 32 or 64 bit relative address 30} ScanRelocationKind; 31 32class StackSpace; 33 34class ScanAddress { 35public: 36 virtual ~ScanAddress() {} // Keeps gcc happy 37 38protected: 39 // Scan an address in the memory. "pt" always points into an object. 40 // It is not called with pt pointing at a C++ automatic variable. 41 // Tagged integers have already been filtered out. 42 // The result is the length word of the object to use if the object 43 // is to be processed recursively or 0 if it should not be. 44 // Default action - call ScanObjectAddress for the base object address of 45 // the address. 46 virtual POLYUNSIGNED ScanAddressAt(PolyWord *pt); 47 48 // As for ScanAddressAt except that the value is a pointer to the first word in a closure object. 49 // In most cases we're just scanning the heap we don't need to do anything and we scan 50 // the code area separately. 51 virtual POLYUNSIGNED ScanCodeAddressAt(PolyObject **pt) { return 0; } 52 53public: 54 // The fundamental overridable for this class. Takes the object address and returns 55 // the updated address. If nothing else is overridden everything eventually comes here. 56 virtual PolyObject *ScanObjectAddress(PolyObject *base) = 0;// { return base; } 57 58 typedef enum { STRENGTH_STRONG = 0, STRENGTH_WEAK = 1 } RtsStrength; 59 60 // Scan an address in the run-time system. This normally just applies ScanObjectAddress 61 // but if this is a weak reference it can set *pt to NULL 62 virtual void ScanRuntimeAddress(PolyObject **pt, RtsStrength weak) 63 { *pt = ScanObjectAddress(*pt); } 64 65 // Scan a word in the run-time system. This is the preferred call for non-weak 66 // references and deals with the general case of a word. 67 void ScanRuntimeWord(PolyWord *w); 68 69 // Process a constant within the code. 70 // The default action is to call the DEFAULT ScanAddressAt NOT the virtual which means that it calls 71 // ScanObjectAddress for the base address of the object referred to. 72 virtual void ScanConstant(PolyObject *base, byte *addressOfConstant, ScanRelocationKind code); 73 74 // Scan the objects in the region and process their addresses. Applies ScanAddressesInObject 75 // to each of the objects. The "region" argument points AT the first length word. 76 // Typically used to scan or update addresses in the mutable area. 77 void ScanAddressesInRegion(PolyWord *region, PolyWord *endOfRegion); 78 79 // General object processor. 80 // If the object is a word object calls ScanAddressesAt for all the addresses. 81 // 82 // If the object is a code object calls ScanAddressesAt for the constant area and 83 // calls (indirectly) ScanConstant, and by default ScanObjectAddress for addresses within 84 // the code 85 // 86 // If the object is a stack calls ScanStackAddress which calls ScanObjectAddress for 87 // addresses within the code. 88 virtual void ScanAddressesInObject(PolyObject *base, POLYUNSIGNED lengthWord); 89 90 void ScanAddressesInObject(PolyObject *base) { ScanAddressesInObject(base, base->LengthWord()); } 91 92 // Extract a constant from the code. 93#ifdef POLYML32IN64 94 static PolyObject *GetConstantValue(byte *addressOfConstant, ScanRelocationKind code, PolyWord *base = globalHeapBase); 95#else 96 static PolyObject *GetConstantValue(byte *addressOfConstant, ScanRelocationKind code, PolyWord *base = 0); 97#endif 98 // Store a constant in the code. 99 static void SetConstantValue(byte *addressOfConstant, PolyObject *p, ScanRelocationKind code); 100}; 101 102#endif 103