From 6c53fd8bc392345951a2f29cc7cca4c52665390c Mon Sep 17 00:00:00 2001 From: John Dallaway Date: Sat, 3 May 2025 19:16:21 +0100 Subject: [PATCH] Support DWARF attribute form DW_FORM_strx1 --- .../.settings/.api_filters | 34 +++------- .../org.eclipse.cdt.core/META-INF/MANIFEST.MF | 2 +- .../eclipse/cdt/utils/debug/dwarf/Dwarf.java | 13 +++- .../cdt/utils/debug/dwarf/DwarfConstants.java | 10 ++- .../cdt/utils/debug/dwarf/DwarfReader.java | 62 ++++++++++++++----- 5 files changed, 76 insertions(+), 45 deletions(-) diff --git a/core/org.eclipse.cdt.core/.settings/.api_filters b/core/org.eclipse.cdt.core/.settings/.api_filters index c220587bcb0..4473bcd9f6c 100644 --- a/core/org.eclipse.cdt.core/.settings/.api_filters +++ b/core/org.eclipse.cdt.core/.settings/.api_filters @@ -1,44 +1,28 @@ - + - - + + - - - - - - - - - - - - - - - - - - + + - - + + - - + + diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 5883f5c456b..a46572ead3e 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true -Bundle-Version: 9.0.0.qualifier +Bundle-Version: 9.1.0.qualifier Bundle-Activator: org.eclipse.cdt.core.CCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin 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 d6cb36148a7..4afe3cdcee0 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2024 QNX Software Systems and others. + * Copyright (c) 2000, 2025 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,6 +15,7 @@ * John Dallaway - Support DW_FORM_line_strp (#198) * John Dallaway - Support DW_FORM_implicit_const (#443) * Alexander Fedorov (ArSysOp) - fix resource leak (#693) + * John Dallaway - Support DW_FORM_strx1 (#1135) *******************************************************************************/ package org.eclipse.cdt.utils.debug.dwarf; @@ -52,6 +53,7 @@ public class Dwarf implements AutoCloseable { final static String DWARF_DEBUG_LOC = ".debug_loc"; //$NON-NLS-1$ final static String DWARF_DEBUG_PUBNAMES = ".debug_pubnames"; //$NON-NLS-1$ final static String DWARF_DEBUG_STR = ".debug_str"; //$NON-NLS-1$ + final static String DWARF_DEBUG_STR_OFFSETS = ".debug_str_offsets"; //$NON-NLS-1$ final static String DWARF_DEBUG_FUNCNAMES = ".debug_funcnames"; //$NON-NLS-1$ final static String DWARF_DEBUG_TYPENAMES = ".debug_typenames"; //$NON-NLS-1$ final static String DWARF_DEBUG_VARNAMES = ".debug_varnames"; //$NON-NLS-1$ @@ -797,6 +799,10 @@ public class Dwarf implements AutoCloseable { } break; + case DwarfConstants.DW_FORM_strx1: + obj = Integer.valueOf(Byte.toUnsignedInt(in.get())); + break; + case DwarfConstants.DW_FORM_ref1: obj = Byte.valueOf(in.get()); break; @@ -859,7 +865,8 @@ public class Dwarf implements AutoCloseable { return obj; } - void processDebugInfoEntry(IDebugEntryRequestor requestor, AbbreviationEntry entry, List list) { + void processDebugInfoEntry(IDebugEntryRequestor requestor, AbbreviationEntry entry, List list) + throws IOException { int len = list.size(); int tag = (int) entry.tag; if (printEnabled) @@ -1015,7 +1022,7 @@ public class Dwarf implements AutoCloseable { requestor.exitFunction(highPC); } - void processCompileUnit(IDebugEntryRequestor requestor, List list) { + void processCompileUnit(IDebugEntryRequestor requestor, List list) throws IOException { if (currentCU != null) { requestor.exitCompilationUnit(currentCU.highPC); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfConstants.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfConstants.java index 29d9965dd90..369bab99162 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfConstants.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/DwarfConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2023 QNX Software Systems and others. + * Copyright (c) 2000, 2025 QNX Software Systems and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -148,6 +148,8 @@ public class DwarfConstants { public final static int DW_AT_variable_parameter = 0x4b; public final static int DW_AT_virtuality = 0x4c; public final static int DW_AT_vtable_elem_location = 0x4d; + /** @since 9.1 */ + public final static int DW_AT_str_offsets_base = 0x72; public final static int DW_AT_lo_user = 0x2000; public final static int DW_AT_MIPS_fde = 0x2001; public final static int DW_AT_MIPS_loop_begin = 0x2002; @@ -209,6 +211,8 @@ public class DwarfConstants { * @since 5.7 */ public final static int DW_FORM_flag_present = 0x19; + /** @since 9.1 */ + public final static int DW_FORM_data16 = 0x1e; /** * @since 8.1 */ @@ -221,6 +225,8 @@ public class DwarfConstants { * @since 8.3 */ public final static int DW_FORM_implicit_const = 0x21; + /** @since 9.1 */ + public final static int DW_FORM_strx1 = 0x25; /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ /** * @since 5.7 @@ -250,6 +256,8 @@ public class DwarfConstants { * @since 8.3 */ public final static int DW_LNCT_directory_index = 0x02; /* Index to directories entry */ + /** @since 9.1 */ + public final static int DW_LNCT_MD5 = 0x05; /* MD5 digest */ /* DWARF location operation encodings. */ public final static int DW_OP_addr = 0x03; /* Constant address. */ 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 04602d1cdfa..addb31060ce 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2023 Nokia and others. + * Copyright (c) 2007, 2025 Nokia and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,7 +13,7 @@ * Ling Wang (Nokia) bug 201000 * Serge Beauchamp (Freescale Semiconductor) - Bug 421070 * Red Hat Inc. - add debuginfo and macro section support - * John Dallaway - support DWARF v5 content form data (#443) + * John Dallaway - support DWARF v5 content form data (#443, #1135) *******************************************************************************/ package org.eclipse.cdt.utils.debug.dwarf; @@ -37,6 +37,7 @@ import org.eclipse.cdt.utils.coff.PE64; import org.eclipse.cdt.utils.debug.IDebugEntryRequestor; import org.eclipse.cdt.utils.elf.Elf; import org.eclipse.cdt.utils.elf.Elf.Section; +import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; @@ -50,7 +51,7 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions // These are sections that need be parsed to get the source file list. final static String[] DWARF_SectionsToParse = { DWARF_DEBUG_INFO, DWARF_DEBUG_LINE, DWARF_DEBUG_ABBREV, DWARF_DEBUG_STR, // this is optional. Some compilers don't generate it. - DWARF_DEBUG_MACRO, DWARF_DEBUG_LINE_STR }; + DWARF_DEBUG_MACRO, DWARF_DEBUG_LINE_STR, DWARF_DEBUG_STR_OFFSETS }; final static String[] DWARF_ALT_SectionsToParse = { DWARF_DEBUG_STR, DWARF_DEBUG_MACRO }; @@ -368,8 +369,8 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions data.get(dcf_count); List directoryContentForms = new ArrayList<>(); for (int fmt = 0; fmt < dcf_count[0]; fmt++) { - ContentForm def = readContentForm(data); - directoryContentForms.add(def); + ContentForm dcf = readContentForm(data); + directoryContentForms.add(dcf); } // read directories @@ -386,7 +387,10 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions dir = new Path(cuCompDir).append(path); } directories.add(dir.toString()); - } // TODO: support other DW_LNCT_path forms + } else { + ILog.get().warn(String.format("DWARF directory content 0x%x form 0x%x not handled", //$NON-NLS-1$ + contentForm.lnct, contentForm.form)); + } } } @@ -395,8 +399,8 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions data.get(fncf_count); List fileNameContentForms = new ArrayList<>(); for (int fmt = 0; fmt < fncf_count[0]; fmt++) { - ContentForm fnef = readContentForm(data); - fileNameContentForms.add(fnef); + ContentForm fncf = readContentForm(data); + fileNameContentForms.add(fncf); } // read file names @@ -409,12 +413,17 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions && (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) + } else 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 + } else if ((DwarfConstants.DW_FORM_data16 == contentForm.form) + && (DwarfConstants.DW_LNCT_MD5 == contentForm.lnct)) { + data.get(new byte[16]); // skip MD5 digest + } else { + ILog.get().warn(String.format("DWARF file content 0x%x form 0x%x not handled", //$NON-NLS-1$ + contentForm.lnct, contentForm.form)); + } } if ((null != directory) && (null != filename)) { addSourceFile(directory, filename); @@ -704,8 +713,8 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions // Override parent: only handle TAG_Compile_Unit. @Override - void processDebugInfoEntry(IDebugEntryRequestor requestor, AbbreviationEntry entry, - List list) { + void processDebugInfoEntry(IDebugEntryRequestor requestor, AbbreviationEntry entry, List list) + throws IOException { int tag = (int) entry.tag; switch (tag) { case DwarfConstants.DW_TAG_compile_unit: @@ -720,10 +729,14 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions // Just get the file name of the CU. // Argument "requestor" is ignored. @Override - void processCompileUnit(IDebugEntryRequestor requestor, List list) { + void processCompileUnit(IDebugEntryRequestor requestor, List list) throws IOException { String cuName, cuCompDir; int stmtList = -1; + ByteBuffer strings = dwarfSections.get(DWARF_DEBUG_STR); + ByteBuffer offsets = dwarfSections.get(DWARF_DEBUG_STR_OFFSETS); + byte offsetSize = (offsets != null) ? readInitialLengthField(offsets).offsetSize : -1; + long offsetsBase = -1L; cuName = cuCompDir = ""; //$NON-NLS-1$ @@ -736,11 +749,30 @@ public class DwarfReader extends Dwarf implements ISymbolReader, ICompileOptions cuName = (String) av.value; break; case DwarfConstants.DW_AT_comp_dir: - cuCompDir = (String) av.value; + if ((av.attribute.form == DwarfConstants.DW_FORM_strp) + || (av.attribute.form == DwarfConstants.DW_FORM_line_strp)) { + cuCompDir = (String) av.value; + } else if ((av.attribute.form == DwarfConstants.DW_FORM_strx1) && (offsets != null) + && (offsetsBase != -1L)) { + int index = ((Number) av.value).intValue(); + // read the pointer into .debug_str from .debug_str_offsets + long offset = offsetsBase + (index * offsetSize); + offsets.position((int) offset); + long strp = readOffset(offsets, offsetSize); + // read the string from .debug_str + strings.position((int) strp); + cuCompDir = readString(strings); + } else { + ILog.get().warn(String.format("DW_AT_comp_dir form 0x%x not handled", av.attribute.form)); //$NON-NLS-1$ + } break; case DwarfConstants.DW_AT_stmt_list: stmtList = ((Number) av.value).intValue(); break; + case DwarfConstants.DW_AT_str_offsets_base: + // read the base of all offsets into .debug_str_offsets + offsetsBase = (offsetSize == 8) ? ((Number) av.value).longValue() : ((Number) av.value).intValue(); + break; default: break; }