Skip to content

Commit d0c34ac

Browse files
committed
refactor: all the things
1 parent 9945608 commit d0c34ac

File tree

45 files changed

+1321
-1490
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1321
-1490
lines changed

data/ExtensionPoint.manifest

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
CodeRelocationSynthesizer
2-
CoffRelocationTypeMapper
2+
CoffRelocationTableBuilder
33
DataRelocationSynthesizer
4-
ElfRelocationTypeMapper
4+
ElfRelocationTableBuilder

src/main/java/ghidra/app/analyzers/RelocationTableSynthesizerAnalyzer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import java.util.List;
1717
import java.util.stream.Collectors;
1818

19-
import ghidra.app.analyzers.relocations.utils.CodeRelocationSynthesizer;
20-
import ghidra.app.analyzers.relocations.utils.DataRelocationSynthesizer;
19+
import ghidra.app.analyzers.relocations.synthesizers.CodeRelocationSynthesizer;
20+
import ghidra.app.analyzers.relocations.synthesizers.DataRelocationSynthesizer;
2121
import ghidra.app.services.AbstractAnalyzer;
2222
import ghidra.app.services.AnalysisPriority;
2323
import ghidra.app.services.AnalyzerType;

src/main/java/ghidra/app/analyzers/relocations/AbsoluteDataRelocationSynthesizer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*/
1414
package ghidra.app.analyzers.relocations;
1515

16-
import ghidra.app.analyzers.relocations.utils.DataRelocationSynthesizer;
16+
import ghidra.app.analyzers.relocations.synthesizers.DataRelocationSynthesizer;
1717
import ghidra.app.analyzers.relocations.utils.SymbolWithOffset;
1818
import ghidra.app.util.importer.MessageLog;
1919
import ghidra.program.model.address.Address;

src/main/java/ghidra/app/analyzers/relocations/MipsCodeRelocationSynthesizer.java

Lines changed: 141 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,27 @@
1515

1616
import java.util.ArrayList;
1717
import java.util.Arrays;
18+
import java.util.Collection;
1819
import java.util.Collections;
1920
import java.util.HashSet;
2021
import java.util.List;
2122
import java.util.Set;
23+
import java.util.regex.Pattern;
2224
import java.util.stream.Collectors;
2325

2426
import ghidra.app.analyzers.relocations.emitters.BundleRelocationEmitter;
2527
import ghidra.app.analyzers.relocations.emitters.FunctionInstructionSink;
2628
import ghidra.app.analyzers.relocations.emitters.InstructionRelocationEmitter;
2729
import ghidra.app.analyzers.relocations.emitters.RelativeNextInstructionRelocationEmitter;
2830
import ghidra.app.analyzers.relocations.emitters.SymbolRelativeInstructionRelocationEmitter;
29-
import ghidra.app.analyzers.relocations.utils.FunctionInstructionSinkCodeRelocationSynthesizer;
31+
import ghidra.app.analyzers.relocations.patterns.FixedOperandMatcher;
32+
import ghidra.app.analyzers.relocations.patterns.OperandMatch;
33+
import ghidra.app.analyzers.relocations.patterns.OperandMatcher;
34+
import ghidra.app.analyzers.relocations.synthesizers.FunctionInstructionSinkCodeRelocationSynthesizer;
3035
import ghidra.app.analyzers.relocations.utils.SymbolWithOffset;
3136
import ghidra.app.util.importer.MessageLog;
3237
import ghidra.program.model.address.Address;
38+
import ghidra.program.model.address.AddressSet;
3339
import ghidra.program.model.block.BasicBlockModel;
3440
import ghidra.program.model.block.CodeBlock;
3541
import ghidra.program.model.block.CodeBlockIterator;
@@ -48,7 +54,6 @@
4854
import ghidra.program.model.symbol.FlowType;
4955
import ghidra.program.model.symbol.Reference;
5056
import ghidra.program.model.symbol.Symbol;
51-
import ghidra.program.model.symbol.SymbolIterator;
5257
import ghidra.program.model.symbol.SymbolTable;
5358
import ghidra.program.util.ProgramUtilities;
5459
import ghidra.util.DataConverter;
@@ -57,8 +62,30 @@
5762

