Skip to content

Commit

Permalink
Improve PE64 symbol presentation in Project Explorer
Browse files Browse the repository at this point in the history
Enhances PE64/COFF symbol presentation for parity with ELF symbol
presentation within Project Explorer.
  • Loading branch information
jld01 committed Jan 4, 2024
1 parent 0173da5 commit 0e41dfe
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -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
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -13,32 +13,22 @@
* Anton Leherbauer (Wind River Systems)
* John Dallaway - Adapt for IBinaryFile (#413)
* John Dallaway - Fix object path processing (#630)
* John Dallaway - Use common buildCWD lookup methods (#652)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;

import java.util.Map;
import java.util.Optional;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
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.CoreModel;
import org.eclipse.cdt.core.model.IArchive;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement;
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.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
Expand Down Expand Up @@ -93,8 +83,8 @@ public boolean computeChildren(OpenableInfo info, IResource res) {
IPath location = res.getLocation();
if (ar != null && location != null) {
// find the build CWD for the archive file
IPath buildCWD = Optional.ofNullable(findBuildConfiguration(res)).map(Archive::getBuildCWD)
.orElse(location.removeLastSegments(1));
IPath buildCWD = Optional.ofNullable(InternalCoreModelUtil.findBuildConfiguration(res))
.map(InternalCoreModelUtil::getBuildCWD).orElse(location.removeLastSegments(1));
for (IBinaryObject obj : ar.getObjects()) {
// assume object names are paths as specified on the archiver command line ("ar -P")
IPath objPath = new Path(obj.getName());
Expand Down Expand Up @@ -162,50 +152,4 @@ protected char getHandleMementoDelimiter() {
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;
}

}
Original file line number Diff line number Diff line change
@@ -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
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -13,6 +13,7 @@
* Markus Schorn (Wind River Systems)
* Anton Leherbauer (Wind River Systems)
* John Dallaway - Adapt for IBinaryFile (#413)
* John Dallaway - Support source file lookup from relative path (#652)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;

Expand All @@ -22,6 +23,7 @@
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CCorePreferenceConstants;
Expand Down Expand Up @@ -282,7 +284,7 @@ boolean computeChildren(OpenableInfo info, IResource res) throws CModelException
// information. If not, fall back on information from the binary parser.
boolean showSourceFiles = Platform.getPreferencesService().getBoolean(CCorePlugin.PLUGIN_ID,
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();
for (ISymbol symbol : symbols) {
switch (symbol.getType()) {
Expand All @@ -302,7 +304,7 @@ boolean computeChildren(OpenableInfo info, IResource res) throws CModelException
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 {
// Try to get the list of source files used to build the binary from the
// symbol information.
Expand All @@ -315,7 +317,12 @@ private boolean addSourceFiles(OpenableInfo info, IBinaryObject obj, Map<IPath,
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);
try {
for (String filename : sourceFiles) {
Expand All @@ -328,11 +335,17 @@ private boolean addSourceFiles(OpenableInfo info, IBinaryObject obj, Map<IPath,
}
}

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
// 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
// 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
String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), file.getName());
Expand All @@ -345,7 +358,7 @@ private boolean addSourceFiles(OpenableInfo info, IBinaryObject obj, Map<IPath,
// We check this to determine if we should create a TranslationUnit or ExternalTranslationUnit
IFile wkspFile = null;
if (file.isAbsolute()) {
IFile[] filesInWP = ResourceLookup.findFilesForLocation(new Path(filename));
IFile[] filesInWP = ResourceLookup.findFilesForLocation(path);

for (IFile element : filesInWP) {
if (element.isAccessible()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -9,7 +9,8 @@
* SPDX-License-Identifier: EPL-2.0
*
* 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;

Expand All @@ -20,16 +21,23 @@
import java.util.Set;

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.IPathEntry;
import org.eclipse.cdt.core.model.ISourceEntry;
import org.eclipse.cdt.core.settings.model.CSourceEntry;
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.ICSourceEntry;
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.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
Expand Down Expand Up @@ -89,4 +97,51 @@ public static void addExclusionPatterns(IPathEntry newEntry, List<IPathEntry> ex
}
}
}

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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
* Space Codesign Systems - Initial API and implementation
* QNX Software Systems - initial CygwinPEBinaryArchive class
* John Dallaway - Initial GNUPEBinaryArchive64 class (#361)
* John Dallaway - Update for parity with GNU ELF implementation (#652)
*******************************************************************************/
package org.eclipse.cdt.utils.coff.parser;

import java.io.IOException;
import java.util.ArrayList;

import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.utils.AR.ARHeader;
Expand All @@ -30,11 +30,12 @@ public GNUPEBinaryArchive64(PEParser64 parser, IPath path) throws IOException {
}

@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++) {
IBinaryObject bin = new GNUPEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
children.add(bin);
result[i] = new GNUPEBinaryObject64(getBinaryParser(), getPath(), headers[i]);
}
return result;
}

}
Loading

0 comments on commit 0e41dfe

Please sign in to comment.