package ghidra.emotionengine; import java.util.Collections; import java.util.HashSet; import java.util.Set; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.plugin.processors.sleigh.template.OpTpl; import ghidra.pcodeCPort.slgh_compile.PcodeParser; import ghidra.program.model.lang.InjectPayload; import ghidra.program.model.lang.InjectPayloadSleigh; import ghidra.program.model.lang.PcodeInjectLibrary; import ghidra.program.model.listing.Program; import ghidra.util.Msg; import org.jdom.JDOMException; public class PcodeInjectLibraryVu extends PcodeInjectLibrary { private PcodeParser parser; private SleighLanguage language; // vector protected static final String VABS = "VABS"; protected static final String VADD = "VADD"; protected static final String VADDBC = "VADDBC"; protected static final String VMADD = "VMADD"; protected static final String VMADDBC = "VMADDBC"; protected static final String VSUB = "VSUB"; protected static final String VSUBBC = "VSUBBC"; protected static final String VMSUB = "VMSUB"; protected static final String VMSUBBC = "VMSUBBC"; protected static final String VMUL = "VMUL"; protected static final String VMULBC = "VMULBC"; protected static final String VFTOI = "VFTOI"; protected static final String VITOF = "VITOF"; protected static final String VULQ = "VULQ"; protected static final String VUSQ = "VUSQ"; protected static final String VMAX = "VMAX"; protected static final String VMAXBC = "VMAXBC"; protected static final String VMIN = "VMINI"; protected static final String VMINBC = "VMINIBC"; protected static final String VMFIR = "VMFIR"; protected static final String VMOVE = "VMOVE"; protected static final String VMOVEBC = "VMOVEBC"; protected static final String VMR32 = "VMR32"; protected static final String VCLEAR = "VCLEAR"; protected static final Set<String> VECTOR_INSTRUCTIONS = getVectorInstructions(); public PcodeInjectLibraryVu(SleighLanguage l) { super(l); language = l; String translateSpec = l.buildTranslatorTag(l.getAddressFactory(), getUniqueBase(), l.getSymbolTable()); parser = null; try { parser = new PcodeParser(translateSpec); } catch (JDOMException e1) { Msg.error(this, e1); } } private static Set<String> getVectorInstructions() { Set<String> instructions = new HashSet<>(); instructions.add(VABS); instructions.add(VADD); instructions.add(VADDBC); instructions.add(VMADD); instructions.add(VMADDBC); instructions.add(VFTOI); instructions.add(VITOF); instructions.add(VSUB); instructions.add(VSUBBC); instructions.add(VMSUB); instructions.add(VMSUBBC); instructions.add(VMUL); instructions.add(VMULBC); instructions.add(VULQ); instructions.add(VUSQ); instructions.add(VMAX); instructions.add(VMAXBC); instructions.add(VMIN); instructions.add(VMINBC); instructions.add(VMFIR); instructions.add(VMOVE); instructions.add(VMOVEBC); instructions.add(VMR32); instructions.add(VCLEAR); return Collections.unmodifiableSet(instructions); } @Override protected InjectPayloadSleigh allocateInject(String sourceName, String name, int tp) { if (tp != InjectPayload.CALLOTHERFIXUP_TYPE) { return super.allocateInject(sourceName, name, tp); } if (VECTOR_INSTRUCTIONS.contains(name)) { return new InjectPayloadVu(sourceName, language); } return super.allocateInject(sourceName, name, InjectPayload.CALLOTHERFIXUP_TYPE); } @Override /** * This method is called by DecompileCallback.getPcodeInject. */ public InjectPayload getPayload(int type, String name, Program program, String context) { if (!VECTOR_INSTRUCTIONS.contains(name)) { return super.getPayload(type, name, program, context); } InjectPayloadVu payload = (InjectPayloadVu) super.getPayload(InjectPayload.CALLOTHERFIXUP_TYPE, name, program, context); synchronized (parser) { try { OpTpl[] opTemplates = payload.getPcode(parser, program, context); adjustUniqueBase(opTemplates); } finally { //clear the added symbols so that the parser can be used again without //duplicate symbol name conflicts. parser.clearSymbols(); } } return payload; } }