From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- libjava/gnu/gcj/tools/gc_analyze/MemoryMap.java | 359 ++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 libjava/gnu/gcj/tools/gc_analyze/MemoryMap.java (limited to 'libjava/gnu/gcj/tools/gc_analyze/MemoryMap.java') diff --git a/libjava/gnu/gcj/tools/gc_analyze/MemoryMap.java b/libjava/gnu/gcj/tools/gc_analyze/MemoryMap.java new file mode 100644 index 000000000..1bc06d584 --- /dev/null +++ b/libjava/gnu/gcj/tools/gc_analyze/MemoryMap.java @@ -0,0 +1,359 @@ +/* MemoryMap.java -- Maps address ranges to their data. + Copyright (C) 2007 Free Software Foundation + + This file is part of libgcj. + + This software is copyrighted work licensed under the terms of the + Libgcj License. Please consult the file "LIBGCJ_LICENSE" for + details. */ + +package gnu.gcj.tools.gc_analyze; + +import java.io.BufferedReader; +import java.io.EOFException; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.util.Comparator; +import java.util.HashMap; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * Reads /proc/self/maps output from dump file. + * Creates map of to Range. + * + * Returns filename given address. + * Returns offset given address. + * Returns BytePtr given address. + * + */ +class MemoryMap +{ + static class RangeComparator implements Comparator + { + public int compare(Range r1, Range r2) + { + if (r2.end == 0 && r1.end != 0) + return -compare(r2, r1); + + if (r1.begin < r2.begin) + return -1; + else if (r1.begin >= r2.end) + return 1; + else + return 0; + } + } + + static class Range + { + long begin; + long end; + + long offset; + String filename; + Range() + { + } + + Range(long b, long e, String s, long o) + { + begin = b; + end = e; + filename = s; + offset = o; + } + } + + /** + * Parse the string as an unsigned hexadecimal number. This is + * similar to Long.parseInt(s,16), but without the restriction that + * values that have the sign bit set not being allowed. + * + * @param s the number as a String. + * @return the number. + */ + static long parseHexLong(String s) + { + if (s.length() > 16) + throw new NumberFormatException(); + long r = 0; + for (int i = 0; i < s.length(); i++) + { + int digit = 0; + char c = s.charAt(i); + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + digit = c - '0'; + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + digit = 10 + c - 'a'; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + digit = 10 + c - 'A'; + break; + default: + throw new NumberFormatException(); + } + r = (r << 4) + digit; + } + return r; + } + + // String filename -> Range + TreeSet map = new TreeSet(new RangeComparator()); + HashMap symbolTables = + new HashMap(); + ByteOrder byteOrder; + int wordSize; + + public MemoryMap(BufferedReader reader, + String rawFileName) throws IOException + { + FileChannel raw = (new RandomAccessFile(rawFileName, "r")).getChannel(); + ByteBuffer buf = ByteBuffer.allocate(8); + raw.read(buf); + if (buf.hasRemaining()) + { + raw.close(); + throw new EOFException(); + } + buf.flip(); + wordSize = buf.get(); + + if (wordSize == 8 || wordSize == 4) + byteOrder = ByteOrder.LITTLE_ENDIAN; + else + { + byteOrder = ByteOrder.BIG_ENDIAN; + buf.rewind(); + wordSize = buf.getInt(); + if (0 == wordSize) + wordSize = buf.getInt(); + } + switch (wordSize) + { + case 4: + case 8: + break; + default: + throw new IOException("Bad .bytes file header"); + } + buf = ByteBuffer.allocate(3 * wordSize); + buf.order(byteOrder); + raw.position(0L); + + for(;;) + { + // Read the block header. + buf.clear(); + if (-1 == raw.read(buf)) + { + //EOF + raw.close(); + break; + } + if (buf.hasRemaining()) + { + raw.close(); + throw new EOFException(); + } + buf.flip(); + long dummy + = (wordSize == 4) ? (buf.getInt() & 0xffffffffL) : buf.getLong(); + if (dummy != wordSize) + throw new IOException("Bad .bytes file header"); + long start + = wordSize == 4 ? (buf.getInt() & 0xffffffffL) : buf.getLong(); + long length + = wordSize == 4 ? (buf.getInt() & 0xffffffffL) : buf.getLong(); + if (length < 0L) + throw new IOException("Bad .bytes file header"); + + long currentPos = raw.position(); + raw.position(currentPos + length); + + Range range = new Range(start, start + length, + rawFileName, currentPos); + map.add(range); + } + + for (;;) + { + String s = reader.readLine(); + if (s == null) + break; + if (s.indexOf("Begin address map") >= 0) + { + for (;;) + { + s = reader.readLine(); + if (s.indexOf("End address map") >= 0) + { + dump(); + return; + } + int endOfAddress = s.indexOf('-'); + long address = parseHexLong(s.substring(0, endOfAddress)); + int endOfAddress2 = s.indexOf(' ', endOfAddress + 1); + long address2 = parseHexLong(s.substring(endOfAddress + 1, + endOfAddress2)); + int endOfOffset = s.indexOf(' ', endOfAddress2 + 6); + long offset; + try + { + offset = parseHexLong(s.substring(endOfAddress2 + 6, + endOfOffset)); + } + catch (Exception e) + { + offset = 0; + } + int end = s.indexOf('/'); + + if (end > 0) + { + String file = s.substring(end); + if (file.startsWith("/dev/")) + continue; + + Range r = new Range(address, address2, file, offset); + if (offset == 0) + { + // Read the file's symbol table + try + { + File f = ToolPrefix.fileForName(file); + if (f != null) + { + SymbolTable st = new SymbolTable(f.getPath()); + if (st.loadAddr != address) + st.relocation = address - st.loadAddr; + symbolTables.put(file, st); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + map.add(r); + } + } // inner loop + } // started inner loop + } // outer loop - finding begin + } // memoryMap + + + public void dump() + { + System.out.println("MemoryMap:"); + for (Range r : map) + { + System.out.println(Long.toHexString(r.begin) + "-" + + Long.toHexString(r.end) + " -> " + + r.filename + " offset " + + Long.toHexString(r.offset)); + } + } + + Range getRange(long addr) + { + Range r = new Range(); + r.begin = addr; + SortedSet t = map.tailSet(r); + if (t.isEmpty()) + return null; + Range c = t.first(); + if (c.begin <= addr && addr < c.end) + return c; + return null; + } + + String getFile(long addr) + { + Range r = getRange(addr); + if (null != r) + return r.filename; + return null; + } + + long getOffset(long addr) + { + Range r = getRange(addr); + if (null != r) + return r.offset; + return 0L; + } + + /** + * @return BytePtr which includes given address. + */ + BytePtr getBytePtr(long addr, int length) throws IOException + { + Range r = getRange(addr); + + if (null == r) + return null; + + File f = ToolPrefix.fileForName(r.filename); + if (null == f) + return null; + + if (addr + length > r.end) + length = (int)(r.end - addr); + + ByteBuffer b = ByteBuffer.allocate(length); + b.order(byteOrder); + + FileChannel fc = (new RandomAccessFile(f, "r")).getChannel(); + fc.position(r.offset + addr - r.begin); + int nr = fc.read(b); + fc.close(); + if (nr != length) + return null; + b.flip(); + return new BytePtr(b, wordSize); + } + + public String getSymbol(long addr) + { + Range r = getRange(addr); + + if (r == null) + return null; + + SymbolTable st = symbolTables.get(r.filename); + if (st == null) + return null; + + // Apply relocation + addr -= st.relocation; + + return st.getSymbol(addr); + } +} -- cgit v1.2.3