somewhat working delphi support (#2672)

This commit is contained in:
Patrick Quist
2021-05-21 20:54:01 +02:00
committed by GitHub
parent ba6da76ffc
commit b2ac544920
4 changed files with 221 additions and 12 deletions

View File

@@ -0,0 +1,47 @@
compilers=&delphi:&delphi64
maxLinesOfAsm=1000
rpathFlag=-O
#################################
# Delphi
group.delphi.compilers=delphi21:delphi22:delphi23:delphi24:delphi25:delphi26
group.delphi.compilerType=pascal-win
group.delphi.demangler=
group.delphi.objdumper=D:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\objdump.exe
group.delphi.versionFlags=| grep "Version"
group.delphi64.compilers=delphi23_64:delphi24_64:delphi25_64:delphi26_64
group.delphi64.compilerType=pascal-win
group.delphi64.demangler=
group.delphi64.objdumper=D:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\objdump.exe
group.delphi64.versionFlags=| grep "Version"
compiler.delphi21.exe=C:\Program Files (x86)\Embarcadero\Studio\15.0\Bin\DCC32.EXE
compiler.delphi21.name=x86 Delphi XE7
compiler.delphi22.exe=C:\Program Files (x86)\Embarcadero\Studio\16.0\Bin\DCC32.EXE
compiler.delphi22.name=x86 Delphi XE8
compiler.delphi23.exe=C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\DCC32.exe
compiler.delphi23.name=x86 Delphi 10 Seattle
compiler.delphi23_64.exe=C:\Program Files (x86)\Embarcadero\Studio\17.0\bin\DCC64.exe
compiler.delphi23_64.name=x86-64 Delphi 10 Seattle
compiler.delphi24.exe=D:\Program Files (x86)\Embarcadero\Studio\18.0\Bin\DCC32.EXE
compiler.delphi24.name=x86 Delphi 10.1 Berlin
compiler.delphi24_64.exe=D:\Program Files (x86)\Embarcadero\Studio\18.0\Bin\DCC64.EXE
compiler.delphi24_64.name=x86-64 Delphi 10.1 Berlin
compiler.delphi25.exe=C:\Program Files (x86)\Embarcadero\Studio\19.0\Bin\DCC32.EXE
compiler.delphi25.name=x86 Delphi 10.2 Tokyo
compiler.delphi25_64.exe=C:\Program Files (x86)\Embarcadero\Studio\19.0\Bin\DCC64.EXE
compiler.delphi25_64.name=x86-64 Delphi 10.2 Tokyo
compiler.delphi26.exe=C:\Program Files (x86)\Embarcadero\Studio\20.0\Bin\DCC32.EXE
compiler.delphi26.name=x86 Delphi 10.3 Rio
compiler.delphi26_64.exe=C:\Program Files (x86)\Embarcadero\Studio\20.0\Bin\DCC64.EXE
compiler.delphi26_64.name=x86-64 Delphi 10.3 Rio

View File

@@ -51,6 +51,7 @@ export { OCamlCompiler } from './ocaml';
export { OptCompiler } from './opt';
export { OSACATool } from './osaca';
export { FPCCompiler } from './pascal';
export { PascalWinCompiler } from './pascal-win';
export { PPCICompiler } from './ppci';
export { PtxAssembler } from './ptxas';
export { PythonCompiler } from './python';

146
lib/compilers/pascal-win.js Normal file
View File

@@ -0,0 +1,146 @@
// Copyright (c) 2017, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
import path from 'path';
import fs from 'fs-extra';
import { BaseCompiler } from '../base-compiler';
import { MapFileReaderDelphi } from '../map-file-delphi';
import { PELabelReconstructor } from '../pe32-support';
import * as utils from '../utils';
export class PascalWinCompiler extends BaseCompiler {
static get key() { return 'pascal-win'; }
constructor(info, env) {
super(info, env);
info.supportsFiltersInBinary = true;
this.mapFilename = false;
this.compileFilename = 'output.pas';
}
exec(command, args, options) {
if (process.platform === 'linux' || process.platform === 'darwin') {
const wine = this.env.gccProps('wine');
args = args.slice(0);
if (command.toLowerCase().endsWith('.exe')) {
args.unshift(command);
command = wine;
}
}
return super.exec(command, args, options);
}
getOutputFilename(dirPath) {
return path.join(dirPath, 'prog.exe');
}
filename(fn) {
if (process.platform === 'linux' || process.platform === 'darwin') {
return 'Z:' + fn;
} else {
return super.filename(fn);
}
}
objdump(outputFilename, result, maxSize, intelAsm) {
outputFilename = this.getOutputFilename(path.dirname(outputFilename));
let args = ['-d', outputFilename];
if (intelAsm) args = args.concat(['-M', 'intel']);
return this.exec(this.compiler.objdumper, args, {maxOutput: 1024 * 1024 * 1024})
.then((objResult) => {
if (objResult.code !== 0) {
result.asm = '<No output: objdump returned ' + objResult.code + '>';
} else {
result.asm = objResult.stdout;
}
return result;
});
}
saveDummyProjectFile(dprfile, sourcefile) {
if (dprfile.startsWith('Z:')) {
dprfile = dprfile.substr(2);
}
fs.writeFileSync(dprfile,
'program prog; ' +
"uses output in '" + sourcefile + "'; " +
'begin ' +
'end.');
}
runCompiler(compiler, options, inputFilename, execOptions) {
if (!execOptions) {
execOptions = this.getDefaultExecOptions();
}
const tempPath = path.dirname(inputFilename);
const projectFile = path.join(tempPath, 'prog.dpr');
this.mapFilename = path.join(tempPath, 'prog.map');
inputFilename = inputFilename.replace(/\//g, '\\');
this.saveDummyProjectFile(projectFile, inputFilename);
options.pop();
options.unshift(
'-CC',
'-W',
'-H',
'-GD',
'-$D+',
'-V',
'-B');
options.push(projectFile.replace(/\//g, '\\'));
return this.exec(compiler, options, execOptions).then((result) => {
result.inputFilename = inputFilename;
result.stdout = utils.parseOutput(result.stdout, inputFilename);
result.stderr = utils.parseOutput(result.stderr, inputFilename);
return result;
});
}
optionsForFilter(filters) {
filters.binary = true;
filters.preProcessBinaryAsmLines = (asmLines) => {
const mapFileReader = new MapFileReaderDelphi(this.mapFilename);
const reconstructor = new PELabelReconstructor(asmLines, false, mapFileReader, false);
reconstructor.run('output');
return reconstructor.asmLines;
};
return [];
}
}

View File

@@ -29,7 +29,7 @@ export class PELabelReconstructor {
* @param {boolean} dontLabelUnmappedAddresses
* @param {MapFileReader} mapFileReader
*/
constructor(asmLines, dontLabelUnmappedAddresses, mapFileReader) {
constructor(asmLines, dontLabelUnmappedAddresses, mapFileReader, needsReconstruction = true) {
this.asmLines = asmLines;
this.addressesToLabel = [];
this.dontLabelUnmappedAddresses = dontLabelUnmappedAddresses;
@@ -40,6 +40,7 @@ export class PELabelReconstructor {
this.int3Regex = /\tcc\s*\tint3\s*$/i;
this.mapFileReader = mapFileReader;
this.needsReconstruction = needsReconstruction;
}
/**
@@ -89,21 +90,35 @@ export class PELabelReconstructor {
* @param {string} unitName
*/
deleteEverythingBut(unitName) {
// todo: deletion by reconstructed addresses is a VS specific technique,
// delphi mapping is more precise and doesnt need reconstruction
if (this.needsReconstruction) {
let unitAddressSpaces = this.mapFileReader.getReconstructedUnitAddressSpace(unitName);
let unitAddressSpaces = this.mapFileReader.getReconstructedUnitAddressSpace(unitName);
for (let idx = 0; idx < this.mapFileReader.reconstructedSegments.length; idx++) {
const info = this.mapFileReader.reconstructedSegments[idx];
if (info.unitName !== unitName) {
if (info.segmentLength > 0) {
if (!this.mapFileReader.isWithinAddressSpace(unitAddressSpaces,
info.addressInt, info.segmentLength)) {
this.deleteLinesBetweenAddresses(info.addressInt, info.addressInt + info.segmentLength);
for (let idx = 0; idx < this.mapFileReader.reconstructedSegments.length; idx++) {
const info = this.mapFileReader.reconstructedSegments[idx];
if (info.unitName !== unitName) {
if (info.segmentLength > 0) {
if (!this.mapFileReader.isWithinAddressSpace(unitAddressSpaces,
info.addressInt, info.segmentLength)) {
this.deleteLinesBetweenAddresses(info.addressInt, info.addressInt + info.segmentLength);
}
}
}
}
} else {
let idx, info;
for (idx = 0; idx < this.mapFileReader.segments.length; idx++) {
info = this.mapFileReader.segments[idx];
if (info.unitName !== unitName) {
this.deleteLinesBetweenAddresses(info.addressInt, info.addressInt + info.segmentLength);
}
}
for (idx = 0; idx < this.mapFileReader.isegments.length; idx++) {
info = this.mapFileReader.isegments[idx];
if (info.unitName !== unitName) {
this.deleteLinesBetweenAddresses(info.addressInt, info.addressInt + info.segmentLength);
}
}
}
}