mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Support DWARF v5 content form data
This commit is contained in:
parent
54d5e1445c
commit
5be8661c9b
4 changed files with 167 additions and 42 deletions
|
@ -13,5 +13,17 @@
|
||||||
<message_argument value="DW_FORM_line_strp"/>
|
<message_argument value="DW_FORM_line_strp"/>
|
||||||
</message_arguments>
|
</message_arguments>
|
||||||
</filter>
|
</filter>
|
||||||
|
<filter id="336658481">
|
||||||
|
<message_arguments>
|
||||||
|
<message_argument value="org.eclipse.cdt.utils.debug.dwarf.DwarfConstants"/>
|
||||||
|
<message_argument value="DW_LNCT_directory_index"/>
|
||||||
|
</message_arguments>
|
||||||
|
</filter>
|
||||||
|
<filter id="336658481">
|
||||||
|
<message_arguments>
|
||||||
|
<message_argument value="org.eclipse.cdt.utils.debug.dwarf.DwarfConstants"/>
|
||||||
|
<message_argument value="DW_LNCT_path"/>
|
||||||
|
</message_arguments>
|
||||||
|
</filter>
|
||||||
</resource>
|
</resource>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class Dwarf implements AutoCloseable {
|
||||||
final static String[] DWARF_SCNNAMES = { DWARF_DEBUG_INFO, DWARF_DEBUG_ABBREV, DWARF_DEBUG_ARANGES,
|
final static String[] DWARF_SCNNAMES = { DWARF_DEBUG_INFO, DWARF_DEBUG_ABBREV, DWARF_DEBUG_ARANGES,
|
||||||
DWARF_DEBUG_LINE, DWARF_DEBUG_FRAME, DWARF_EH_FRAME, DWARF_DEBUG_LOC, DWARF_DEBUG_PUBNAMES, DWARF_DEBUG_STR,
|
DWARF_DEBUG_LINE, DWARF_DEBUG_FRAME, DWARF_EH_FRAME, DWARF_DEBUG_LOC, DWARF_DEBUG_PUBNAMES, DWARF_DEBUG_STR,
|
||||||
DWARF_DEBUG_FUNCNAMES, DWARF_DEBUG_TYPENAMES, DWARF_DEBUG_VARNAMES, DWARF_DEBUG_WEAKNAMES,
|
DWARF_DEBUG_FUNCNAMES, DWARF_DEBUG_TYPENAMES, DWARF_DEBUG_VARNAMES, DWARF_DEBUG_WEAKNAMES,
|
||||||
DWARF_DEBUG_MACINFO };
|
DWARF_DEBUG_MACINFO, DWARF_DEBUG_LINE_STR };
|
||||||
|
|
||||||
final static String[] DWARF_ALT_SCNNAMES = { DWARF_DEBUG_INFO, DWARF_DEBUG_TYPES, DWARF_DEBUG_MACRO,
|
final static String[] DWARF_ALT_SCNNAMES = { DWARF_DEBUG_INFO, DWARF_DEBUG_TYPES, DWARF_DEBUG_MACRO,
|
||||||
DWARF_DEBUG_STR, };
|
DWARF_DEBUG_STR, };
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
* John Dallaway - Add DW_FORM_line_strp (#198)
|
* John Dallaway - Add DW_FORM_line_strp (#198)
|
||||||
* John Dallaway - Add DW_FORM_implicit_const (#443)
|
* John Dallaway - Add DW_FORM_implicit_const and DW_LNCT codes (#443)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.utils.debug.dwarf;
|
package org.eclipse.cdt.utils.debug.dwarf;
|
||||||
|
@ -241,6 +241,16 @@ public class DwarfConstants {
|
||||||
*/
|
*/
|
||||||
public final static int DW_FORM_GNU_strp_alt = 0x1f21;
|
public final static int DW_FORM_GNU_strp_alt = 0x1f21;
|
||||||
|
|
||||||
|
/* DWARF v5 content types */
|
||||||
|
/**
|
||||||
|
* @since 8.3
|
||||||
|
*/
|
||||||
|
public final static int DW_LNCT_path = 0x01; /* Null-terminated path name string */
|
||||||
|
/**
|
||||||
|
* @since 8.3
|
||||||
|
*/
|
||||||
|
public final static int DW_LNCT_directory_index = 0x02; /* Index to directories entry */
|
||||||
|
|
||||||
/* DWARF location operation encodings. */
|
/* DWARF location operation encodings. */
|
||||||
public final static int DW_OP_addr = 0x03; /* Constant address. */
|
public final static int DW_OP_addr = 0x03; /* Constant address. */
|
||||||
public final static int DW_OP_deref = 0x06;
|
public final static int DW_OP_deref = 0x06;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* Ling Wang (Nokia) bug 201000
|
* Ling Wang (Nokia) bug 201000
|
||||||
* Serge Beauchamp (Freescale Semiconductor) - Bug 421070
|
* Serge Beauchamp (Freescale Semiconductor) - Bug 421070
|
||||||
* Red Hat Inc. - add debuginfo and macro section support
|
* Red Hat Inc. - add debuginfo and macro section support
|
||||||
|
* John Dallaway - support DWARF v5 content form data (#443)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.utils.debug.dwarf;
|
package org.eclipse.cdt.utils.debug.dwarf;
|
||||||
|
@ -62,6 +63,11 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions
|
||||||
private final ArrayList<Integer> m_parsedLineTableOffsets = new ArrayList<>();
|
private final ArrayList<Integer> m_parsedLineTableOffsets = new ArrayList<>();
|
||||||
private long m_parsedLineTableSize = 0;
|
private long m_parsedLineTableSize = 0;
|
||||||
|
|
||||||
|
private class ContentForm {
|
||||||
|
long lnct; // content type code DW_LNCT_*
|
||||||
|
long form; // content form code DW_FORM_*
|
||||||
|
}
|
||||||
|
|
||||||
public DwarfReader(String file) throws IOException {
|
public DwarfReader(String file) throws IOException {
|
||||||
super(file);
|
super(file);
|
||||||
}
|
}
|
||||||
|
@ -285,6 +291,137 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getPathInLineStr(long offset) {
|
||||||
|
final ByteBuffer data = dwarfSections.get(DWARF_DEBUG_LINE_STR);
|
||||||
|
if (null != data) {
|
||||||
|
data.position((int) offset);
|
||||||
|
return readString(data);
|
||||||
|
}
|
||||||
|
return ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
private long readOffset(ByteBuffer data, byte offsetSize) throws IOException {
|
||||||
|
switch (offsetSize) {
|
||||||
|
case 8:
|
||||||
|
return read_8_bytes(data);
|
||||||
|
case 4:
|
||||||
|
return read_4_bytes(data);
|
||||||
|
case 2:
|
||||||
|
return read_2_bytes(data);
|
||||||
|
default:
|
||||||
|
return -1L; // unsupported
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContentForm readContentForm(ByteBuffer in) throws IOException {
|
||||||
|
ContentForm contentForm = new ContentForm();
|
||||||
|
contentForm.lnct = read_unsigned_leb128(in); // DW_LNCT_*
|
||||||
|
contentForm.form = read_unsigned_leb128(in); // DW_FORM_*
|
||||||
|
return contentForm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read source file data (DWARF v4 and earlier) */
|
||||||
|
private void addSourceFilesDwarf(String cuCompDir, ByteBuffer data) throws IOException {
|
||||||
|
List<String> dirList = new ArrayList<>();
|
||||||
|
|
||||||
|
// add the compilation directory of the CU as the first directory
|
||||||
|
dirList.add(cuCompDir);
|
||||||
|
|
||||||
|
// read directories
|
||||||
|
while (true) {
|
||||||
|
String str = readString(data);
|
||||||
|
if (str.isEmpty()) { // if no more directories
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// if the directory is relative, append it to the CU directory
|
||||||
|
IPath dir = new Path(str);
|
||||||
|
if (!dir.isAbsolute()) {
|
||||||
|
dir = new Path(cuCompDir).append(str);
|
||||||
|
}
|
||||||
|
dirList.add(dir.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file names
|
||||||
|
while (true) {
|
||||||
|
String fileName = readString(data);
|
||||||
|
if (fileName.isEmpty()) { // if no more file entries
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read directory index
|
||||||
|
long leb128 = read_unsigned_leb128(data);
|
||||||
|
|
||||||
|
addSourceFile(dirList.get((int) leb128), fileName);
|
||||||
|
|
||||||
|
// skip modification time
|
||||||
|
leb128 = read_unsigned_leb128(data);
|
||||||
|
|
||||||
|
// skip file size in bytes
|
||||||
|
leb128 = read_unsigned_leb128(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read source file data (DWARF v5 and later) */
|
||||||
|
private void addSourceFilesDwarf5(String cuCompDir, ByteBuffer data, byte offsetSize) throws IOException {
|
||||||
|
// read directory content forms
|
||||||
|
byte dcf_count[] = new byte[1];
|
||||||
|
data.get(dcf_count);
|
||||||
|
List<ContentForm> directoryContentForms = new ArrayList<>();
|
||||||
|
for (int fmt = 0; fmt < dcf_count[0]; fmt++) {
|
||||||
|
ContentForm def = readContentForm(data);
|
||||||
|
directoryContentForms.add(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read directories
|
||||||
|
long directories_count = read_unsigned_leb128(data);
|
||||||
|
List<String> directories = new ArrayList<>((int) directories_count);
|
||||||
|
for (int directory_index = 0; directory_index < directories_count; directory_index++) {
|
||||||
|
for (ContentForm contentForm : directoryContentForms) {
|
||||||
|
if ((DwarfConstants.DW_FORM_line_strp == contentForm.form)
|
||||||
|
&& (DwarfConstants.DW_LNCT_path == contentForm.lnct)) {
|
||||||
|
long offset = readOffset(data, offsetSize);
|
||||||
|
String path = getPathInLineStr(offset);
|
||||||
|
IPath dir = new Path(path);
|
||||||
|
if (!dir.isAbsolute()) {
|
||||||
|
dir = new Path(cuCompDir).append(path);
|
||||||
|
}
|
||||||
|
directories.add(dir.toString());
|
||||||
|
} // TODO: support other DW_LNCT_path forms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file name content forms
|
||||||
|
byte[] fncf_count = new byte[1];
|
||||||
|
data.get(fncf_count);
|
||||||
|
List<ContentForm> fileNameContentForms = new ArrayList<>();
|
||||||
|
for (int fmt = 0; fmt < fncf_count[0]; fmt++) {
|
||||||
|
ContentForm fnef = readContentForm(data);
|
||||||
|
fileNameContentForms.add(fnef);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file names
|
||||||
|
long file_names_count = read_unsigned_leb128(data);
|
||||||
|
for (int file_index = 0; file_index < file_names_count; file_index++) {
|
||||||
|
String filename = null;
|
||||||
|
String directory = null;
|
||||||
|
for (ContentForm contentForm : fileNameContentForms) {
|
||||||
|
if ((DwarfConstants.DW_FORM_line_strp == contentForm.form)
|
||||||
|
&& (DwarfConstants.DW_LNCT_path == contentForm.lnct)) {
|
||||||
|
long offset = readOffset(data, offsetSize);
|
||||||
|
filename = getPathInLineStr(offset);
|
||||||
|
} // TODO: support other DW_LNCT_path forms
|
||||||
|
if ((DwarfConstants.DW_FORM_udata == contentForm.form)
|
||||||
|
&& (DwarfConstants.DW_LNCT_directory_index == contentForm.lnct)) {
|
||||||
|
long directory_index = read_unsigned_leb128(data);
|
||||||
|
directory = directories.get((int) directory_index);
|
||||||
|
} // TODO: support other DW_LNCT_directory_index forms
|
||||||
|
}
|
||||||
|
if ((null != directory) && (null != filename)) {
|
||||||
|
addSourceFile(directory, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse line table data of a compilation unit to get names of all source files
|
* Parse line table data of a compilation unit to get names of all source files
|
||||||
* that contribute to the compilation unit.
|
* that contribute to the compilation unit.
|
||||||
|
@ -319,11 +456,13 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions
|
||||||
Integer cuOffset = Integer.valueOf(cuStmtList);
|
Integer cuOffset = Integer.valueOf(cuStmtList);
|
||||||
|
|
||||||
boolean dwarf64Bit = false;
|
boolean dwarf64Bit = false;
|
||||||
|
byte offsetSize = 0;
|
||||||
if (!m_parsedLineTableOffsets.contains(cuOffset)) {
|
if (!m_parsedLineTableOffsets.contains(cuOffset)) {
|
||||||
m_parsedLineTableOffsets.add(cuOffset);
|
m_parsedLineTableOffsets.add(cuOffset);
|
||||||
|
|
||||||
// Note the length does not including the "length" field(s) itself.
|
// Note the length does not including the "length" field(s) itself.
|
||||||
InitialLengthValue length = readInitialLengthField(data);
|
InitialLengthValue length = readInitialLengthField(data);
|
||||||
|
offsetSize = length.offsetSize;
|
||||||
dwarf64Bit = length.offsetSize == 8;
|
dwarf64Bit = length.offsetSize == 8;
|
||||||
m_parsedLineTableSize += length.length + (dwarf64Bit ? 12 : 4);
|
m_parsedLineTableSize += length.length + (dwarf64Bit ? 12 : 4);
|
||||||
} else {
|
} else {
|
||||||
|
@ -346,46 +485,10 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions
|
||||||
int opcode_base = data.get();
|
int opcode_base = data.get();
|
||||||
data.position(data.position() + opcode_base - 1);
|
data.position(data.position() + opcode_base - 1);
|
||||||
|
|
||||||
// Read in directories.
|
if (version >= 5) {
|
||||||
//
|
addSourceFilesDwarf5(cuCompDir, data, offsetSize);
|
||||||
ArrayList<String> dirList = new ArrayList<>();
|
} else {
|
||||||
|
addSourceFilesDwarf(cuCompDir, data);
|
||||||
// Put the compilation directory of the CU as the first dir
|
|
||||||
dirList.add(cuCompDir);
|
|
||||||
|
|
||||||
String str, fileName;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
str = readString(data);
|
|
||||||
if (str.length() == 0)
|
|
||||||
break;
|
|
||||||
// If the directory is relative, append it to the CU dir
|
|
||||||
IPath dir = new Path(str);
|
|
||||||
if (!dir.isAbsolute())
|
|
||||||
dir = new Path(cuCompDir).append(str);
|
|
||||||
dirList.add(dir.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read file names
|
|
||||||
//
|
|
||||||
long leb128;
|
|
||||||
while (true) {
|
|
||||||
fileName = readString(data);
|
|
||||||
if (fileName.length() == 0) // no more file entry
|
|
||||||
break;
|
|
||||||
|
|
||||||
// dir index
|
|
||||||
leb128 = read_unsigned_leb128(data);
|
|
||||||
|
|
||||||
addSourceFile(dirList.get((int) leb128), fileName);
|
|
||||||
|
|
||||||
// Skip the followings
|
|
||||||
//
|
|
||||||
// modification time
|
|
||||||
leb128 = read_unsigned_leb128(data);
|
|
||||||
|
|
||||||
// file size in bytes
|
|
||||||
leb128 = read_unsigned_leb128(data);
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CCorePlugin.log("Failed to parse part of dwarf header", e); //$NON-NLS-1$
|
CCorePlugin.log("Failed to parse part of dwarf header", e); //$NON-NLS-1$
|
||||||
|
|
Loading…
Add table
Reference in a new issue