OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [gnu/] [gcj/] [tools/] [gc_analyze/] [MemoryMap.java] - Blame information for rev 756

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 756 jeremybenn
/* MemoryMap.java -- Maps address ranges to their data.
2
   Copyright (C) 2007  Free Software Foundation
3
 
4
   This file is part of libgcj.
5
 
6
   This software is copyrighted work licensed under the terms of the
7
   Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
8
   details.  */
9
 
10
package gnu.gcj.tools.gc_analyze;
11
 
12
import java.io.BufferedReader;
13
import java.io.EOFException;
14
import java.io.File;
15
import java.io.IOException;
16
import java.io.RandomAccessFile;
17
import java.nio.ByteBuffer;
18
import java.nio.ByteOrder;
19
import java.nio.channels.FileChannel;
20
import java.util.Comparator;
21
import java.util.HashMap;
22
import java.util.SortedSet;
23
import java.util.TreeSet;
24
 
25
/**
26
 * Reads /proc/self/maps output from dump file.
27
 * Creates map of <filename> to Range.
28
 *
29
 * Returns filename given address.
30
 * Returns offset given address.
31
 * Returns BytePtr given address.
32
 *
33
 */
34
class MemoryMap
35
{
36
  static class RangeComparator implements Comparator<Range>
37
  {
38
    public int compare(Range r1, Range r2)
39
    {
40
      if (r2.end == 0 && r1.end != 0)
41
        return -compare(r2, r1);
42
 
43
      if (r1.begin < r2.begin)
44
        return -1;
45
      else if (r1.begin >= r2.end)
46
        return 1;
47
      else
48
        return 0;
49
    }
50
  }
51
 
52
  static class Range
53
  {
54
    long begin;
55
    long end;
56
 
57
    long offset;
58
    String filename;
59
    Range()
60
    {
61
    }
62
 
63
    Range(long b, long e, String s, long o)
64
    {
65
      begin = b;
66
      end = e;
67
      filename = s;
68
      offset = o;
69
    }
70
  }
71
 
72
  /**
73
   * Parse the string as an unsigned hexadecimal number.  This is
74
   * similar to Long.parseInt(s,16), but without the restriction that
75
   * values that have the sign bit set not being allowed.
76
   *
77
   * @param s the number as a String.
78
   * @return the number.
79
   */
80
  static long parseHexLong(String s)
81
  {
82
    if (s.length() > 16)
83
      throw new NumberFormatException();
84
    long r = 0;
85
    for (int i = 0; i < s.length(); i++)
86
      {
87
        int digit = 0;
88
        char c = s.charAt(i);
89
        switch (c)
90
          {
91
          case '0':
92
          case '1':
93
          case '2':
94
          case '3':
95
          case '4':
96
          case '5':
97
          case '6':
98
          case '7':
99
          case '8':
100
          case '9':
101
            digit = c - '0';
102
            break;
103
          case 'a':
104
          case 'b':
105
          case 'c':
106
          case 'd':
107
          case 'e':
108
          case 'f':
109
            digit = 10 + c - 'a';
110
            break;
111
          case 'A':
112
          case 'B':
113
          case 'C':
114
          case 'D':
115
          case 'E':
116
          case 'F':
117
            digit = 10 + c - 'A';
118
            break;
119
          default:
120
            throw new NumberFormatException();
121
          }
122
        r = (r << 4) + digit;
123
      }
124
    return r;
125
  }
126
 
127
  // String filename -> Range
128
  TreeSet<Range> map = new TreeSet<Range>(new RangeComparator());
129
  HashMap<String, SymbolTable> symbolTables =
130
    new HashMap<String, SymbolTable>();
131
  ByteOrder byteOrder;
132
  int wordSize;
133
 
134
  public MemoryMap(BufferedReader reader,
135
                   String rawFileName) throws IOException
136
  {
137
    FileChannel raw = (new RandomAccessFile(rawFileName, "r")).getChannel();
138
    ByteBuffer buf = ByteBuffer.allocate(8);
139
    raw.read(buf);
140
    if (buf.hasRemaining())
141
      {
142
        raw.close();
143
        throw new EOFException();
144
      }
145
    buf.flip();
146
    wordSize = buf.get();
147
 
148
    if (wordSize == 8 || wordSize == 4)
149
      byteOrder = ByteOrder.LITTLE_ENDIAN;
150
    else
151
      {
152
        byteOrder = ByteOrder.BIG_ENDIAN;
153
        buf.rewind();
154
        wordSize = buf.getInt();
155
        if (0 == wordSize)
156
          wordSize = buf.getInt();
157
      }
158
    switch (wordSize)
159
      {
160
      case 4:
161
      case 8:
162
        break;
163
      default:
164
        throw new IOException("Bad .bytes file header");
165
      }
166
    buf = ByteBuffer.allocate(3 * wordSize);
167
    buf.order(byteOrder);
168
    raw.position(0L);
169
 
170
    for(;;)
171
      {
172
        // Read the block header.
173
        buf.clear();
174
        if (-1 == raw.read(buf))
175
          {
176
            //EOF
177
            raw.close();
178
            break;
179
          }
180
        if (buf.hasRemaining())
181
          {
182
            raw.close();
183
            throw new EOFException();
184
          }
185
        buf.flip();
186
        long dummy
187
          = (wordSize == 4) ? (buf.getInt() & 0xffffffffL) : buf.getLong();
188
        if (dummy != wordSize)
189
          throw new IOException("Bad .bytes file header");
190
        long start
191
          = wordSize == 4 ? (buf.getInt() & 0xffffffffL) : buf.getLong();
192
        long length
193
          = wordSize == 4 ? (buf.getInt() & 0xffffffffL) : buf.getLong();
194
        if (length < 0L)
195
          throw new IOException("Bad .bytes file header");
196
 
197
        long currentPos = raw.position();
198
        raw.position(currentPos + length);
199
 
200
        Range range = new Range(start, start + length,
201
                                rawFileName, currentPos);
202
        map.add(range);
203
      }
204
 
205
    for (;;)
206
      {
207
        String s = reader.readLine();
208
        if (s == null)
209
          break;
210
        if (s.indexOf("Begin address map") >= 0)
211
          {
212
            for (;;)
213
              {
214
                s = reader.readLine();
215
                if (s.indexOf("End address map") >= 0)
216
                  {
217
                    dump();
218
                    return;
219
                  }
220
                int endOfAddress = s.indexOf('-');
221
                long address = parseHexLong(s.substring(0, endOfAddress));
222
                int endOfAddress2 = s.indexOf(' ', endOfAddress + 1);
223
                long address2 = parseHexLong(s.substring(endOfAddress + 1,
224
                                                         endOfAddress2));
225
                int endOfOffset = s.indexOf(' ', endOfAddress2 + 6);
226
                long offset;
227
                try
228
                  {
229
                    offset = parseHexLong(s.substring(endOfAddress2 + 6,
230
                                                      endOfOffset));
231
                  }
232
                catch (Exception e)
233
                  {
234
                    offset = 0;
235
                  }
236
                int end = s.indexOf('/');
237
 
238
                if (end > 0)
239
                  {
240
                    String file = s.substring(end);
241
                    if (file.startsWith("/dev/"))
242
                      continue;
243
 
244
                    Range r = new Range(address, address2, file, offset);
245
                    if (offset == 0)
246
                      {
247
                        // Read the file's symbol table
248
                        try
249
                          {
250
                            File f = ToolPrefix.fileForName(file);
251
                            if (f != null)
252
                              {
253
                                SymbolTable st = new SymbolTable(f.getPath());
254
                                if (st.loadAddr != address)
255
                                  st.relocation = address - st.loadAddr;
256
                                symbolTables.put(file, st);
257
                              }
258
                          }
259
                        catch (Exception ex)
260
                          {
261
                            ex.printStackTrace();
262
                          }
263
                      }
264
                    map.add(r);
265
                  }
266
              } // inner loop
267
          } // started inner loop
268
      } // outer loop - finding begin
269
  } // memoryMap
270
 
271
 
272
  public void dump()
273
  {
274
    System.out.println("MemoryMap:");
275
    for (Range r : map)
276
      {
277
        System.out.println(Long.toHexString(r.begin) + "-"
278
                           + Long.toHexString(r.end) + " -> "
279
                           + r.filename + " offset "
280
                           + Long.toHexString(r.offset));
281
      }
282
  }
283
 
284
  Range getRange(long addr)
285
  {
286
    Range r = new Range();
287
    r.begin = addr;
288
    SortedSet<Range> t = map.tailSet(r);
289
    if (t.isEmpty())
290
      return null;
291
    Range c = t.first();
292
    if (c.begin <= addr && addr < c.end)
293
      return c;
294
    return null;
295
  }
296
 
297
  String getFile(long addr)
298
  {
299
    Range r = getRange(addr);
300
    if (null != r)
301
      return r.filename;
302
    return null;
303
  }
304
 
305
  long getOffset(long addr)
306
  {
307
    Range r = getRange(addr);
308
    if (null != r)
309
      return r.offset;
310
    return 0L;
311
  }
312
 
313
  /**
314
   * @return BytePtr which includes given address.
315
   */
316
  BytePtr getBytePtr(long addr, int length) throws IOException
317
  {
318
    Range r = getRange(addr);
319
 
320
    if (null == r)
321
      return null;
322
 
323
    File f = ToolPrefix.fileForName(r.filename);
324
    if (null == f)
325
      return null;
326
 
327
    if (addr + length > r.end)
328
      length = (int)(r.end - addr);
329
 
330
    ByteBuffer b = ByteBuffer.allocate(length);
331
    b.order(byteOrder);
332
 
333
    FileChannel fc = (new RandomAccessFile(f, "r")).getChannel();
334
    fc.position(r.offset + addr - r.begin);
335
    int nr = fc.read(b);
336
    fc.close();
337
    if (nr != length)
338
      return null;
339
    b.flip();
340
    return new BytePtr(b, wordSize);
341
  }
342
 
343
  public String getSymbol(long addr)
344
  {
345
    Range r = getRange(addr);
346
 
347
    if (r == null)
348
      return null;
349
 
350
    SymbolTable st = symbolTables.get(r.filename);
351
    if (st == null)
352
      return null;
353
 
354
    // Apply relocation
355
    addr -= st.relocation;
356
 
357
    return st.getSymbol(addr);
358
  }
359
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.