mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 12:55:40 +02:00
Improve PE64 symbol presentation in Project Explorer
Enhances PE64/COFF symbol presentation for parity with ELF symbol presentation within Project Explorer.
This commit is contained in:
parent
0173da5325
commit
0e41dfea40
8 changed files with 283 additions and 79 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2023 QNX Software Systems and others.
|
* Copyright (c) 2000, 2024 QNX Software Systems and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -13,32 +13,22 @@
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* John Dallaway - Adapt for IBinaryFile (#413)
|
* John Dallaway - Adapt for IBinaryFile (#413)
|
||||||
* John Dallaway - Fix object path processing (#630)
|
* John Dallaway - Fix object path processing (#630)
|
||||||
|
* John Dallaway - Use common buildCWD lookup methods (#652)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.model;
|
package org.eclipse.cdt.internal.core.model;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
|
||||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
||||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||||
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
|
|
||||||
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
|
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
|
||||||
import org.eclipse.cdt.core.model.IArchive;
|
import org.eclipse.cdt.core.model.IArchive;
|
||||||
import org.eclipse.cdt.core.model.IBinary;
|
import org.eclipse.cdt.core.model.IBinary;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
|
||||||
import org.eclipse.cdt.core.settings.model.ICOutputEntry;
|
|
||||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
|
||||||
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
|
|
||||||
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
|
|
||||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
|
||||||
import org.eclipse.cdt.internal.core.util.MementoTokenizer;
|
import org.eclipse.cdt.internal.core.util.MementoTokenizer;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IProject;
|
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
import org.eclipse.core.runtime.Assert;
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
@ -93,8 +83,8 @@ public class Archive extends Openable implements IArchive {
|
||||||
IPath location = res.getLocation();
|
IPath location = res.getLocation();
|
||||||
if (ar != null && location != null) {
|
if (ar != null && location != null) {
|
||||||
// find the build CWD for the archive file
|
// find the build CWD for the archive file
|
||||||
IPath buildCWD = Optional.ofNullable(findBuildConfiguration(res)).map(Archive::getBuildCWD)
|
IPath buildCWD = Optional.ofNullable(InternalCoreModelUtil.findBuildConfiguration(res))
|
||||||
.orElse(location.removeLastSegments(1));
|
.map(InternalCoreModelUtil::getBuildCWD).orElse(location.removeLastSegments(1));
|
||||||
for (IBinaryObject obj : ar.getObjects()) {
|
for (IBinaryObject obj : ar.getObjects()) {
|
||||||
// assume object names are paths as specified on the archiver command line ("ar -P")
|
// assume object names are paths as specified on the archiver command line ("ar -P")
|
||||||
IPath objPath = new Path(obj.getName());
|
IPath objPath = new Path(obj.getName());
|
||||||
|
@ -162,50 +152,4 @@ public class Archive extends Openable implements IArchive {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICConfigurationDescription findBuildConfiguration(IResource resource) {
|
|
||||||
IPath location = resource.getLocation();
|
|
||||||
IProject project = resource.getProject();
|
|
||||||
ICProjectDescription projectDesc = CoreModel.getDefault().getProjectDescription(project, false);
|
|
||||||
if (projectDesc == null) {
|
|
||||||
return null; // not a CDT project
|
|
||||||
}
|
|
||||||
// for each build configuration of the project
|
|
||||||
for (ICConfigurationDescription configDesc : projectDesc.getConfigurations()) {
|
|
||||||
CConfigurationData configData = configDesc.getConfigurationData();
|
|
||||||
if (configData == null) {
|
|
||||||
continue; // no configuration data
|
|
||||||
}
|
|
||||||
CBuildData buildData = configData.getBuildData();
|
|
||||||
if (buildData == null) {
|
|
||||||
continue; // no build data
|
|
||||||
}
|
|
||||||
// for each build output directory of the build configuration
|
|
||||||
for (ICOutputEntry dir : buildData.getOutputDirectories()) {
|
|
||||||
IPath dirLocation = CDataUtil.makeAbsolute(project, dir).getLocation();
|
|
||||||
// if the build output directory is an ancestor of the resource
|
|
||||||
if ((dirLocation != null) && dirLocation.isPrefixOf(location)) {
|
|
||||||
return configDesc; // build configuration found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IPath getBuildCWD(ICConfigurationDescription configDesc) {
|
|
||||||
IPath builderCWD = configDesc.getBuildSetting().getBuilderCWD();
|
|
||||||
if (builderCWD != null) {
|
|
||||||
ICdtVariableManager manager = CCorePlugin.getDefault().getCdtVariableManager();
|
|
||||||
try {
|
|
||||||
String cwd = builderCWD.toString();
|
|
||||||
cwd = manager.resolveValue(cwd, "", null, configDesc); //$NON-NLS-1$
|
|
||||||
if (!cwd.isEmpty()) {
|
|
||||||
return new Path(cwd);
|
|
||||||
}
|
|
||||||
} catch (CdtVariableException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2023 QNX Software Systems and others.
|
* Copyright (c) 2000, 2024 QNX Software Systems and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* John Dallaway - Adapt for IBinaryFile (#413)
|
* John Dallaway - Adapt for IBinaryFile (#413)
|
||||||
|
* John Dallaway - Support source file lookup from relative path (#652)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.model;
|
package org.eclipse.cdt.internal.core.model;
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||||
|
@ -282,7 +284,7 @@ public class Binary extends Openable implements IBinary {
|
||||||
// information. If not, fall back on information from the binary parser.
|
// information. If not, fall back on information from the binary parser.
|
||||||
boolean showSourceFiles = Platform.getPreferencesService().getBoolean(CCorePlugin.PLUGIN_ID,
|
boolean showSourceFiles = Platform.getPreferencesService().getBoolean(CCorePlugin.PLUGIN_ID,
|
||||||
CCorePreferenceConstants.SHOW_SOURCE_FILES_IN_BINARIES, false, null);
|
CCorePreferenceConstants.SHOW_SOURCE_FILES_IN_BINARIES, false, null);
|
||||||
if (!showSourceFiles || !addSourceFiles(info, obj, hash)) {
|
if (!showSourceFiles || !addSourceFiles(info, res, obj, hash)) {
|
||||||
ISymbol[] symbols = obj.getSymbols();
|
ISymbol[] symbols = obj.getSymbols();
|
||||||
for (ISymbol symbol : symbols) {
|
for (ISymbol symbol : symbols) {
|
||||||
switch (symbol.getType()) {
|
switch (symbol.getType()) {
|
||||||
|
@ -302,7 +304,7 @@ public class Binary extends Openable implements IBinary {
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addSourceFiles(OpenableInfo info, IBinaryObject obj, Map<IPath, BinaryModule> hash)
|
private boolean addSourceFiles(OpenableInfo info, IResource res, IBinaryObject obj, Map<IPath, BinaryModule> hash)
|
||||||
throws CModelException {
|
throws CModelException {
|
||||||
// Try to get the list of source files used to build the binary from the
|
// Try to get the list of source files used to build the binary from the
|
||||||
// symbol information.
|
// symbol information.
|
||||||
|
@ -315,7 +317,12 @@ public class Binary extends Openable implements IBinary {
|
||||||
sourceFiles = symbolreader.getSourceFiles();
|
sourceFiles = symbolreader.getSourceFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFiles != null && sourceFiles.length > 0) {
|
final IPath location = res.getLocation();
|
||||||
|
if (location != null && sourceFiles != null && sourceFiles.length > 0) {
|
||||||
|
// find the build CWD for the archive file
|
||||||
|
IPath buildCWD = Optional.ofNullable(InternalCoreModelUtil.findBuildConfiguration(res))
|
||||||
|
.map(InternalCoreModelUtil::getBuildCWD).orElse(location.removeLastSegments(1));
|
||||||
|
|
||||||
ISourceFinder srcFinder = getAdapter(ISourceFinder.class);
|
ISourceFinder srcFinder = getAdapter(ISourceFinder.class);
|
||||||
try {
|
try {
|
||||||
for (String filename : sourceFiles) {
|
for (String filename : sourceFiles) {
|
||||||
|
@ -328,11 +335,17 @@ public class Binary extends Openable implements IBinary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPath path = new Path(filename);
|
||||||
|
if (!path.isAbsolute()) {
|
||||||
|
// assume path is relative to the build CWD
|
||||||
|
path = buildCWD.append(path);
|
||||||
|
}
|
||||||
|
|
||||||
// Be careful how you use this File object. If filename is a relative path, the resulting File
|
// Be careful how you use this File object. If filename is a relative path, the resulting File
|
||||||
// object will apply the relative path to the working directory, which is not what we want.
|
// object will apply the relative path to the working directory, which is not what we want.
|
||||||
// Stay away from methods that return or use the absolute path of the object. Note that
|
// Stay away from methods that return or use the absolute path of the object. Note that
|
||||||
// File.isAbsolute() returns false when the object was constructed with a relative path.
|
// File.isAbsolute() returns false when the object was constructed with a relative path.
|
||||||
File file = new File(filename);
|
File file = path.toFile();
|
||||||
|
|
||||||
// Create a translation unit for this file and add it as a child of the binary
|
// Create a translation unit for this file and add it as a child of the binary
|
||||||
String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), file.getName());
|
String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), file.getName());
|
||||||
|
@ -345,7 +358,7 @@ public class Binary extends Openable implements IBinary {
|
||||||
// We check this to determine if we should create a TranslationUnit or ExternalTranslationUnit
|
// We check this to determine if we should create a TranslationUnit or ExternalTranslationUnit
|
||||||
IFile wkspFile = null;
|
IFile wkspFile = null;
|
||||||
if (file.isAbsolute()) {
|
if (file.isAbsolute()) {
|
||||||
IFile[] filesInWP = ResourceLookup.findFilesForLocation(new Path(filename));
|
IFile[] filesInWP = ResourceLookup.findFilesForLocation(path);
|
||||||
|
|
||||||
for (IFile element : filesInWP) {
|
for (IFile element : filesInWP) {
|
||||||
if (element.isAccessible()) {
|
if (element.isAccessible()) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2010, 2015 Google, Inc and others.
|
* Copyright (c) 2010, 2024 Google, Inc and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -9,7 +9,8 @@
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Sergey Prigogin (Google) - initial API and implementation
|
* Sergey Prigogin (Google) - initial API and implementation
|
||||||
|
* John Dallaway - Support build CWD lookup (#652)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.model;
|
package org.eclipse.cdt.internal.core.model;
|
||||||
|
|
||||||
|
@ -20,16 +21,23 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
|
||||||
|
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.IPathEntry;
|
import org.eclipse.cdt.core.model.IPathEntry;
|
||||||
import org.eclipse.cdt.core.model.ISourceEntry;
|
import org.eclipse.cdt.core.model.ISourceEntry;
|
||||||
import org.eclipse.cdt.core.settings.model.CSourceEntry;
|
import org.eclipse.cdt.core.settings.model.CSourceEntry;
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICOutputEntry;
|
||||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||||
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
|
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
|
||||||
import org.eclipse.cdt.core.settings.model.WriteAccessException;
|
import org.eclipse.cdt.core.settings.model.WriteAccessException;
|
||||||
|
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
|
||||||
|
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
|
||||||
|
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||||
import org.eclipse.core.resources.IFolder;
|
import org.eclipse.core.resources.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
@ -89,4 +97,51 @@ public class InternalCoreModelUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ICConfigurationDescription findBuildConfiguration(IResource resource) {
|
||||||
|
IPath location = resource.getLocation();
|
||||||
|
IProject project = resource.getProject();
|
||||||
|
ICProjectDescription projectDesc = CoreModel.getDefault().getProjectDescription(project, false);
|
||||||
|
if (projectDesc == null) {
|
||||||
|
return null; // not a CDT project
|
||||||
|
}
|
||||||
|
// for each build configuration of the project
|
||||||
|
for (ICConfigurationDescription configDesc : projectDesc.getConfigurations()) {
|
||||||
|
CConfigurationData configData = configDesc.getConfigurationData();
|
||||||
|
if (configData == null) {
|
||||||
|
continue; // no configuration data
|
||||||
|
}
|
||||||
|
CBuildData buildData = configData.getBuildData();
|
||||||
|
if (buildData == null) {
|
||||||
|
continue; // no build data
|
||||||
|
}
|
||||||
|
// for each build output directory of the build configuration
|
||||||
|
for (ICOutputEntry dir : buildData.getOutputDirectories()) {
|
||||||
|
IPath dirLocation = CDataUtil.makeAbsolute(project, dir).getLocation();
|
||||||
|
// if the build output directory is an ancestor of the resource
|
||||||
|
if ((dirLocation != null) && dirLocation.isPrefixOf(location)) {
|
||||||
|
return configDesc; // build configuration found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPath getBuildCWD(ICConfigurationDescription configDesc) {
|
||||||
|
IPath builderCWD = configDesc.getBuildSetting().getBuilderCWD();
|
||||||
|
if (builderCWD != null) {
|
||||||
|
ICdtVariableManager manager = CCorePlugin.getDefault().getCdtVariableManager();
|
||||||
|
try {
|
||||||
|
String cwd = builderCWD.toString();
|
||||||
|
cwd = manager.resolveValue(cwd, "", null, configDesc); //$NON-NLS-1$
|
||||||
|
if (!cwd.isEmpty()) {
|
||||||
|
return new Path(cwd);
|
||||||
|
}
|
||||||
|
} catch (CdtVariableException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
* Space Codesign Systems - Initial API and implementation
|
* Space Codesign Systems - Initial API and implementation
|
||||||
* QNX Software Systems - initial CygwinPEBinaryArchive class
|
* QNX Software Systems - initial CygwinPEBinaryArchive class
|
||||||
* John Dallaway - Initial GNUPEBinaryArchive64 class (#361)
|
* John Dallaway - Initial GNUPEBinaryArchive64 class (#361)
|
||||||
|
* John Dallaway - Update for parity with GNU ELF implementation (#652)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.utils.coff.parser;
|
package org.eclipse.cdt.utils.coff.parser;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||||
import org.eclipse.cdt.utils.AR.ARHeader;
|
import org.eclipse.cdt.utils.AR.ARHeader;
|
||||||
|
@ -30,11 +30,12 @@ public class GNUPEBinaryArchive64 extends PEBinaryArchive64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addArchiveMembers(ARHeader[] headers, ArrayList<IBinaryObject> children2) {
|
protected IBinaryObject[] createArchiveMembers(ARHeader[] headers) {
|
||||||
|
IBinaryObject[] result = new IBinaryObject[headers.length];
|
||||||
for (int i = 0; i < headers.length; i++) {
|
for (int i = 0; i < headers.length; i++) {
|
||||||
IBinaryObject bin = new GNUPEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
|
result[i] = new GNUPEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
|
||||||
children.add(bin);
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2023 Space Codesign Systems and others.
|
* Copyright (c) 2000, 2024 Space Codesign Systems and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -12,22 +12,38 @@
|
||||||
* Space Codesign Systems - Initial API and implementation
|
* Space Codesign Systems - Initial API and implementation
|
||||||
* QNX Software Systems - Initial CygwinPEBinaryObject class
|
* QNX Software Systems - Initial CygwinPEBinaryObject class
|
||||||
* John Dallaway - Initial GNUPEBinaryObject64 class (#361)
|
* John Dallaway - Initial GNUPEBinaryObject64 class (#361)
|
||||||
|
* John Dallaway - Update for parity with GNU ELF implementation (#652)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.utils.coff.parser;
|
package org.eclipse.cdt.utils.coff.parser;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.IAddress;
|
||||||
import org.eclipse.cdt.core.IBinaryParser;
|
import org.eclipse.cdt.core.IBinaryParser;
|
||||||
|
import org.eclipse.cdt.core.IBinaryParser.ISymbol;
|
||||||
import org.eclipse.cdt.utils.AR.ARHeader;
|
import org.eclipse.cdt.utils.AR.ARHeader;
|
||||||
|
import org.eclipse.cdt.utils.Addr2line;
|
||||||
|
import org.eclipse.cdt.utils.Addr32;
|
||||||
|
import org.eclipse.cdt.utils.CPPFilt;
|
||||||
import org.eclipse.cdt.utils.IGnuToolFactory;
|
import org.eclipse.cdt.utils.IGnuToolFactory;
|
||||||
import org.eclipse.cdt.utils.Objdump;
|
import org.eclipse.cdt.utils.Objdump;
|
||||||
|
import org.eclipse.cdt.utils.Symbol;
|
||||||
|
import org.eclipse.cdt.utils.coff.Coff64;
|
||||||
|
import org.eclipse.cdt.utils.coff.PE64;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
/** @since 8.2 */
|
/** @since 8.2 */
|
||||||
public class GNUPEBinaryObject64 extends PEBinaryObject64 {
|
public class GNUPEBinaryObject64 extends PEBinaryObject64 {
|
||||||
|
|
||||||
|
private Addr2line autoDisposeAddr2line;
|
||||||
|
private Addr2line symbolLoadingAddr2line;
|
||||||
|
private CPPFilt symbolLoadingCPPFilt;
|
||||||
|
long starttime;
|
||||||
|
|
||||||
public GNUPEBinaryObject64(IBinaryParser parser, IPath path, ARHeader header) {
|
public GNUPEBinaryObject64(IBinaryParser parser, IPath path, ARHeader header) {
|
||||||
super(parser, path, header);
|
super(parser, path, header);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +70,60 @@ public class GNUPEBinaryObject64 extends PEBinaryObject64 {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 8.4 */
|
||||||
|
public Addr2line getAddr2line(boolean autodisposing) {
|
||||||
|
if (!autodisposing) {
|
||||||
|
return getAddr2line();
|
||||||
|
}
|
||||||
|
if (autoDisposeAddr2line == null) {
|
||||||
|
autoDisposeAddr2line = getAddr2line();
|
||||||
|
if (autoDisposeAddr2line != null) {
|
||||||
|
starttime = System.currentTimeMillis();
|
||||||
|
Runnable worker = () -> {
|
||||||
|
|
||||||
|
long diff = System.currentTimeMillis() - starttime;
|
||||||
|
while (diff < 10000) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
diff = System.currentTimeMillis() - starttime;
|
||||||
|
}
|
||||||
|
stopAddr2Line();
|
||||||
|
};
|
||||||
|
new Thread(worker, "Addr2line Reaper").start(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
starttime = System.currentTimeMillis(); // reset autodispose timeout
|
||||||
|
}
|
||||||
|
return autoDisposeAddr2line;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void stopAddr2Line() {
|
||||||
|
if (autoDisposeAddr2line != null) {
|
||||||
|
autoDisposeAddr2line.dispose();
|
||||||
|
}
|
||||||
|
autoDisposeAddr2line = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Addr2line getAddr2line() {
|
||||||
|
IGnuToolFactory factory = getBinaryParser().getAdapter(IGnuToolFactory.class);
|
||||||
|
if (factory != null) {
|
||||||
|
return factory.getAddr2line(getPath());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 8.4 */
|
||||||
|
protected CPPFilt getCPPFilt() {
|
||||||
|
IGnuToolFactory factory = getBinaryParser().getAdapter(IGnuToolFactory.class);
|
||||||
|
if (factory != null) {
|
||||||
|
return factory.getCPPFilt();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected Objdump getObjdump() {
|
protected Objdump getObjdump() {
|
||||||
IGnuToolFactory factory = getBinaryParser().getAdapter(IGnuToolFactory.class);
|
IGnuToolFactory factory = getBinaryParser().getAdapter(IGnuToolFactory.class);
|
||||||
if (factory != null) {
|
if (factory != null) {
|
||||||
|
@ -62,4 +132,60 @@ public class GNUPEBinaryObject64 extends PEBinaryObject64 {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadSymbols(PE64 pe) throws IOException {
|
||||||
|
symbolLoadingAddr2line = getAddr2line(false);
|
||||||
|
symbolLoadingCPPFilt = getCPPFilt();
|
||||||
|
try {
|
||||||
|
super.loadSymbols(pe);
|
||||||
|
} finally {
|
||||||
|
if (symbolLoadingAddr2line != null) {
|
||||||
|
symbolLoadingAddr2line.dispose();
|
||||||
|
symbolLoadingAddr2line = null;
|
||||||
|
}
|
||||||
|
if (symbolLoadingCPPFilt != null) {
|
||||||
|
symbolLoadingCPPFilt.dispose();
|
||||||
|
symbolLoadingCPPFilt = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addSymbols(Coff64.Symbol[] peSyms, byte[] table, List<Symbol> list) {
|
||||||
|
for (Coff64.Symbol element : peSyms) {
|
||||||
|
if ((element.n_sclass != Coff64.Symbol.SC_EXTERNAL) || (element.n_scnum <= 0)) {
|
||||||
|
continue; // ignore non-external symbol
|
||||||
|
}
|
||||||
|
String name = element.toString();
|
||||||
|
if (symbolLoadingCPPFilt != null) {
|
||||||
|
try {
|
||||||
|
name = symbolLoadingCPPFilt.getFunction(name);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
symbolLoadingCPPFilt.dispose();
|
||||||
|
symbolLoadingCPPFilt = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IAddress addr = new Addr32(element.n_value);
|
||||||
|
long size = element.getSize();
|
||||||
|
int type = element.isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE;
|
||||||
|
if (symbolLoadingAddr2line != null) {
|
||||||
|
try {
|
||||||
|
String filename = symbolLoadingAddr2line.getFileName(addr);
|
||||||
|
// addr2line returns "??" when it can not find the file
|
||||||
|
IPath file = (filename != null && !filename.equals("??")) ? new Path(filename) : Path.EMPTY; //$NON-NLS-1$
|
||||||
|
int startLine = symbolLoadingAddr2line.getLineNumber(addr);
|
||||||
|
int endLine = symbolLoadingAddr2line.getLineNumber(addr.add(size - 1));
|
||||||
|
list.add(new GNUPESymbol64(this, name, type, addr, size, file, startLine, endLine));
|
||||||
|
} catch (IOException e) {
|
||||||
|
symbolLoadingAddr2line.dispose();
|
||||||
|
symbolLoadingAddr2line = null;
|
||||||
|
// the symbol still needs to be added
|
||||||
|
list.add(new GNUPESymbol64(this, name, type, addr, size));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list.add(new GNUPESymbol64(this, name, type, addr, size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2024 QNX Software Systems and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation of GNUSymbol
|
||||||
|
* John Dallaway - Initial GNUPESymbol64 class (#652)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.utils.coff.parser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.IAddress;
|
||||||
|
import org.eclipse.cdt.utils.Addr2line;
|
||||||
|
import org.eclipse.cdt.utils.Symbol;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 8.4
|
||||||
|
*/
|
||||||
|
public class GNUPESymbol64 extends Symbol {
|
||||||
|
|
||||||
|
public GNUPESymbol64(GNUPEBinaryObject64 binary, String name, int type, IAddress addr, long size, IPath sourceFile,
|
||||||
|
int startLine, int endLine) {
|
||||||
|
super(binary, name, type, addr, size, sourceFile, startLine, endLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GNUPESymbol64(GNUPEBinaryObject64 binary, String name, int type, IAddress addr, long size) {
|
||||||
|
super(binary, name, type, addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLineNumber(long offset) {
|
||||||
|
int line = -1;
|
||||||
|
Addr2line addr2line = ((GNUPEBinaryObject64) binary).getAddr2line(true);
|
||||||
|
if (addr2line != null) {
|
||||||
|
try {
|
||||||
|
return addr2line.getLineNumber(getAddress().add(offset));
|
||||||
|
} catch (IOException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2019 Space Codesign Systems and others.
|
* Copyright (c) 2000, 2024 Space Codesign Systems and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -11,11 +11,13 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Space Codesign Systems - Initial API and implementation
|
* Space Codesign Systems - Initial API and implementation
|
||||||
* QNX Software Systems - Initial PEBinaryArchive class
|
* QNX Software Systems - Initial PEBinaryArchive class
|
||||||
|
* John Dallaway - Update for parity with ELF implementation (#630)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.utils.coff.parser;
|
package org.eclipse.cdt.utils.coff.parser;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
||||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||||
|
@ -51,7 +53,8 @@ public class PEBinaryArchive64 extends BinaryFile implements IBinaryArchive {
|
||||||
try {
|
try {
|
||||||
ar = new AR(getPath().toOSString());
|
ar = new AR(getPath().toOSString());
|
||||||
AR.ARHeader[] headers = ar.getHeaders();
|
AR.ARHeader[] headers = ar.getHeaders();
|
||||||
addArchiveMembers(headers, children);
|
IBinaryObject[] bobjs = createArchiveMembers(headers);
|
||||||
|
children.addAll(Arrays.asList(bobjs));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
//e.printStackTrace();
|
//e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -63,10 +66,21 @@ public class PEBinaryArchive64 extends BinaryFile implements IBinaryArchive {
|
||||||
return children.toArray(new IBinaryObject[0]);
|
return children.toArray(new IBinaryObject[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 8.4 */
|
||||||
|
protected IBinaryObject[] createArchiveMembers(ARHeader[] headers) {
|
||||||
|
IBinaryObject[] result = new IBinaryObject[headers.length];
|
||||||
|
for (int i = 0; i < headers.length; i++) {
|
||||||
|
result[i] = new PEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param headers
|
* @param headers
|
||||||
* @param children2
|
* @param children2
|
||||||
|
* @deprecated use {@link #createArchiveMembers(ARHeader[])}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
protected void addArchiveMembers(ARHeader[] headers, ArrayList<IBinaryObject> children2) {
|
protected void addArchiveMembers(ARHeader[] headers, ArrayList<IBinaryObject> children2) {
|
||||||
for (int i = 0; i < headers.length; i++) {
|
for (int i = 0; i < headers.length; i++) {
|
||||||
IBinaryObject bin = new PEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
|
IBinaryObject bin = new PEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2023 Space Codesign Systems and others.
|
* Copyright (c) 2000, 2024 Space Codesign Systems and others.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License 2.0
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
* Space Codesign Systems - Initial API and implementation
|
* Space Codesign Systems - Initial API and implementation
|
||||||
* QNX Software Systems - Initial PEBinaryObject class
|
* QNX Software Systems - Initial PEBinaryObject class
|
||||||
* John Dallaway - Fix archive header processing (#630)
|
* John Dallaway - Fix archive header processing (#630)
|
||||||
* John Dallaway - Support sections sizes in binary info (#652)
|
* John Dallaway - Support sections sizes and all external symbols (#652)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.utils.coff.parser;
|
package org.eclipse.cdt.utils.coff.parser;
|
||||||
|
|
||||||
|
@ -170,8 +170,8 @@ public class PEBinaryObject64 extends BinaryObjectAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addSymbols(Coff64.Symbol[] peSyms, byte[] table, List<Symbol> list) {
|
protected void addSymbols(Coff64.Symbol[] peSyms, byte[] table, List<Symbol> list) {
|
||||||
for (org.eclipse.cdt.utils.coff.Coff64.Symbol peSym : peSyms) {
|
for (Coff64.Symbol peSym : peSyms) {
|
||||||
if (peSym.isFunction() || peSym.isPointer() || peSym.isArray()) {
|
if ((peSym.n_sclass == Coff64.Symbol.SC_EXTERNAL) && (peSym.n_scnum > 0)) {
|
||||||
String name = peSym.getName(table);
|
String name = peSym.getName(table);
|
||||||
if (name == null || name.trim().length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) {
|
if (name == null || name.trim().length() == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Add table
Reference in a new issue