1 /* 2 * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 package sun.jvm.hotspot.debugger.posix; 25 26 import sun.jvm.hotspot.debugger.*; 27 import sun.jvm.hotspot.debugger.cdbg.*; 28 import sun.jvm.hotspot.debugger.posix.elf.*; 29 import sun.jvm.hotspot.utilities.memo.*; 30 31 /** Provides a simple wrapper around the ELF library which handles 32 relocation. */ 33 public abstract class DSO implements LoadObject { 34 35 private MemoizedObject file; // contains ELFFile 36 private String filename; 37 private Address addr; 38 private long size; 39 private IsDSO dso = new IsDSO(); 40 41 class IsDSO extends MemoizedBoolean { 42 protected boolean computeValue() { 43 return getFile().getHeader().getFileType() == ELFHeader.FT_DYN; 44 } 45 }; 46 47 class ELFFileByName extends MemoizedObject { 48 protected Object computeValue() { 49 return ELFFileParser.getParser().parse(DSO.this.filename); 50 } 51 }; 52 53 class ELFFileByAddress extends MemoizedObject { 54 protected Object computeValue() { 55 return ELFFileParser.getParser().parse(new AddressDataSource(DSO.this.addr)); 56 } 57 }; 58 59 public DSO(String filename, long size, Address relocation) throws ELFException { 60 this.filename = filename; 61 this.size = size; 62 this.addr = relocation; 63 this.file = new ELFFileByName(); 64 } 65 66 public DSO(long size, Address relocation) throws ELFException { 67 this.addr = relocation; 68 this.size = size; 69 this.file = new ELFFileByAddress(); 70 } 71 72 public String getName() { 73 return filename; 74 } 75 76 public Address getBase() { 77 return addr; 78 } 79 80 /** if this .so is unloaded and re-loaded in the same process at a different 81 base, change the base by calling this to avoid re-parsing the ELF. */ 82 public void setBase(Address newBase) { 83 addr = newBase; 84 if (filename == null) { 85 // ELFFile was created by address. we have to re-parse it. 86 file = new ELFFileByAddress(); 87 dso = new IsDSO(); 88 } 89 } 90 91 public long getSize() { 92 return size; 93 } 94 95 public CDebugInfoDataBase getDebugInfoDataBase() throws DebuggerException { 96 // FIXME: after stabs parser 97 return null; 98 } 99 100 public BlockSym debugInfoForPC(Address pc) throws DebuggerException { 101 // FIXME: after stabs parser 102 return null; 103 } 104 105 public ClosestSymbol closestSymbolToPC(Address pcAsAddr) throws DebuggerException { 106 boolean dso = isDSO(); 107 long offset = dso? pcAsAddr.minus(addr) : getAddressValue(pcAsAddr); 108 ELFSymbol sym = getFile().getHeader().getELFSymbol(offset); 109 return (sym != null)? createClosestSymbol(sym.getName(), offset - sym.getValue()) : null; 110 } 111 112 public LineNumberInfo lineNumberForPC(Address pc) throws DebuggerException { 113 // FIXME: after stabs parser 114 return null; 115 } 116 117 /** return true if file is a .so */ 118 public boolean isDSO() { 119 return dso.getValue(); 120 } 121 122 /** Look up a symbol; returns absolute address or null if symbol was 123 not found. */ 124 public Address lookupSymbol(String symbol) throws ELFException { 125 ELFSymbol sym = getFile().getHeader().getELFSymbol(symbol); 126 if (sym == null) { 127 return null; 128 } 129 130 long value = sym.getValue(); 131 if (isDSO()) { 132 return addr.addOffsetTo(value); 133 } else { 134 return newAddress(value); 135 } 136 } 137 138 public boolean equals(Object o) { 139 if (o == null || !(o instanceof DSO)) { 140 return false; 141 } 142 DSO other = (DSO)o; 143 return getBase().equals(other.getBase()); 144 } 145 146 public int hashCode() { 147 return getBase().hashCode(); 148 } 149 150 protected ELFFile getFile() { 151 return (ELFFile) file.getValue(); 152 } 153 154 protected abstract Address newAddress(long addr); 155 protected abstract long getAddressValue(Address addr); 156 157 protected ClosestSymbol createClosestSymbol(String name, long diff) { 158 return new ClosestSymbol(name, diff); 159 } 160 }