mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 09:23:52 -05:00
somewhat working delphi support (#2672)
This commit is contained in:
47
docs/WindowsDelphi.properties
Normal file
47
docs/WindowsDelphi.properties
Normal 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
|
||||
@@ -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
146
lib/compilers/pascal-win.js
Normal 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 [];
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user