Skip to content

Commit

Permalink
Port pe32-support to ts; replace some optional fields with T|undefined (
Browse files Browse the repository at this point in the history
#4438)

* Port pe32-support to ts; replace some optional fields with T|undefined
  • Loading branch information
mattgodbolt committed Jan 24, 2023
1 parent 44dd972 commit 0e246d2
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 89 deletions.
40 changes: 20 additions & 20 deletions lib/mapfiles/map-file.ts
Expand Up @@ -33,7 +33,7 @@ type SegmentOffset = {
segmentLength: number;
};

type Segment = {
export type Segment = {
segment: string;
addressInt: number;
address: string;
Expand Down Expand Up @@ -103,7 +103,7 @@ export class MapFileReader {
}
}

getLineInfoByAddress(segment: string | boolean, address: number) {
getLineInfoByAddress(segment: string | undefined, address: number): LineNumber | undefined {
for (let idx = 0; idx < this.lineNumbers.length; idx++) {
const lineInfo = this.lineNumbers[idx];
if (!segment && lineInfo.addressInt === address) {
Expand All @@ -113,7 +113,7 @@ export class MapFileReader {
}
}

return false;
return undefined;
}

getSegmentOffset(segment: string): number {
Expand Down Expand Up @@ -157,29 +157,29 @@ export class MapFileReader {
});
}

getSegmentInfoByUnitName(unitName: string) {
getSegmentInfoByUnitName(unitName: string): Segment | undefined {
for (let idx = 0; idx < this.segments.length; idx++) {
const info = this.segments[idx];
if (info.unitName === unitName) {
return info;
}
}

return false;
return undefined;
}

getICodeSegmentInfoByUnitName(unitName: string) {
getICodeSegmentInfoByUnitName(unitName: string): Segment | undefined {
for (let idx = 0; idx < this.isegments.length; idx++) {
const info = this.isegments[idx];
if (info.unitName === unitName) {
return info;
}
}

return false;
return undefined;
}

getSegmentIdByUnitName(unitName: string) {
getSegmentIdByUnitName(unitName: string): number | undefined {
const info = this.getSegmentInfoByUnitName(unitName);
if (info) {
return info.id;
Expand All @@ -191,7 +191,7 @@ export class MapFileReader {
/**
* Get Segment info for exact address
*/
getSegmentInfoByStartingAddress(segment: string | boolean, address: number) {
getSegmentInfoByStartingAddress(segment: string | undefined, address: number): Segment | undefined {
for (let idx = 0; idx < this.segments.length; idx++) {
const info = this.segments[idx];
if (!segment && info.addressInt === address) {
Expand All @@ -201,13 +201,13 @@ export class MapFileReader {
}
}

return false;
return undefined;
}

/**
* Get Segment info for the segment where the given address is in
*/
getSegmentInfoAddressIsIn(segment: string | boolean, address: number) {
getSegmentInfoAddressIsIn(segment: string | undefined, address: number): Segment | undefined {
for (let idx = 0; idx < this.segments.length; idx++) {
const info = this.segments[idx];
if (!segment && address >= info.addressInt && address < info.addressInt + info.segmentLength) {
Expand All @@ -221,13 +221,13 @@ export class MapFileReader {
}
}

return false;
return undefined;
}

/**
* Get Segment info for the segment where the given address is in
*/
getSegmentInfoAddressWithoutOffsetIsIn(segment: string, address: number) {
getSegmentInfoAddressWithoutOffsetIsIn(segment: string, address: number): Segment | undefined {
for (let idx = 0; idx < this.segments.length; idx++) {
const info = this.segments[idx];
if (
Expand All @@ -239,10 +239,10 @@ export class MapFileReader {
}
}

return false;
return undefined;
}

getSymbolAt(segment: string, address: number) {
getSymbolAt(segment: string | undefined, address: number): Segment | undefined {
for (let idx = 0; idx < this.namedAddresses.length; idx++) {
const info = this.namedAddresses[idx];
if (!segment && info.addressInt === address) {
Expand All @@ -252,11 +252,11 @@ export class MapFileReader {
}
}

return false;
return undefined;
}

getSymbolBefore(segment: string, address: number) {
let maxNamed: false | Segment = false;
getSymbolBefore(segment: string, address: number): Segment | undefined {
let maxNamed: Segment | undefined;

for (let idx = 0; idx < this.namedAddresses.length; idx++) {
const info = this.namedAddresses[idx];
Expand All @@ -274,15 +274,15 @@ export class MapFileReader {
return maxNamed;
}

getSymbolInfoByName(name: string) {
getSymbolInfoByName(name: string): Segment | undefined {
for (let idx = 0; idx < this.namedAddresses.length; idx++) {
const info = this.namedAddresses[idx];
if (info.displayName === name) {
return info;
}
}

return false;
return undefined;
}

addressToObject(segment: string, address: string): LineNumber {
Expand Down
69 changes: 35 additions & 34 deletions lib/pe32-support.js → lib/pe32-support.ts
Expand Up @@ -22,14 +22,25 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

import {MapFileReader, Segment} from './mapfiles/map-file';

export class PELabelReconstructor {
/**
*
* @param {Array} asmLines
* @param {boolean} dontLabelUnmappedAddresses
* @param {MapFileReader} mapFileReader
*/
constructor(asmLines, dontLabelUnmappedAddresses, mapFileReader, needsReconstruction = true) {
public readonly asmLines: string[];
private readonly addressesToLabel: string[];
private readonly dontLabelUnmappedAddresses: boolean;
private readonly needsReconstruction: boolean;
private readonly mapFileReader: MapFileReader;
private readonly addressRegex: RegExp;
private readonly jumpRegex: RegExp;
private readonly callRegex: RegExp;
private readonly int3Regex: RegExp;

constructor(
asmLines: string[],
dontLabelUnmappedAddresses: boolean,
mapFileReader: MapFileReader,
needsReconstruction = true,
) {
this.asmLines = asmLines;
this.addressesToLabel = [];
this.dontLabelUnmappedAddresses = dontLabelUnmappedAddresses;
Expand All @@ -47,7 +58,7 @@ export class PELabelReconstructor {
* Start reconstructing labels using the mapfile and remove unneccessary assembly
*
*/
run(/*unitName*/) {
run(_unitName?: string) {
this.mapFileReader.run();

//this.deleteEverythingBut(unitName);
Expand Down Expand Up @@ -86,12 +97,10 @@ export class PELabelReconstructor {

/**
* Remove any assembly or data that isn't part of the given unit
*
* @param {string} unitName
*/
deleteEverythingBut(unitName) {
deleteEverythingBut(unitName: string) {
if (this.needsReconstruction) {
let unitAddressSpaces = this.mapFileReader.getReconstructedUnitAddressSpace(unitName);
const unitAddressSpaces = this.mapFileReader.getReconstructedUnitAddressSpace(unitName);

for (let idx = 0; idx < this.mapFileReader.reconstructedSegments.length; idx++) {
const info = this.mapFileReader.reconstructedSegments[idx];
Expand Down Expand Up @@ -146,12 +155,7 @@ export class PELabelReconstructor {
}
}

/**
*
* @param {number} beginAddress
* @param {number} endAddress
*/
deleteLinesBetweenAddresses(beginAddress, endAddress) {
deleteLinesBetweenAddresses(beginAddress: number, endAddress?: number) {
let startIdx = -1;
let linesRemoved = false;
let lineIdx = 0;
Expand Down Expand Up @@ -185,19 +189,16 @@ export class PELabelReconstructor {
/**
* Replaces an address used in a jmp or call instruction by its label.
* Does not replace an address if it has an offset.
*
* @param {int} lineIdx
* @param {regex} regex
*/
addAddressAsLabelAndReplaceLine(lineIdx, regex) {
addAddressAsLabelAndReplaceLine(lineIdx: number, regex: RegExp) {
const line = this.asmLines[lineIdx];
let matches = line.match(regex);
const matches = line.match(regex);
if (matches) {
const address = matches[3];
if (!address.includes('+') && !address.includes('-')) {
let labelName = 'L' + address;
const namedAddr = this.mapFileReader.getSymbolAt(false, parseInt(address, 16));
if (namedAddr) {
const namedAddr = this.mapFileReader.getSymbolAt(undefined, parseInt(address, 16));
if (namedAddr && namedAddr.displayName) {
labelName = namedAddr.displayName;
}

Expand Down Expand Up @@ -225,7 +226,7 @@ export class PELabelReconstructor {
* if an address doesn't have a mapped name, it is called <Laddress>
*/
insertLabels() {
let currentSegment = false;
let currentSegment: Segment | undefined;
let segmentChanged = false;

let lineIdx = 0;
Expand All @@ -237,21 +238,21 @@ export class PELabelReconstructor {
const addressStr = matches[1];
const address = parseInt(addressStr, 16);

const segmentInfo = this.mapFileReader.getSegmentInfoByStartingAddress(false, address);
const segmentInfo = this.mapFileReader.getSegmentInfoByStartingAddress(undefined, address);
if (segmentInfo) {
currentSegment = segmentInfo;
segmentChanged = true;
}

let namedAddr = false;
let labelLine = false;
let namedAddr: Segment | undefined;
let labelLine: string | undefined;

const isReferenced = this.addressesToLabel.indexOf(addressStr);
if (isReferenced === -1) {
// we might have missed the reference to this address,
// but if it's listed as a symbol, we should still label it.
// todo: the call might be in <.itext>, should we include that part of the assembly?
namedAddr = this.mapFileReader.getSymbolAt(false, address);
namedAddr = this.mapFileReader.getSymbolAt(undefined, address);
if (namedAddr) {
labelLine = matches[1] + ' <' + namedAddr.displayName + '>:';

Expand All @@ -261,7 +262,7 @@ export class PELabelReconstructor {
} else {
labelLine = matches[1] + ' <L' + addressStr + '>:';

namedAddr = this.mapFileReader.getSymbolAt(false, address);
namedAddr = this.mapFileReader.getSymbolAt(undefined, address);
if (namedAddr) {
labelLine = matches[1] + ' <' + namedAddr.displayName + '>:';
}
Expand All @@ -272,11 +273,11 @@ export class PELabelReconstructor {
}
}

const lineInfo = this.mapFileReader.getLineInfoByAddress(false, address);
if (lineInfo && currentSegment.unitName) {
const lineInfo = this.mapFileReader.getLineInfoByAddress(undefined, address);
if (lineInfo && currentSegment && currentSegment.unitName) {
this.asmLines.splice(lineIdx, 0, '/app/' + currentSegment.unitName + ':' + lineInfo.lineNumber);
lineIdx++;
} else if (segmentChanged) {
} else if (segmentChanged && currentSegment) {
this.asmLines.splice(lineIdx, 0, '/app/' + currentSegment.unitName + ':0');
lineIdx++;
}
Expand Down

0 comments on commit 0e246d2

Please sign in to comment.