mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 23:05:47 +02:00
use mapping of sections for dwarf parser rather than allocating memory which avoids out of memory exceptions for large symbol files.
This commit is contained in:
parent
f0893c8b81
commit
7ef8d28991
3 changed files with 146 additions and 177 deletions
|
@ -11,10 +11,9 @@
|
|||
|
||||
package org.eclipse.cdt.utils.debug.dwarf;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -160,7 +159,7 @@ public class Dwarf {
|
|||
int identifierCase;
|
||||
}
|
||||
|
||||
Map<String, byte[]> dwarfSections = new HashMap<String, byte[]>();
|
||||
Map<String, ByteBuffer> dwarfSections = new HashMap<String, ByteBuffer>();
|
||||
Map<Integer, Map<Long, AbbreviationEntry>> abbreviationMaps = new HashMap<Integer, Map<Long, AbbreviationEntry>>();
|
||||
|
||||
boolean isLE;
|
||||
|
@ -188,113 +187,105 @@ public class Dwarf {
|
|||
String name = section.toString();
|
||||
for (String element : DWARF_SCNNAMES) {
|
||||
if (name.equals(element)) {
|
||||
dwarfSections.put(element, section.loadSectionData());
|
||||
try {
|
||||
dwarfSections.put(element, section.mapSectionData());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int read_4_bytes(InputStream in) throws IOException {
|
||||
int read_4_bytes(ByteBuffer in) throws IOException {
|
||||
try {
|
||||
byte[] bytes = new byte[4];
|
||||
int n = in.read(bytes, 0, bytes.length);
|
||||
if (n != 4) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.missingBytes")); //$NON-NLS-1$
|
||||
}
|
||||
return read_4_bytes(bytes, 0);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
in.get(bytes);
|
||||
return read_4_bytes(bytes);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.missingBytes")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME:This is wrong, it's signed.
|
||||
int read_4_bytes(byte[] bytes, int offset) throws IndexOutOfBoundsException {
|
||||
int read_4_bytes(byte[] bytes) throws IndexOutOfBoundsException {
|
||||
if (isLE) {
|
||||
return (
|
||||
((bytes[offset + 3] & 0xff) << 24)
|
||||
| ((bytes[offset + 2] & 0xff) << 16)
|
||||
| ((bytes[offset + 1] & 0xff) << 8)
|
||||
| (bytes[offset] & 0xff));
|
||||
((bytes[3] & 0xff) << 24)
|
||||
| ((bytes[2] & 0xff) << 16)
|
||||
| ((bytes[1] & 0xff) << 8)
|
||||
| (bytes[0] & 0xff));
|
||||
}
|
||||
return (
|
||||
((bytes[offset] & 0xff) << 24)
|
||||
| ((bytes[offset + 1] & 0xff) << 16)
|
||||
| ((bytes[offset + 2] & 0xff) << 8)
|
||||
| (bytes[offset + 3] & 0xff));
|
||||
((bytes[0] & 0xff) << 24)
|
||||
| ((bytes[1] & 0xff) << 16)
|
||||
| ((bytes[2] & 0xff) << 8)
|
||||
| (bytes[3] & 0xff));
|
||||
}
|
||||
|
||||
long read_8_bytes(InputStream in) throws IOException {
|
||||
long read_8_bytes(ByteBuffer in) throws IOException {
|
||||
try {
|
||||
byte[] bytes = new byte[8];
|
||||
int n = in.read(bytes, 0, bytes.length);
|
||||
if (n != 8) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.missingBytes")); //$NON-NLS-1$
|
||||
}
|
||||
return read_8_bytes(bytes, 0);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
in.get(bytes);
|
||||
return read_8_bytes(bytes);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.missingBytes")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME:This is wrong, for unsigned.
|
||||
long read_8_bytes(byte[] bytes, int offset) throws IndexOutOfBoundsException {
|
||||
long read_8_bytes(byte[] bytes) throws IndexOutOfBoundsException {
|
||||
|
||||
if (isLE) {
|
||||
return (((bytes[offset + 7] & 0xff) << 56)
|
||||
| ((bytes[offset + 6] & 0xff) << 48)
|
||||
| ((bytes[offset + 5] & 0xff) << 40)
|
||||
| ((bytes[offset + 4] & 0xff) << 32)
|
||||
| ((bytes[offset + 3] & 0xff) << 24)
|
||||
| ((bytes[offset + 2] & 0xff) << 16)
|
||||
| ((bytes[offset + 1] & 0xff) << 8)
|
||||
| (bytes[offset] & 0xff));
|
||||
return (((bytes[7] & 0xff) << 56)
|
||||
| ((bytes[6] & 0xff) << 48)
|
||||
| ((bytes[5] & 0xff) << 40)
|
||||
| ((bytes[4] & 0xff) << 32)
|
||||
| ((bytes[3] & 0xff) << 24)
|
||||
| ((bytes[2] & 0xff) << 16)
|
||||
| ((bytes[1] & 0xff) << 8)
|
||||
| (bytes[0] & 0xff));
|
||||
}
|
||||
|
||||
return (((bytes[offset] & 0xff) << 56)
|
||||
| ((bytes[offset + 1] & 0xff) << 48)
|
||||
| ((bytes[offset + 2] & 0xff) << 40)
|
||||
| ((bytes[offset + 3] & 0xff) << 32)
|
||||
| ((bytes[offset + 4] & 0xff) << 24)
|
||||
| ((bytes[offset + 5] & 0xff) << 16)
|
||||
| ((bytes[offset + 6] & 0xff) << 8)
|
||||
| (bytes[offset] & 0xff));
|
||||
return (((bytes[0] & 0xff) << 56)
|
||||
| ((bytes[1] & 0xff) << 48)
|
||||
| ((bytes[2] & 0xff) << 40)
|
||||
| ((bytes[3] & 0xff) << 32)
|
||||
| ((bytes[4] & 0xff) << 24)
|
||||
| ((bytes[5] & 0xff) << 16)
|
||||
| ((bytes[6] & 0xff) << 8)
|
||||
| (bytes[7] & 0xff));
|
||||
}
|
||||
|
||||
short read_2_bytes(InputStream in) throws IOException {
|
||||
short read_2_bytes(ByteBuffer in) throws IOException {
|
||||
try {
|
||||
byte[] bytes = new byte[2];
|
||||
int n = in.read(bytes, 0, bytes.length);
|
||||
if (n != 2) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.missingBytes")); //$NON-NLS-1$
|
||||
}
|
||||
return read_2_bytes(bytes, 0);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
in.get(bytes);
|
||||
return read_2_bytes(bytes);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.missingBytes")); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
short read_2_bytes(byte[] bytes, int offset) throws IndexOutOfBoundsException {
|
||||
short read_2_bytes(byte[] bytes) throws IndexOutOfBoundsException {
|
||||
if (isLE) {
|
||||
return (short) (((bytes[offset + 1] & 0xff) << 8) + (bytes[offset] & 0xff));
|
||||
return (short) (((bytes[1] & 0xff) << 8) + (bytes[0] & 0xff));
|
||||
}
|
||||
return (short) (((bytes[offset] & 0xff) << 8) + (bytes[offset + 1] & 0xff));
|
||||
return (short) (((bytes[0] & 0xff) << 8) + (bytes[1] & 0xff));
|
||||
}
|
||||
|
||||
private int num_leb128_read;
|
||||
|
||||
/* unsigned */
|
||||
long read_unsigned_leb128(InputStream in) throws IOException {
|
||||
long read_unsigned_leb128(ByteBuffer in) throws IOException {
|
||||
/* unsigned */
|
||||
long result = 0;
|
||||
num_leb128_read = 0;
|
||||
int shift = 0;
|
||||
short b;
|
||||
|
||||
while (true) {
|
||||
b = (short) in.read();
|
||||
if (b == -1)
|
||||
b = in.get();
|
||||
if (!in.hasRemaining())
|
||||
break; //throw new IOException("no more data");
|
||||
num_leb128_read++;
|
||||
result |= ((long) (b & 0x7f) << shift);
|
||||
if ((b & 0x80) == 0) {
|
||||
break;
|
||||
|
@ -305,19 +296,17 @@ public class Dwarf {
|
|||
}
|
||||
|
||||
/* unsigned */
|
||||
long read_signed_leb128(InputStream in) throws IOException {
|
||||
long read_signed_leb128(ByteBuffer in) throws IOException {
|
||||
/* unsigned */
|
||||
long result = 0;
|
||||
int shift = 0;
|
||||
int size = 32;
|
||||
num_leb128_read = 0;
|
||||
short b;
|
||||
|
||||
while (true) {
|
||||
b = (short) in.read();
|
||||
if (b == -1)
|
||||
b = in.get();
|
||||
if (!in.hasRemaining())
|
||||
throw new IOException(CCorePlugin.getResourceString("Util.exception.noData")); //$NON-NLS-1$
|
||||
num_leb128_read++;
|
||||
result |= ((long) (b & 0x7f) << shift);
|
||||
shift += 7;
|
||||
if ((b & 0x80) == 0) {
|
||||
|
@ -335,27 +324,29 @@ public class Dwarf {
|
|||
}
|
||||
|
||||
void parseDebugInfo(IDebugEntryRequestor requestor) {
|
||||
byte[] data = dwarfSections.get(DWARF_DEBUG_INFO);
|
||||
ByteBuffer data = dwarfSections.get(DWARF_DEBUG_INFO);
|
||||
if (data != null) {
|
||||
try {
|
||||
int length = 0;
|
||||
for (int offset = 0; offset < data.length; offset += (length + 4)) {
|
||||
while (data.hasRemaining()) {
|
||||
CompilationUnitHeader header = new CompilationUnitHeader();
|
||||
header.length = length = read_4_bytes(data, offset);
|
||||
header.version = read_2_bytes(data, offset + 4);
|
||||
header.abbreviationOffset = read_4_bytes(data, offset + 6);
|
||||
header.addressSize = data[offset + 10];
|
||||
header.length = read_4_bytes(data);
|
||||
header.version = read_2_bytes(data);
|
||||
header.abbreviationOffset = read_4_bytes(data);
|
||||
header.addressSize = data.get();
|
||||
|
||||
if (printEnabled) {
|
||||
System.out.println("Compilation Unit @ " + Long.toHexString(offset)); //$NON-NLS-1$
|
||||
System.out.println("Compilation Unit @ " + Long.toHexString(data.position())); //$NON-NLS-1$
|
||||
System.out.println(header);
|
||||
}
|
||||
|
||||
// read the abbrev section.
|
||||
// Note "length+4" is the total size in bytes of the CU data.
|
||||
InputStream in = new ByteArrayInputStream(data, offset + 11, length+4-11);
|
||||
Map<Long, AbbreviationEntry> abbrevs = parseDebugAbbreviation(header);
|
||||
parseDebugInfoEntry(requestor, in, abbrevs, header);
|
||||
// Note "length+4" is the total size in bytes of the CU data.
|
||||
ByteBuffer entryBuffer = data.slice();
|
||||
entryBuffer.limit(header.length + 4 - 11);
|
||||
parseDebugInfoEntry(requestor, entryBuffer, abbrevs, header);
|
||||
|
||||
data.position(data.position() + header.length + 4 - 11);
|
||||
|
||||
if (printEnabled)
|
||||
System.out.println();
|
||||
|
@ -367,23 +358,21 @@ public class Dwarf {
|
|||
}
|
||||
|
||||
Map<Long, AbbreviationEntry> parseDebugAbbreviation(CompilationUnitHeader header) throws IOException {
|
||||
int offset = header.abbreviationOffset;
|
||||
Integer key = new Integer(offset);
|
||||
Integer key = new Integer(header.abbreviationOffset);
|
||||
Map<Long, AbbreviationEntry> abbrevs = abbreviationMaps.get(key);
|
||||
if (abbrevs == null) {
|
||||
abbrevs = new HashMap<Long, AbbreviationEntry>();
|
||||
abbreviationMaps.put(key, abbrevs);
|
||||
byte[] data = dwarfSections.get(DWARF_DEBUG_ABBREV);
|
||||
ByteBuffer data = dwarfSections.get(DWARF_DEBUG_ABBREV);
|
||||
if (data != null) {
|
||||
InputStream in = new ByteArrayInputStream(data);
|
||||
in.skip(offset);
|
||||
while (in.available() > 0) {
|
||||
long code = read_unsigned_leb128(in);
|
||||
data.position(header.abbreviationOffset);
|
||||
while (data.remaining() > 0) {
|
||||
long code = read_unsigned_leb128(data);
|
||||
if (code == 0) {
|
||||
break;
|
||||
}
|
||||
long tag = read_unsigned_leb128(in);
|
||||
byte hasChildren = (byte) in.read();
|
||||
long tag = read_unsigned_leb128(data);
|
||||
byte hasChildren = data.get();
|
||||
AbbreviationEntry entry = new AbbreviationEntry(code, tag, hasChildren);
|
||||
|
||||
//System.out.println("\tAbrev Entry: " + code + " " + Long.toHexString(entry.tag) + " " + entry.hasChildren);
|
||||
|
@ -392,8 +381,8 @@ public class Dwarf {
|
|||
long name = 0;
|
||||
long form = 0;
|
||||
do {
|
||||
name = read_unsigned_leb128(in);
|
||||
form = read_unsigned_leb128(in);
|
||||
name = read_unsigned_leb128(data);
|
||||
form = read_unsigned_leb128(data);
|
||||
if (name != 0) {
|
||||
entry.attributes.add(new Attribute(name, form));
|
||||
}
|
||||
|
@ -406,9 +395,9 @@ public class Dwarf {
|
|||
return abbrevs;
|
||||
}
|
||||
|
||||
void parseDebugInfoEntry(IDebugEntryRequestor requestor, InputStream in, Map<Long, AbbreviationEntry> abbrevs, CompilationUnitHeader header)
|
||||
void parseDebugInfoEntry(IDebugEntryRequestor requestor, ByteBuffer in, Map<Long, AbbreviationEntry> abbrevs, CompilationUnitHeader header)
|
||||
throws IOException {
|
||||
while (in.available() > 0) {
|
||||
while (in.remaining() > 0) {
|
||||
long code = read_unsigned_leb128(in);
|
||||
AbbreviationEntry entry = abbrevs.get(new Long(code));
|
||||
if (entry != null) {
|
||||
|
@ -428,7 +417,7 @@ public class Dwarf {
|
|||
}
|
||||
}
|
||||
|
||||
Object readAttribute(int form, InputStream in, CompilationUnitHeader header) throws IOException {
|
||||
Object readAttribute(int form, ByteBuffer in, CompilationUnitHeader header) throws IOException {
|
||||
Object obj = null;
|
||||
switch (form) {
|
||||
case DwarfConstants.DW_FORM_addr :
|
||||
|
@ -440,16 +429,16 @@ public class Dwarf {
|
|||
{
|
||||
int size = (int) read_unsigned_leb128(in);
|
||||
byte[] bytes = new byte[size];
|
||||
in.read(bytes, 0, size);
|
||||
in.get(bytes);
|
||||
obj = bytes;
|
||||
}
|
||||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_block1 :
|
||||
{
|
||||
int size = in.read();
|
||||
int size = in.get();
|
||||
byte[] bytes = new byte[size];
|
||||
in.read(bytes, 0, size);
|
||||
in.get(bytes);
|
||||
obj = bytes;
|
||||
}
|
||||
break;
|
||||
|
@ -458,7 +447,7 @@ public class Dwarf {
|
|||
{
|
||||
int size = read_2_bytes(in);
|
||||
byte[] bytes = new byte[size];
|
||||
in.read(bytes, 0, size);
|
||||
in.get(bytes);
|
||||
obj = bytes;
|
||||
}
|
||||
break;
|
||||
|
@ -467,13 +456,13 @@ public class Dwarf {
|
|||
{
|
||||
int size = read_4_bytes(in);
|
||||
byte[] bytes = new byte[size];
|
||||
in.read(bytes, 0, size);
|
||||
in.get(bytes);
|
||||
obj = bytes;
|
||||
}
|
||||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_data1 :
|
||||
obj = new Byte((byte) in.read());
|
||||
obj = new Byte(in.get());
|
||||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_data2 :
|
||||
|
@ -500,7 +489,7 @@ public class Dwarf {
|
|||
{
|
||||
int c;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while ((c = in.read()) != -1) {
|
||||
while ((c = in.get()) != -1) {
|
||||
if (c == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -511,21 +500,22 @@ public class Dwarf {
|
|||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_flag :
|
||||
obj = new Byte((byte) in.read());
|
||||
obj = new Byte(in.get());
|
||||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_strp :
|
||||
{
|
||||
int offset = read_4_bytes(in);
|
||||
byte[] data = dwarfSections.get(DWARF_DEBUG_STR);
|
||||
ByteBuffer data = dwarfSections.get(DWARF_DEBUG_STR);
|
||||
if (data == null) {
|
||||
obj = new String();
|
||||
} else if (offset < 0 || offset > data.length) {
|
||||
} else if (offset < 0 || offset > data.capacity()) {
|
||||
obj = new String();
|
||||
} else {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (; offset < data.length; offset++) {
|
||||
byte c = data[offset];
|
||||
data.position(offset);
|
||||
while (data.hasRemaining()) {
|
||||
byte c = data.get();
|
||||
if (c == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -537,7 +527,7 @@ public class Dwarf {
|
|||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_ref1 :
|
||||
obj = new Byte((byte) in.read());
|
||||
obj = new Byte(in.get());
|
||||
break;
|
||||
|
||||
case DwarfConstants.DW_FORM_ref2 :
|
||||
|
@ -647,7 +637,7 @@ public class Dwarf {
|
|||
}
|
||||
}
|
||||
|
||||
Long readAddress(InputStream in, CompilationUnitHeader header) throws IOException {
|
||||
Long readAddress(ByteBuffer in, CompilationUnitHeader header) throws IOException {
|
||||
long value = 0;
|
||||
|
||||
switch (header.addressSize) {
|
||||
|
|
|
@ -14,10 +14,12 @@ package org.eclipse.cdt.utils.debug.dwarf;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ISymbolReader;
|
||||
import org.eclipse.cdt.utils.debug.IDebugEntryRequestor;
|
||||
import org.eclipse.cdt.utils.elf.Elf;
|
||||
|
@ -45,7 +47,6 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
private String m_exeFileWin32Drive; // Win32 drive of the exe file.
|
||||
private boolean m_onWindows;
|
||||
private boolean m_parsed = false;
|
||||
private int m_leb128Size = 0;
|
||||
private ArrayList<Integer> m_parsedLineTableOffsets = new ArrayList<Integer>();
|
||||
private int m_parsedLineTableSize = 0;
|
||||
|
||||
|
@ -77,9 +78,10 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
// problem itself, but will at least continue to load the other
|
||||
// sections.
|
||||
try {
|
||||
dwarfSections.put(element, section.loadSectionData());
|
||||
} catch (OutOfMemoryError e) {
|
||||
// Don't log this error, handle it silently without any UI.
|
||||
dwarfSections.put(element, section.mapSectionData());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,10 +106,10 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
String cuCompDir, // compilation directory of the CU
|
||||
int cuStmtList) // offset of the CU line table in .debug_line section
|
||||
{
|
||||
byte[] data = dwarfSections.get(DWARF_DEBUG_LINE);
|
||||
ByteBuffer data = dwarfSections.get(DWARF_DEBUG_LINE);
|
||||
if (data != null) {
|
||||
try {
|
||||
int offset = cuStmtList;
|
||||
data.position(cuStmtList);
|
||||
|
||||
/* Read line table header:
|
||||
*
|
||||
|
@ -127,7 +129,7 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
if (! m_parsedLineTableOffsets.contains(cuOffset)) {
|
||||
m_parsedLineTableOffsets.add(cuOffset);
|
||||
|
||||
int length = read_4_bytes(data, offset) + 4;
|
||||
int length = read_4_bytes(data) + 4;
|
||||
m_parsedLineTableSize += length + 4;
|
||||
}
|
||||
else {
|
||||
|
@ -137,9 +139,9 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
}
|
||||
|
||||
// Skip the following till "opcode_base"
|
||||
offset = offset + 14;
|
||||
int opcode_base = data[offset++];
|
||||
offset += opcode_base - 1;
|
||||
data.position(data.position() + 10);
|
||||
int opcode_base = data.get();
|
||||
data.position(data.position() + opcode_base - 1);
|
||||
|
||||
// Read in directories.
|
||||
//
|
||||
|
@ -151,38 +153,32 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
String str, fileName;
|
||||
|
||||
while (true) {
|
||||
str = readString(data, offset);
|
||||
str = readString(data);
|
||||
if (str.length() == 0)
|
||||
break;
|
||||
dirList.add(str);
|
||||
offset += str.length()+1;
|
||||
}
|
||||
offset++;
|
||||
|
||||
// Read file names
|
||||
//
|
||||
long leb128;
|
||||
while (true) {
|
||||
fileName = readString(data, offset);
|
||||
fileName = readString(data);
|
||||
if (fileName.length() == 0) // no more file entry
|
||||
break;
|
||||
offset += fileName.length()+1;
|
||||
|
||||
// dir index
|
||||
leb128 = read_unsigned_leb128(data, offset);
|
||||
offset += m_leb128Size;
|
||||
leb128 = read_unsigned_leb128(data);
|
||||
|
||||
addSourceFile(dirList.get((int)leb128), fileName);
|
||||
|
||||
// Skip the followings
|
||||
//
|
||||
// modification time
|
||||
leb128 = read_unsigned_leb128(data, offset);
|
||||
offset += m_leb128Size;
|
||||
leb128 = read_unsigned_leb128(data);
|
||||
|
||||
// file size in bytes
|
||||
leb128 = read_unsigned_leb128(data, offset);
|
||||
offset += m_leb128Size;
|
||||
leb128 = read_unsigned_leb128(data);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -200,11 +196,11 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
*/
|
||||
private void getSourceFilesFromDebugLineSection()
|
||||
{
|
||||
byte[] data = dwarfSections.get(DWARF_DEBUG_LINE);
|
||||
ByteBuffer data = dwarfSections.get(DWARF_DEBUG_LINE);
|
||||
if (data == null)
|
||||
return;
|
||||
|
||||
int sectionSize = data.length;
|
||||
int sectionSize = data.capacity();
|
||||
int minHeaderSize = 16;
|
||||
|
||||
// Check if there is data in .debug_line section that is not parsed
|
||||
|
@ -233,13 +229,13 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
|
||||
try {
|
||||
while (lineTableStart < sectionSize - minHeaderSize) {
|
||||
int offset = lineTableStart;
|
||||
data.position(lineTableStart);
|
||||
|
||||
Integer currLineTableStart = new Integer(lineTableStart);
|
||||
|
||||
// Read length of the line table for one compile unit
|
||||
// Note the length does not including the "length" field itself.
|
||||
int tableLength = read_4_bytes(data, offset);
|
||||
int tableLength = read_4_bytes(data);
|
||||
|
||||
// Record start of next CU line table
|
||||
lineTableStart += tableLength + 4;
|
||||
|
@ -256,9 +252,12 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
if (lineTableStart < sectionSize - minHeaderSize &&
|
||||
(lineTableStart & 0x3) != 0)
|
||||
{
|
||||
int ltLength = read_4_bytes(data, lineTableStart);
|
||||
int dwarfVer = read_2_bytes(data, lineTableStart+4);
|
||||
int minInstLengh = data[lineTableStart+4+2+4];
|
||||
int savedPosition = data.position();
|
||||
data.position(lineTableStart);
|
||||
|
||||
int ltLength = read_4_bytes(data);
|
||||
int dwarfVer = read_2_bytes(data);
|
||||
int minInstLengh = data.get(data.position() + 4);
|
||||
|
||||
boolean dataValid =
|
||||
ltLength > minHeaderSize &&
|
||||
|
@ -268,6 +267,8 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
|
||||
if (! dataValid) // padding exists !
|
||||
lineTableStart = (lineTableStart+3) & ~0x3;
|
||||
|
||||
data.position(savedPosition);
|
||||
}
|
||||
|
||||
if (m_parsedLineTableOffsets.contains(currLineTableStart))
|
||||
|
@ -275,9 +276,9 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
continue;
|
||||
|
||||
// Skip following fields till "opcode_base"
|
||||
offset = offset + 14;
|
||||
int opcode_base = data[offset++];
|
||||
offset += opcode_base - 1;
|
||||
data.position(data.position() + 10);
|
||||
int opcode_base = data.get();
|
||||
data.position(data.position() + opcode_base - 1);
|
||||
|
||||
// Read in directories.
|
||||
//
|
||||
|
@ -289,38 +290,32 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
dirList.add(""); //$NON-NLS-1$
|
||||
|
||||
while (true) {
|
||||
str = readString(data, offset);
|
||||
str = readString(data);
|
||||
if (str.length() == 0)
|
||||
break;
|
||||
dirList.add(str);
|
||||
offset += str.length() + 1;
|
||||
}
|
||||
offset++;
|
||||
|
||||
// Read file names
|
||||
//
|
||||
long leb128;
|
||||
while (true) {
|
||||
fileName = readString(data, offset);
|
||||
fileName = readString(data);
|
||||
if (fileName.length() == 0) // no more file entry
|
||||
break;
|
||||
offset += fileName.length() + 1;
|
||||
|
||||
// dir index. Note "0" is reserved for compilation directory.
|
||||
leb128 = read_unsigned_leb128(data, offset);
|
||||
offset += m_leb128Size;
|
||||
leb128 = read_unsigned_leb128(data);
|
||||
|
||||
addSourceFile(dirList.get((int) leb128), fileName);
|
||||
|
||||
// Skip the followings
|
||||
//
|
||||
// modification time
|
||||
leb128 = read_unsigned_leb128(data, offset);
|
||||
offset += m_leb128Size;
|
||||
leb128 = read_unsigned_leb128(data);
|
||||
|
||||
// file size in bytes
|
||||
leb128 = read_unsigned_leb128(data, offset);
|
||||
offset += m_leb128Size;
|
||||
leb128 = read_unsigned_leb128(data);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -400,17 +395,16 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
}
|
||||
|
||||
/**
|
||||
* Read a null-ended string from the given "data" stream starting at the given "offset".
|
||||
* data : IN, byte stream
|
||||
* offset: IN, offset in the stream
|
||||
* Read a null-ended string from the given "data" stream.
|
||||
* data : IN, byte buffer
|
||||
*/
|
||||
String readString(byte[] data, int offset)
|
||||
String readString(ByteBuffer data)
|
||||
{
|
||||
String str;
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (; offset < data.length; offset++) {
|
||||
byte c = data[offset];
|
||||
while (data.hasRemaining()) {
|
||||
byte c = data.get();
|
||||
if (c == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -421,30 +415,6 @@ public class DwarfReader extends Dwarf implements ISymbolReader {
|
|||
return str;
|
||||
}
|
||||
|
||||
// Note this method modifies a data member
|
||||
//
|
||||
long read_unsigned_leb128(byte[] data, int offset) throws IOException {
|
||||
/* unsigned */
|
||||
long result = 0;
|
||||
int shift = 0;
|
||||
short b;
|
||||
|
||||
m_leb128Size = 0;
|
||||
while (true) {
|
||||
b = data[offset++];
|
||||
if (data.length == offset)
|
||||
break; //throw new IOException("no more data");
|
||||
m_leb128Size++;
|
||||
result |= ((long) (b & 0x7f) << shift);
|
||||
if ((b & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Override parent: only handle TAG_Compile_Unit.
|
||||
@Override
|
||||
void processDebugInfoEntry(IDebugEntryRequestor requestor, AbbreviationEntry entry, List<Dwarf.AttributeValue> list) {
|
||||
|
|
|
@ -13,6 +13,8 @@ package org.eclipse.cdt.utils.elf;
|
|||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
@ -333,6 +335,10 @@ public class Elf {
|
|||
public long sh_addralign;
|
||||
public long sh_entsize;
|
||||
|
||||
public ByteBuffer mapSectionData() throws IOException {
|
||||
return efile.getChannel().map(MapMode.READ_ONLY, sh_offset, sh_size).load().asReadOnlyBuffer();
|
||||
}
|
||||
|
||||
public byte[] loadSectionData() throws IOException {
|
||||
byte[] data = new byte[(int)sh_size];
|
||||
efile.seek(sh_offset);
|
||||
|
@ -943,6 +949,9 @@ public class Elf {
|
|||
if (efile != null) {
|
||||
efile.close();
|
||||
efile = null;
|
||||
|
||||
// ensure the mappings get cleaned up
|
||||
System.gc();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue