1 /*
   2  * Copyright (c) 2001, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores,
  20  * CA 94065 USA or visit www.oracle.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.bugspot;
  26 
  27 import sun.jvm.hotspot.debugger.*;
  28 import sun.jvm.hotspot.debugger.cdbg.*;
  29 
  30 /** Helper class for locating a program counter. Indicates the
  31     confidence of the find. */
  32 
  33 public class PCFinder {
  34   public static final int LOW_CONFIDENCE = 1;
  35   public static final int HIGH_CONFIDENCE = 2;
  36 
  37   public static class Info {
  38     private String name;
  39     private long   offset;
  40     private int    confidence;
  41 
  42     public Info(String name, long offset, int confidence) {
  43       this.name = name;
  44       this.offset = offset;
  45       this.confidence = confidence;
  46     }
  47 
  48     /** May be null */
  49     public String getName()       { return name;       }
  50 
  51     /** If this is -1, a symbol could not be found, and the offset
  52         should not be shown */
  53     public long   getOffset()     { return offset;     }
  54 
  55     /** PCFinder.LOW_CONFIDENCE or PCFinder.HIGH_CONFIDENCE */
  56     public int    getConfidence() { return confidence; }
  57   }
  58 
  59   /** Passed loadobject may be null in which case the returned Info
  60       object has low confidence */
  61   public static Info findPC(Address pc, LoadObject lo, CDebugger dbg) {
  62     if (lo == null) {
  63       return new Info(null, -1, LOW_CONFIDENCE);
  64     }
  65 
  66     // First try debug info
  67     BlockSym sym = lo.debugInfoForPC(pc);
  68     while (sym != null) {
  69       if (sym.isFunction()) {
  70         // Highest confidence
  71         return new Info(sym.toString(), pc.minus(sym.getAddress()), HIGH_CONFIDENCE);
  72       }
  73     }
  74 
  75     // Now try looking up symbol in loadobject
  76 
  77     // FIXME: must add support for mapfiles on Win32 and try looking
  78     // up there first if possible. Should we hide that behind
  79     // LoadObject.closestSymbolToPC and have the ClosestSymbol return
  80     // confidence? I think so. On Solaris there is no notion of a
  81     // mapfile, and the confidence for closestSymbolToPC will be high
  82     // instead of low.
  83 
  84     int confidence = HIGH_CONFIDENCE;
  85 
  86     ClosestSymbol cs = lo.closestSymbolToPC(pc);
  87     if (cs != null) {
  88       // FIXME: currently low confidence (only on Win32)
  89       return new Info(cs.getName() + "()", cs.getOffset(), LOW_CONFIDENCE);
  90     }
  91 
  92     // Unknown location
  93     return new Info(dbg.getNameOfFile(lo.getName()).toUpperCase() +
  94                     "! " + pc + "()", -1, HIGH_CONFIDENCE);
  95   }
  96 }