5863
public class MipsCodeRelocationSynthesizer
5964
extends FunctionInstructionSinkCodeRelocationSynthesizer {
65+
public static final Pattern GP_SYMBOLS_PATTERN = Pattern.compile("^_gp$");
66+
6067
private static class MIPS_26_InstructionRelocationEmitter extends InstructionRelocationEmitter {
61-
private static final List<Byte> OPMASK_JTYPE = Arrays.asList(new Byte[] { -1, -1, -1, 3 });
68+
private static final OperandMatcher MATCHER_LITTLE_ENDIAN =
69+
new JtypeOperandMatcher(new Byte[] { -1, -1, -1, 3 }, 0x3ffffff);
70+
71+
private static class JtypeOperandMatcher extends FixedOperandMatcher {
72+
private final long bitmask;
73+
74+
public JtypeOperandMatcher(Byte[] operandMask, long bitmask) {
75+
super(operandMask);
76+
77+
this.bitmask = bitmask;
78+
}
79+
80+
@Override
81+
public OperandMatch createMatch(Instruction instruction, int operandIndex)
82+
throws MemoryAccessException {
83+
DataConverter dc = ProgramUtilities.getDataConverter(instruction.getProgram());
84+
long value = (dc.getInt(instruction.getBytes()) & bitmask) << 2;
85+
86+
return new OperandMatch(operandIndex, 0, 4, bitmask, value);
87+
}
88+
}
6289

6390
private final Set<Instruction> branchesToShiftByOne;
6491

@@ -71,53 +98,46 @@ public MIPS_26_InstructionRelocationEmitter(Program program,
7198
}
7299

73100
@Override
74-
public List<List<Byte>> getMasks() {
75-
return List.of(OPMASK_JTYPE);
76-
}
77-
78-
@Override
79-
public long computeValue(Instruction instruction, int operandIndex, Reference reference,
80-
int offset, List<Byte> mask) throws MemoryAccessException {
81-
DataConverter dc = ProgramUtilities.getDataConverter(instruction.getProgram());
82-
long value = dc.getValue(instruction.getBytes(), offset, getSizeFromMask(mask));
83-
return (value & 0x3ffffff) << 2;
84-
}
85-
86-
@Override
87-
public boolean matches(Instruction instruction, int operandIndex, Reference reference,
88-
int offset, List<Byte> mask) throws MemoryAccessException {
89-
long origin = instruction.getAddress().getUnsignedOffset() & 0xfffffffff0000000L;
90-
long value = computeValue(instruction, operandIndex, reference, offset, mask);
101+
public boolean evaluate(Instruction instruction, OperandMatch match,
102+
SymbolWithOffset symbol, Reference reference) throws MemoryAccessException {
103+
Address fromAddress = instruction.getAddress();
104+
long origin = fromAddress.getUnsignedOffset() & 0xfffffffff0000000L;
91105
long target = reference.getToAddress().getUnsignedOffset();
106+
long addend = computeAddend(instruction, match, symbol, reference);
92107

93-
return (origin | value) == target;
94-
}
108+
if (addend < -0x4000000 || addend > 0x3ffffff || ((addend & 3) != 0)) {
109+
return false;
110+
}
95111

96-
@Override
97-
public long computeAddend(Instruction instruction, int operandIndex,
98-
SymbolWithOffset symbol, Reference reference, int offset, List<Byte> mask)
99-
throws MemoryAccessException {
100-
return symbol.offset >> 2;
112+
return (origin | match.getValue()) == target;
101113
}
102114

103115
@Override
104-
public boolean emitRelocation(Instruction instruction, int operandIndex,
105-
SymbolWithOffset symbol, Reference reference, int offset, List<Byte> mask,
106-
long addend) throws MemoryAccessException {
116+
protected void emit(Instruction instruction, OperandMatch match, SymbolWithOffset symbol,
117+
Reference reference) {
118+
RelocationTable relocationTable = getRelocationTable();
119+
Address address = instruction.getAddress();
120+
long addend = computeAddend(instruction, match, symbol, reference);
121+
107122
if (branchesToShiftByOne.contains(instruction)) {
108-
logBranchDelaySlotWithHI16(instruction.getAddress(), getMessageLog());
109-
addend -= 1;
123+
addend -= 4;
124+
logBranchDelaySlotWithHI16(address, getMessageLog());
110125
}
111126

112-
if (addend < -0x4000000 || addend > 0x3ffffff) {
113-
return false;
114-
}
127+
relocationTable.addMIPS26(address, symbol.name, addend);
128+
}
115129

116-
RelocationTable relocationTable = getRelocationTable();
117-
Address fromAddress = instruction.getAddress();
130+
private long computeAddend(Instruction instruction, OperandMatch match,
131+
SymbolWithOffset symbol, Reference reference) {
132+
long origin = instruction.getAddress().getUnsignedOffset() & 0xfffffffff0000000L;
133+
long addend = (origin | match.getValue()) - symbol.address;
118134

119-
relocationTable.addMIPS26(fromAddress.add(offset), symbol.name, addend);
120-
return true;
135+
return addend;
136+
}
137+
138+
@Override
139+
public Collection<OperandMatcher> getOperandMatchers() {
140+
return List.of(MATCHER_LITTLE_ENDIAN);
121141
}
122142
}
123143

@@ -350,6 +370,27 @@ private Register getOutputRegister(Instruction instruction) {
350370
*/
351371
private static class MIPS_PC16_InstructionRelocationEmitter
352372
extends RelativeNextInstructionRelocationEmitter {
373+
private static final OperandMatcher MATCHER_LITTLE_ENDIAN =
374+
new ItypeOperandMatcher(new Byte[] { -1, -1, 0, 0 }, 0x0000ffffL);
375+
376+
private static class ItypeOperandMatcher extends FixedOperandMatcher {
377+
private final long bitmask;
378+
379+
public ItypeOperandMatcher(Byte[] operandMask, long bitmask) {
380+
super(operandMask);
381+
382+
this.bitmask = bitmask;
383+
}
384+
385+
@Override
386+
public OperandMatch createMatch(Instruction instruction, int operandIndex)
387+
throws MemoryAccessException {
388+
DataConverter dc = ProgramUtilities.getDataConverter(instruction.getProgram());
389+
long value = ((long) (short) (dc.getInt(instruction.getBytes()) & bitmask)) << 2;
390+
391+
return new OperandMatch(operandIndex, 0, 4, bitmask, value);
392+
}
393+
}
353394

354395
private final Set<Instruction> branchesToShiftByOne;
355396

@@ -362,46 +403,60 @@ public MIPS_PC16_InstructionRelocationEmitter(Program program,
362403
}
363404

364405
@Override
365-
public long computeAddend(Instruction instruction, int operandIndex,
366-
SymbolWithOffset symbol, Reference reference, int offset, List<Byte> mask)
367-
throws MemoryAccessException {
368-
return super.computeAddend(instruction, operandIndex, symbol, reference, offset,
369-
mask) >> 2;
406+
public boolean evaluate(Instruction instruction, OperandMatch match,
407+
SymbolWithOffset symbol, Reference reference) throws MemoryAccessException {
408+
return ((match.getValue() & 3) == 0) &&
409+
super.evaluate(instruction, match, symbol, reference);
370410
}
371411

372412
@Override
373-
public long computeValue(Instruction instruction, int operandIndex, Reference reference,
374-
int offset, List<Byte> mask) throws MemoryAccessException {
375-
return super.computeValue(instruction, operandIndex, reference, offset, mask) << 2;
376-
}
413+
public void emit(Instruction instruction, OperandMatch match, SymbolWithOffset symbol,
414+
Reference reference) {
415+
RelocationTable relocationTable = getRelocationTable();
416+
Address address = instruction.getAddress().add(match.getOffset());
417+
long addend = address.getUnsignedOffset() - symbol.address + match.getValue();
418+
boolean isTransparent = true;
377419

378-
@Override
379-
public boolean emitRelocation(Instruction instruction, int operandIndex,
380-
SymbolWithOffset symbol, Reference reference, int offset, List<Byte> mask,
381-
long addend) throws MemoryAccessException {
382420
if (branchesToShiftByOne.contains(instruction)) {
383-
// FIXME: clean up hack job for branch delay slots with HI16.
384421
logBranchDelaySlotWithHI16(instruction.getAddress(), getMessageLog());
385-
addend -= 1;
422+
addend -= 4;
423+
isTransparent = false;
424+
}
386425

387-
RelocationTable relocationTable = getRelocationTable();
388-
Address fromAddress = instruction.getAddress();
426+
relocationTable.addRelativePC(address, match.getSize(), match.getBitmask(), symbol.name,
427+
addend, isTransparent);
428+
}
389429

390-
relocationTable.addRelativePC(fromAddress.add(offset), getSizeFromMask(mask),
391-
symbol.name, addend, false);
392-
return true;
393-
}
394-
else {
395-
return super.emitRelocation(instruction, operandIndex, symbol, reference, offset,
396-
mask, addend);
397-
}
430+
@Override
431+
public Collection<OperandMatcher> getOperandMatchers() {
432+
return List.of(MATCHER_LITTLE_ENDIAN);
398433
}
399434
}
400435

401436
private static class MIPS_GPREL16_InstructionRelocationEmitter
402437
extends SymbolRelativeInstructionRelocationEmitter {
403-
private static final List<Byte> OPMASK_LOAD_STORE =
404-
Arrays.asList(new Byte[] { -1, -1, -32, 3 });
438+
private static final OperandMatcher MATCHER_LITTLE_ENDIAN =
439+
new LoadStoreOperandMatcher(new Byte[] { -1, -1, -32, 3 }, 0x0000ffffL);
440+
441+
private static class LoadStoreOperandMatcher extends FixedOperandMatcher {
442+
private final long bitmask;
443+
444+
public LoadStoreOperandMatcher(Byte[] bytes, long bitmask) {
445+
super(bytes);
446+
447+
this.bitmask = bitmask;
448+
}
449+
450+
@Override
451+
public OperandMatch createMatch(Instruction instruction, int operandIndex)
452+
throws MemoryAccessException {
453+
int size = getMaskLength();
454+
DataConverter dc = ProgramUtilities.getDataConverter(instruction.getProgram());
455+
long value = (short) (dc.getInt(instruction.getBytes()) & bitmask);
456+
457+
return new OperandMatch(operandIndex, 0, size, bitmask, value);
458+
}
459+
}
405460

406461
private final Register gp;
407462

@@ -414,24 +469,19 @@ public MIPS_GPREL16_InstructionRelocationEmitter(Program program,
414469
}
415470

416471
@Override
417-
public List<List<Byte>> getMasks() {
418-
return List.of(OPMASK_LOAD_STORE);
419-
}
420-
421-
@Override
422-
public int getSizeFromMask(List<Byte> mask) {
423-
return 2;
424-
}
425-
426-
@Override
427-
public boolean matches(Instruction instruction, int operandIndex, Reference reference,
428-
int offset, List<Byte> mask) throws MemoryAccessException {
429-
Object[] objects = instruction.getOpObjects(operandIndex);
472+
public boolean evaluate(Instruction instruction, OperandMatch match,
473+
SymbolWithOffset symbol, Reference reference) throws MemoryAccessException {
474+
Object[] objects = instruction.getOpObjects(match.getOperandIndex());
430475
if (!Arrays.asList(objects).contains(gp)) {
431476
return false;
432477
}
433478

434-
return super.matches(instruction, operandIndex, reference, offset, mask);
479+
return super.evaluate(instruction, match, symbol, reference);
480+
}
481+
482+
@Override
483+
public Collection<OperandMatcher> getOperandMatchers() {
484+
return List.of(MATCHER_LITTLE_ENDIAN);
435485
}
436486
}
437487

@@ -449,11 +499,17 @@ public List<FunctionInstructionSink> getFunctionInstructionSinks(Program program
449499
sinks.add(new MIPS_PC16_InstructionRelocationEmitter(program, relocationTable, function,
450500
branchesToShiftByOne, monitor, log));
451501

452-
SymbolTable symtab = program.getSymbolTable();
453-
SymbolIterator _gp = symtab.getSymbols("_gp");
454-
if (_gp.hasNext()) {
455-
sinks.add(new MIPS_GPREL16_InstructionRelocationEmitter(program, relocationTable,
456-
function, _gp.next(), monitor, log));
502+
SymbolTable symbolTable = program.getSymbolTable();
503+
AddressSet addressSet = new AddressSet();
504+
for (Symbol symbol : symbolTable.getSymbolIterator(true)) {
505+
String name = symbol.getName(true);
506+
Address address = symbol.getAddress();
507+
508+
if (GP_SYMBOLS_PATTERN.matcher(name).matches() && !addressSet.contains(address)) {
509+
sinks.add(new MIPS_GPREL16_InstructionRelocationEmitter(program, relocationTable,
510+
function, symbol, monitor, log));
511+
addressSet.add(address);
512+
}
457513
}
458514

459515
return sinks;

0 commit comments

Comments
 (0)