001 // This file is part of the program FRYSK. 002 // 003 // Copyright 2006, Red Hat Inc. 004 // 005 // FRYSK is free software; you can redistribute it and/or modify it 006 // under the terms of the GNU General Public License as published by 007 // the Free Software Foundation; version 2 of the License. 008 // 009 // FRYSK is distributed in the hope that it will be useful, but 010 // WITHOUT ANY WARRANTY; without even the implied warranty of 011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 // General Public License for more details. 013 // 014 // You should have received a copy of the GNU General Public License 015 // along with FRYSK; if not, write to the Free Software Foundation, 016 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 017 // 018 // In addition, as a special exception, Red Hat, Inc. gives You the 019 // additional right to link the code of FRYSK with code not covered 020 // under the GNU General Public License ("Non-GPL Code") and to 021 // distribute linked combinations including the two, subject to the 022 // limitations in this paragraph. Non-GPL Code permitted under this 023 // exception must only link to the code of FRYSK through those well 024 // defined interfaces identified in the file named EXCEPTION found in 025 // the source code files (the "Approved Interfaces"). The files of 026 // Non-GPL Code may instantiate templates or use macros or inline 027 // functions from the Approved Interfaces without causing the 028 // resulting work to be covered by the GNU General Public 029 // License. Only Red Hat, Inc. may make changes or additions to the 030 // list of Approved Interfaces. You must obey the GNU General Public 031 // License in all respects for all of the FRYSK code and other code 032 // used in conjunction with FRYSK except the Non-GPL Code covered by 033 // this exception. If you modify this file, you may extend this 034 // exception to your version of the file, but you are not obligated to 035 // do so. If you do not wish to provide this exception without 036 // modification, you must delete this exception statement from your 037 // version and license this file solely under the GPL without 038 // exception. 039 040 package frysk.stack; 041 042 public class FrameIdentifier { 043 private final long functionAddress; 044 private final long cfa; 045 046 /** 047 * Create a new FrameIdentifier. Identifies a stack frame based on 048 * its canonical frame address and function starting address. 049 * 050 * @param functionAddress The address of the start of the frame 051 * @param cfa The canonical frame address of the stack frame 052 */ 053 public FrameIdentifier (long functionAddress, long cfa) { 054 this.functionAddress = functionAddress; 055 this.cfa = cfa; 056 } 057 058 /** 059 * Returns true if this FrameIdentifier is inner to the parameter. 060 * 061 * @param fi The FrameIdentifier to compare to 062 * @return true If this is inner to fi 063 */ 064 public boolean innerTo (FrameIdentifier fi) { 065 return this.cfa < fi.cfa; 066 } 067 068 /** 069 * Returns true if this FrameIdentifier is outer to the parameter. 070 * 071 * @param fi The FrameIdentifier to compare to 072 * @return true If this is outer to fi 073 */ 074 public boolean outerTo (FrameIdentifier fi) { 075 return this.cfa > fi.cfa; 076 } 077 078 /** 079 * Compares this FrameIdentifier to the parameter and returns true if 080 * both the cfa and function address match. 081 * 082 * It is important to use the function address instead of the 083 * stack frame's current address because that address may change 084 * in the lifetime of * a stack frame, and thus this method could 085 * potentially return false if * one of the frames had been 086 * stepped and the other was not. Using the * frame start address 087 * guarantees that if two StackFrames are compared, * and they 088 * both represent the same frame on the stack, this method will * 089 * return true regardless of the state of either frame. 090 * 091 * @param fi The FrameIdentifier to compare to. 092 * @return true If the cfa and function address belonging to this 093 * FrameIdentifier match the cfa and function address in the parameter. 094 */ 095 public boolean equals (Object fi) { 096 if (! (fi instanceof FrameIdentifier)) 097 return false; 098 099 FrameIdentifier rhs = (FrameIdentifier) fi; 100 return (this.cfa == rhs.cfa 101 && this.functionAddress == rhs.functionAddress); 102 } 103 104 /** 105 * Returns the function address from this FrameIdentifier 106 * 107 * @return functionAddress The start address of the frame 108 * represented by this FrameIdentifier 109 */ 110 public long getFunctionAddress () { 111 return this.functionAddress; 112 } 113 114 /** 115 * Returns a hashCode for this object 116 */ 117 public int hashCode () { 118 return (int) (this.cfa ^ this.functionAddress); 119 } 120 121 /** 122 * Displays customized String output. 123 */ 124 public String toString () { 125 StringBuffer buffer = new StringBuffer(); 126 buffer.append("{"); 127 buffer.append(super.toString()); 128 buffer.append(",functionAddress="); 129 buffer.append(this.functionAddress); 130 buffer.append(",cfa="); 131 buffer.append(this.cfa); 132 buffer.append("}"); 133 134 return buffer.toString(); 135 } 136 137 }