diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java index 09cfc38dc32..7205ba6ad06 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Coff.java @@ -13,13 +13,16 @@ package org.eclipse.cdt.utils.coff; import java.io.EOFException; import java.io.IOException; import java.io.RandomAccessFile; -import com.ibm.icu.text.DateFormat; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel.MapMode; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; +import com.ibm.icu.text.DateFormat; + public class Coff { public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -308,6 +311,13 @@ public class Coff { //*/ return buffer.toString(); } + + /** + * @since 5.1 + */ + public ByteBuffer mapSectionData() throws IOException { + return sfile.getChannel().map(MapMode.READ_ONLY, s_scnptr, s_paddr).load().asReadOnlyBuffer(); + } } public static class Reloc { @@ -563,7 +573,7 @@ public class Coff { // } return buffer.toString(); } - + public static String[] getStringTable(byte[] bytes) { List aList = new ArrayList(); int offset = 0; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java index 8ad0849da15..977036a0a38 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java @@ -24,6 +24,7 @@ import org.eclipse.cdt.utils.coff.Coff.OptionalHeader; import org.eclipse.cdt.utils.coff.Coff.SectionHeader; import org.eclipse.cdt.utils.coff.Coff.Symbol; import org.eclipse.cdt.utils.coff.Exe.ExeHeader; +import org.eclipse.cdt.utils.debug.dwarf.DwarfReader; import org.eclipse.cdt.utils.debug.stabs.StabsReader; /** @@ -65,6 +66,7 @@ import org.eclipse.cdt.utils.debug.stabs.StabsReader; */ public class PE { + public static final String NL = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ RandomAccessFile rfile; String filename; @@ -840,6 +842,40 @@ public class PE { if (reader == null) { reader = createCodeViewReader(); } + if (reader == null) { + reader = createDwarfReader(); + } return reader; } + + private ISymbolReader createDwarfReader() { + DwarfReader reader = null; + // Check if Dwarf data exists + try { + reader = new DwarfReader(this); + } catch (IOException e) { + // No Dwarf data in the Elf. + } + return reader; + } + + /** + * @since 5.1 + */ + public String getStringTableEntry(int offset) throws IOException + { + byte[] bytes = getStringTable(); + offset = offset - 4; + for (int i = offset; i < bytes.length; i++) { + if (bytes[i] == 0) { + return new String(bytes, offset, i - offset); + } + } + + return new String(); + } + + public String getFilename() { + return filename; + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java index 2dcf3f0ccad..30ceacf6835 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java @@ -20,6 +20,8 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.Coff.SectionHeader; import org.eclipse.cdt.utils.debug.DebugUnknownType; import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; import org.eclipse.cdt.utils.debug.tools.DebugSym; @@ -178,6 +180,13 @@ public class Dwarf { init(exe); } + /** + * @since 5.1 + */ + public Dwarf(PE exe) throws IOException { + init(exe); + } + public void init(Elf exe) throws IOException { Elf.ELFhdr header = exe.getELFhdr(); isLE = header.e_ident[Elf.ELFhdr.EI_DATA] == Elf.ELFhdr.ELFDATA2LSB; @@ -198,6 +207,36 @@ public class Dwarf { } } + /** + * @since 5.1 + */ + public void init(PE exe) throws IOException { + + isLE = true; + SectionHeader[] sections = exe.getSectionHeaders(); + + + for (int i = 0; i < sections.length; i++) { + String name = new String(sections[i].s_name).trim(); + if (name.startsWith("/")) //$NON-NLS-1$ + { + int stringTableOffset = Integer.parseInt(name.substring(1)); + name = exe.getStringTableEntry(stringTableOffset); + } + for (String element : Dwarf.DWARF_SCNNAMES) { + if (name.equals(element)) { + try { + dwarfSections.put(element, sections[i].mapSectionData()); + } catch (Exception e) { + e.printStackTrace(); + CCorePlugin.log(e); + } + } + } + } + + } + int read_4_bytes(ByteBuffer in) throws IOException { try { byte[] bytes = new byte[4]; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java index 91ba1f94b41..bddbea9a84c 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfReader.java @@ -21,6 +21,8 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ISymbolReader; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.Coff.SectionHeader; import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; import org.eclipse.cdt.utils.elf.Elf; import org.eclipse.cdt.utils.elf.Elf.Section; @@ -33,6 +35,11 @@ import org.eclipse.core.runtime.Path; */ public class DwarfReader extends Dwarf implements ISymbolReader { + private static boolean isWindows() { + String os = System.getProperty("os.name"); //$NON-NLS-1$ + return (os != null && os.toLowerCase().startsWith("win")); //$NON-NLS-1$ + } + // These are sections that need be parsed to get the source file list. final static String[] DWARF_SectionsToParse = { @@ -42,12 +49,12 @@ public class DwarfReader extends Dwarf implements ISymbolReader { DWARF_DEBUG_STR // this is optional. Some compilers don't generate it. }; - private Collection m_fileCollection = new ArrayList(); + private final Collection m_fileCollection = new ArrayList(); private String[] m_fileNames = null; private String m_exeFileWin32Drive; // Win32 drive of the exe file. private boolean m_onWindows; private boolean m_parsed = false; - private ArrayList m_parsedLineTableOffsets = new ArrayList(); + private final ArrayList m_parsedLineTableOffsets = new ArrayList(); private int m_parsedLineTableSize = 0; public DwarfReader(String file) throws IOException { @@ -58,6 +65,13 @@ public class DwarfReader extends Dwarf implements ISymbolReader { super(exe); } + /** + * @since 5.1 + */ + public DwarfReader(PE exe) throws IOException { + super(exe); + } + // Override parent. // @Override @@ -80,7 +94,6 @@ public class DwarfReader extends Dwarf implements ISymbolReader { try { dwarfSections.put(element, section.mapSectionData()); } catch (Exception e) { - e.printStackTrace(); CCorePlugin.log(e); } } @@ -89,12 +102,44 @@ public class DwarfReader extends Dwarf implements ISymbolReader { // Don't print during parsing. printEnabled = false; - m_parsed = false; Path pa = new Path(exe.getFilename()); m_exeFileWin32Drive = pa.getDevice(); + m_onWindows = isWindows(); + } + + @Override + public void init(PE exe) throws IOException { + + isLE = true; + SectionHeader[] sections = exe.getSectionHeaders(); + + for (int i = 0; i < sections.length; i++) { + String name = new String(sections[i].s_name).trim(); + if (name.startsWith("/")) //$NON-NLS-1$ + { + int stringTableOffset = Integer.parseInt(name.substring(1)); + name = exe.getStringTableEntry(stringTableOffset); + } + for (String element : Dwarf.DWARF_SCNNAMES) { + if (name.equals(element)) { + try { + dwarfSections.put(element, sections[i].mapSectionData()); + } catch (Exception e) { + CCorePlugin.log(e); + } + } + } + } + // Don't print during parsing. + printEnabled = false; + m_parsed = false; + + Path pa = new Path(exe.getFilename()); + m_exeFileWin32Drive = pa.getDevice(); + m_onWindows = (File.separatorChar == '\\'); }