mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 21:21:56 +00:00
Merge remote-tracking branch 'origin/GP-49_external_disassembly_upgrade--SQUASHED' into Ghidra_9.2
This commit is contained in:
commit
39ef49d1d1
@ -59,10 +59,10 @@ int objdump_sprintf (SFILE *f, const char *format, ...)
|
|||||||
|
|
||||||
|
|
||||||
void configureDisassembleInfo(bfd* abfd,
|
void configureDisassembleInfo(bfd* abfd,
|
||||||
disassemble_info* info,
|
disassemble_info* info,
|
||||||
enum bfd_architecture arch,
|
enum bfd_architecture arch,
|
||||||
unsigned long mach,
|
unsigned long mach,
|
||||||
enum bfd_endian end)
|
enum bfd_endian end)
|
||||||
{
|
{
|
||||||
|
|
||||||
memset(sfile.buffer, 0x00, BUFF_SIZE);
|
memset(sfile.buffer, 0x00, BUFF_SIZE);
|
||||||
@ -79,11 +79,11 @@ void configureDisassembleInfo(bfd* abfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
disassembler_ftype configureBfd(bfd* abfd,
|
disassembler_ftype configureBfd(bfd* abfd,
|
||||||
enum bfd_architecture arch,
|
enum bfd_architecture arch,
|
||||||
unsigned long mach,
|
unsigned long mach,
|
||||||
enum bfd_endian endian,
|
enum bfd_endian endian,
|
||||||
disassemble_info* DI,
|
disassemble_info* DI,
|
||||||
disassembler_ftype* disassemble_fn)
|
disassembler_ftype* disassemble_fn)
|
||||||
{
|
{
|
||||||
struct bfd_target *xvec;
|
struct bfd_target *xvec;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ disassembler_ftype configureBfd(bfd* abfd,
|
|||||||
/*
|
/*
|
||||||
bfd_error_type err = bfd_get_error();
|
bfd_error_type err = bfd_get_error();
|
||||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Use libopcodes to locate a suitable disassembler. */
|
/* Use libopcodes to locate a suitable disassembler. */
|
||||||
*disassemble_fn = NULL;
|
*disassemble_fn = NULL;
|
||||||
@ -118,17 +118,17 @@ disassembler_ftype configureBfd(bfd* abfd,
|
|||||||
if (!*disassemble_fn){
|
if (!*disassemble_fn){
|
||||||
printf("can't disassemble for arch 0x%08X, mach 0x%08lX\n", arch, mach);
|
printf("can't disassemble for arch 0x%08X, mach 0x%08lX\n", arch, mach);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *disassemble_fn;
|
return *disassemble_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int disassemble_buffer( disassembler_ftype disassemble_fn,
|
int disassemble_buffer( disassembler_ftype disassemble_fn,
|
||||||
disassemble_info *info,
|
disassemble_info *info,
|
||||||
int* offset,
|
int* offset,
|
||||||
PDIS_INFO pDisInfo)
|
PDIS_INFO pDisInfo)
|
||||||
{
|
{
|
||||||
int i, j, size = 0;
|
int i, j, size = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
@ -174,15 +174,15 @@ int disassemble_buffer( disassembler_ftype disassemble_fn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
END:
|
END:
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void processBuffer(unsigned char* buff,
|
void processBuffer(unsigned char* buff,
|
||||||
int buff_len,
|
int buff_len,
|
||||||
bfd_vma buff_vma,
|
bfd_vma buff_vma,
|
||||||
disassembler_ftype disassemble_fn,
|
disassembler_ftype disassemble_fn,
|
||||||
struct disassemble_info* DI)
|
struct disassemble_info* DI)
|
||||||
{
|
{
|
||||||
int bytesConsumed = -1;
|
int bytesConsumed = -1;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@ -199,12 +199,12 @@ void processBuffer(unsigned char* buff,
|
|||||||
bytesConsumed = disassemble_buffer( disassemble_fn, DI, &offset, &(disassemblyInfoBuffer[numDisassemblies++]));
|
bytesConsumed = disassemble_buffer( disassemble_fn, DI, &offset, &(disassemblyInfoBuffer[numDisassemblies++]));
|
||||||
}
|
}
|
||||||
for (i = 0; i < numDisassemblies; i++) {
|
for (i = 0; i < numDisassemblies; i++) {
|
||||||
printf("%s\nInfo: %d,%d,%d,%d,%d\n", disassemblyInfoBuffer[i].disassemblyString,
|
printf("%s\nInfo: %d,%d,%d,%d,%d\n", disassemblyInfoBuffer[i].disassemblyString,
|
||||||
disassemblyInfoBuffer[i].count,
|
disassemblyInfoBuffer[i].count,
|
||||||
disassemblyInfoBuffer[i].insn_info_valid,
|
disassemblyInfoBuffer[i].insn_info_valid,
|
||||||
disassemblyInfoBuffer[i].branch_delay_insns,
|
disassemblyInfoBuffer[i].branch_delay_insns,
|
||||||
disassemblyInfoBuffer[i].data_size,
|
disassemblyInfoBuffer[i].data_size,
|
||||||
disassemblyInfoBuffer[i].insn_type);
|
disassemblyInfoBuffer[i].insn_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ int main(int argc, char* argv[]){
|
|||||||
// if arch starts with 0x, then parse a number
|
// if arch starts with 0x, then parse a number
|
||||||
// else lookup the string in the table to get the arch, ignore the mach
|
// else lookup the string in the table to get the arch, ignore the mach
|
||||||
if (arch_str[0] == '0' && arch_str[1] == 'x') {
|
if (arch_str[0] == '0' && arch_str[1] == 'x') {
|
||||||
sscanf(arch_str, "%10X", &arch);
|
sscanf(arch_str, "%10X", &arch);
|
||||||
} else {
|
} else {
|
||||||
const char** archList = bfd_arch_list();
|
const char** archList = bfd_arch_list();
|
||||||
const bfd_arch_info_type* ait;
|
const bfd_arch_info_type* ait;
|
||||||
@ -271,8 +271,8 @@ int main(int argc, char* argv[]){
|
|||||||
archList++;
|
archList++;
|
||||||
}
|
}
|
||||||
if (ait == NULL) {
|
if (ait == NULL) {
|
||||||
printf("Couldn't find arch %s\n", arch_str);
|
printf("Couldn't find arch %s\n", arch_str);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,11 +294,6 @@ int main(int argc, char* argv[]){
|
|||||||
stdin_mode = 1; // use STDIN
|
stdin_mode = 1; // use STDIN
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char byteBuffer[BYTE_BUFFER_SIZE];
|
|
||||||
char byteStringBuffer[(BYTE_BUFFER_SIZE*2)];
|
|
||||||
|
|
||||||
char addressStringBuffer[128];
|
|
||||||
|
|
||||||
if (endian == BFD_ENDIAN_BIG){
|
if (endian == BFD_ENDIAN_BIG){
|
||||||
strcat(elf_file_location, BIG_ELF_FILE);
|
strcat(elf_file_location, BIG_ELF_FILE);
|
||||||
}
|
}
|
||||||
@ -306,47 +301,59 @@ int main(int argc, char* argv[]){
|
|||||||
strcat(elf_file_location, LITTLE_ELF_FILE);
|
strcat(elf_file_location, LITTLE_ELF_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bfd_init();
|
||||||
|
|
||||||
while (stdin_mode) {
|
while (stdin_mode) {
|
||||||
|
|
||||||
|
//bfd_init();
|
||||||
// convert user input AsciiHex to Binary data for processing
|
// convert user input AsciiHex to Binary data for processing
|
||||||
char tmp[3];
|
char tmp[3];
|
||||||
unsigned int byteValue;
|
unsigned int byteValue;
|
||||||
tmp[0] = tmp[1] = tmp[2] = 0x00;
|
tmp[0] = tmp[1] = tmp[2] = 0x00;
|
||||||
|
char disassemblerOptions[128] = {0};
|
||||||
|
unsigned char byteBuffer[BYTE_BUFFER_SIZE] = {0};
|
||||||
|
char byteStringBuffer[(BYTE_BUFFER_SIZE*2)] = {0};
|
||||||
|
char addressStringBuffer[128] = {0};
|
||||||
|
char bytesAndOptionsBuffer[BYTE_BUFFER_SIZE*2 + sizeof(disassemblerOptions)] = {0};
|
||||||
|
|
||||||
if (stdin_mode == 1) { // use stdin
|
if (stdin_mode == 1) { // use stdin
|
||||||
// read in the address
|
// read in the address
|
||||||
if (fgets(addressStringBuffer, sizeof(addressStringBuffer), stdin)) {
|
if (fgets(addressStringBuffer, sizeof(addressStringBuffer), stdin)) {
|
||||||
|
|
||||||
//fprintf(stderr, "read: %s\n", addressStringBuffer);
|
|
||||||
//char *p = strchr(addressStringBuffer, '\n');
|
|
||||||
//if (p) {
|
|
||||||
// *p = '\0';
|
|
||||||
//}
|
|
||||||
|
|
||||||
sscanf(addressStringBuffer, "%18lX", &offset);
|
sscanf(addressStringBuffer, "%18lX", &offset);
|
||||||
}
|
}
|
||||||
//getchar();
|
//Read in the rest of the input. There are two possible styles:
|
||||||
// read in the ASCII hex string from stdin
|
//"old": input is just the bytes to disassemble
|
||||||
if (fgets(byteStringBuffer, sizeof(byteStringBuffer), stdin)) {
|
//"new": input = bytes"*"<disassmbler_options>
|
||||||
|
//for compatibility reasons, handle both styles
|
||||||
//fprintf(stderr, "read: %s\n", byteStringBuffer);
|
if (fgets(bytesAndOptionsBuffer, sizeof(bytesAndOptionsBuffer), stdin)) {
|
||||||
// remove trailing newline
|
char *p = strchr(bytesAndOptionsBuffer, '*');
|
||||||
char *p = strchr(byteStringBuffer, '\n');
|
|
||||||
if (p) {
|
if (p) {
|
||||||
*p = '\0';
|
strncpy(byteStringBuffer,bytesAndOptionsBuffer,(int) (p - bytesAndOptionsBuffer));
|
||||||
|
strncpy(disassemblerOptions,p+1,sizeof(disassemblerOptions));
|
||||||
|
p = strchr(disassemblerOptions,'\n');
|
||||||
|
if (p){
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//no "*" in the string, so no disassembly options
|
||||||
|
//replace newline with null terminator
|
||||||
|
strncpy(byteStringBuffer, bytesAndOptionsBuffer, sizeof(byteStringBuffer));
|
||||||
|
p = strchr(byteStringBuffer,'\n');
|
||||||
|
if (p){
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//if (strcmp(byteStringBuffer, "EOF") == 0) {
|
|
||||||
//return 0; // terminate on EOF string
|
|
||||||
//}
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "exiting, no ASCII hex found\n");
|
|
||||||
return 0; // finished! #TODO
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
} else {
|
fprintf(stderr, "exiting, no ASCII hex found\n");
|
||||||
|
return 0; // finished! #TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
if(strlen(byteString) > BYTE_BUFFER_SIZE*2) {
|
if(strlen(byteString) > BYTE_BUFFER_SIZE*2) {
|
||||||
fprintf(stderr, "Max ascii string size is %d you provided: %lu chars. Exiting.\n", BYTE_BUFFER_SIZE*2,
|
fprintf(stderr, "Max ascii string size is %d you provided: %lu chars. Exiting.\n", BYTE_BUFFER_SIZE*2,
|
||||||
strlen(byteString));
|
strlen(byteString));
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
strncpy(byteStringBuffer, byteString, BYTE_BUFFER_SIZE*2);
|
strncpy(byteStringBuffer, byteString, BYTE_BUFFER_SIZE*2);
|
||||||
@ -378,9 +385,9 @@ int main(int argc, char* argv[]){
|
|||||||
for(j=0; j < BYTE_BUFFER_SIZE; j++){
|
for(j=0; j < BYTE_BUFFER_SIZE; j++){
|
||||||
printf("0x%02X ", byteBuffer[j]);
|
printf("0x%02X ", byteBuffer[j]);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bfd_init( );
|
//bfd_init( );
|
||||||
target = argv[1];
|
target = argv[1];
|
||||||
bfd_set_default_target(target);
|
bfd_set_default_target(target);
|
||||||
|
|
||||||
@ -420,14 +427,17 @@ int main(int argc, char* argv[]){
|
|||||||
/*
|
/*
|
||||||
bfd_error_type err = bfd_get_error();
|
bfd_error_type err = bfd_get_error();
|
||||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*if (disassemblerOptions[0] != '\0'){
|
||||||
|
DI.disassembler_options = disassemblerOptions;
|
||||||
|
}*/
|
||||||
configureBfd(bfdfile, arch, mach, endian, &DI, &disassemble_fn);
|
configureBfd(bfdfile, arch, mach, endian, &DI, &disassemble_fn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
err = bfd_get_error();
|
err = bfd_get_error();
|
||||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (disassemble_fn == NULL){
|
if (disassemble_fn == NULL){
|
||||||
fprintf(stderr, "Error: disassemble_fn is NULL. Nothing I can do.\n");
|
fprintf(stderr, "Error: disassemble_fn is NULL. Nothing I can do.\n");
|
||||||
@ -437,8 +447,12 @@ int main(int argc, char* argv[]){
|
|||||||
/*
|
/*
|
||||||
printf("the disassemble_fn func pointer is: 0x%08X.\n", disassemble_fn);
|
printf("the disassemble_fn func pointer is: 0x%08X.\n", disassemble_fn);
|
||||||
printf("We can try to disassemble for this arch/mach. calling disassemble_init_for_target().\n");
|
printf("We can try to disassemble for this arch/mach. calling disassemble_init_for_target().\n");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
disassemble_init_for_target(&DI);
|
disassemble_init_for_target(&DI);
|
||||||
|
if (disassemblerOptions[0] != '\0'){
|
||||||
|
DI.disassembler_options = disassemblerOptions;
|
||||||
|
}
|
||||||
|
|
||||||
// go diassemble the buffer and build up the result in a accumulator string buffer.
|
// go diassemble the buffer and build up the result in a accumulator string buffer.
|
||||||
processBuffer(byteBuffer, size >> 1, offset, disassemble_fn, &DI); //
|
processBuffer(byteBuffer, size >> 1, offset, disassemble_fn, &DI); //
|
||||||
|
@ -23,6 +23,8 @@ public interface ExternalDisassembler extends ExtensionPoint {
|
|||||||
|
|
||||||
public String getDisassembly(CodeUnit cu) throws Exception;
|
public String getDisassembly(CodeUnit cu) throws Exception;
|
||||||
|
|
||||||
|
public String getDisassemblyDisplayPrefix(CodeUnit cu) throws Exception;
|
||||||
|
|
||||||
public String getDisassemblyOfBytes(Language language, boolean isBigEndian, long address,
|
public String getDisassemblyOfBytes(Language language, boolean isBigEndian, long address,
|
||||||
byte[] byteString) throws Exception;
|
byte[] byteString) throws Exception;
|
||||||
|
|
||||||
|
@ -150,7 +150,10 @@ public class ExternalDisassemblyFieldFactory extends FieldFactory {
|
|||||||
if (disassembly == null) {
|
if (disassembly == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
String prefix = disassembler.getDisassemblyDisplayPrefix(cu);
|
||||||
|
if (prefix != null) {
|
||||||
|
disassembly = prefix + " " + disassembly;
|
||||||
|
}
|
||||||
return disassembly;
|
return disassembly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,19 +18,23 @@ package ghidra.app.util.disassemble;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.jdom.*;
|
||||||
|
import org.jdom.input.SAXBuilder;
|
||||||
|
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.app.util.bin.ByteProvider;
|
import ghidra.app.util.bin.ByteProvider;
|
||||||
import ghidra.app.util.bin.MemoryByteProvider;
|
import ghidra.app.util.bin.MemoryByteProvider;
|
||||||
import ghidra.framework.*;
|
import ghidra.framework.*;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||||
import ghidra.program.model.lang.Language;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.lang.LanguageID;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.listing.CodeUnit;
|
|
||||||
import ghidra.program.model.listing.Program;
|
|
||||||
import ghidra.program.model.mem.MemBuffer;
|
import ghidra.program.model.mem.MemBuffer;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
|
import ghidra.util.xml.XmlUtilities;
|
||||||
|
import util.CollectionUtils;
|
||||||
|
|
||||||
public class GNUExternalDisassembler implements ExternalDisassembler {
|
public class GNUExternalDisassembler implements ExternalDisassembler {
|
||||||
|
|
||||||
@ -39,6 +43,7 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
// magic values for gdis that direct it to read bytes from stdin
|
// magic values for gdis that direct it to read bytes from stdin
|
||||||
private static final String READ_FROM_STDIN_PARAMETER = "stdin";
|
private static final String READ_FROM_STDIN_PARAMETER = "stdin";
|
||||||
private static final String SEPARATOR_CHARACTER = "\n";
|
private static final String SEPARATOR_CHARACTER = "\n";
|
||||||
|
private static final String OPTIONS_SEPARATOR = "*";
|
||||||
private static final String ADDRESS_OUT_OF_BOUNDS = "is out of bounds.";
|
private static final String ADDRESS_OUT_OF_BOUNDS = "is out of bounds.";
|
||||||
private static final String ENDING_STRING = "EOF";
|
private static final String ENDING_STRING = "EOF";
|
||||||
private static final int NUM_BYTES = 32;
|
private static final int NUM_BYTES = 32;
|
||||||
@ -48,6 +53,8 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
private static final String GDIS_EXE =
|
private static final String GDIS_EXE =
|
||||||
Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.WINDOWS ? "gdis.exe"
|
Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.WINDOWS ? "gdis.exe"
|
||||||
: "gdis";
|
: "gdis";
|
||||||
|
private static final String EMPTY_DISASSEMBLER_OPTIONS = "";
|
||||||
|
private static final String GDIS_OPTIONS_FILENAME_PROPERTY = "gdis.disassembler.options.file";
|
||||||
|
|
||||||
private static HashMap<String, File> languageGdisMap;
|
private static HashMap<String, File> languageGdisMap;
|
||||||
private static File defaultGdisExecFile;
|
private static File defaultGdisExecFile;
|
||||||
@ -82,6 +89,21 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
return gdisConfig != null && gdisConfig.architecture != UNSUPPORTED;
|
return gdisConfig != null && gdisConfig.architecture != UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDisassemblyDisplayPrefix(CodeUnit cu) throws Exception {
|
||||||
|
GdisConfig gdisConfig = checkLanguage(cu.getProgram().getLanguage());
|
||||||
|
if (gdisConfig == null || gdisConfig.architecture == UNSUPPORTED) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Register contextRegister = gdisConfig.getContextRegister();
|
||||||
|
if (contextRegister == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long value = getContextRegisterValue(cu, contextRegister);
|
||||||
|
String option = gdisConfig.getDisplayPrefixMap().get(value);
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
private static void reportMultipleMappings(Language language) {
|
private static void reportMultipleMappings(Language language) {
|
||||||
List<String> externalNames = language.getLanguageDescription().getExternalNames("gnu");
|
List<String> externalNames = language.getLanguageDescription().getExternalNames("gnu");
|
||||||
if (externalNames != null && externalNames.size() > 1) {
|
if (externalNames != null && externalNames.size() > 1) {
|
||||||
@ -89,8 +111,9 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
boolean prependSeparator = false;
|
boolean prependSeparator = false;
|
||||||
for (String name : externalNames) {
|
for (String name : externalNames) {
|
||||||
if (prependSeparator)
|
if (prependSeparator) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
|
}
|
||||||
sb.append(name);
|
sb.append(name);
|
||||||
prependSeparator = true;
|
prependSeparator = true;
|
||||||
}
|
}
|
||||||
@ -110,11 +133,17 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
String machineId;
|
String machineId;
|
||||||
File gdisExecFile;
|
File gdisExecFile;
|
||||||
boolean usingDefault;
|
boolean usingDefault;
|
||||||
|
Register contextRegister;
|
||||||
|
Map<Long, String> valueToOptionString;
|
||||||
|
Map<Long, String> valueToDisplayPrefix;
|
||||||
|
Language lang;
|
||||||
|
String globalDisassemblerOptions;
|
||||||
|
|
||||||
GdisConfig(Language language, boolean isBigEndian) {
|
GdisConfig(Language language, boolean isBigEndian) {
|
||||||
|
|
||||||
this.languageId = language.getLanguageID().toString();
|
this.languageId = language.getLanguageID().toString();
|
||||||
this.isBigEndian = isBigEndian;
|
this.isBigEndian = isBigEndian;
|
||||||
|
this.lang = language;
|
||||||
|
|
||||||
List<String> architectures = language.getLanguageDescription().getExternalNames("gnu");
|
List<String> architectures = language.getLanguageDescription().getExternalNames("gnu");
|
||||||
//get first non-null
|
//get first non-null
|
||||||
@ -143,12 +172,123 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
gdisExecFile = defaultGdisExecFile;
|
gdisExecFile = defaultGdisExecFile;
|
||||||
usingDefault = true;
|
usingDefault = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> gDisOptionsFile =
|
||||||
|
language.getLanguageDescription().getExternalNames(GDIS_OPTIONS_FILENAME_PROPERTY);
|
||||||
|
if (!CollectionUtils.isBlank(gDisOptionsFile)) {
|
||||||
|
try {
|
||||||
|
parseGdisOptionsFile(gDisOptionsFile.get(0));
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
Msg.error(this, "Error reading gdis options file " + e.getMessage());
|
||||||
|
contextRegister = null;
|
||||||
|
valueToOptionString = null;
|
||||||
|
valueToDisplayPrefix = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GdisConfig(Language lang) {
|
GdisConfig(Language lang) {
|
||||||
this(lang, lang.isBigEndian());
|
this(lang, lang.isBigEndian());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parseGdisOptionsFile(String fileName) throws IOException {
|
||||||
|
LanguageDescription desc = lang.getLanguageDescription();
|
||||||
|
if (!(desc instanceof SleighLanguageDescription)) {
|
||||||
|
throw new IOException("Not a Sleigh Language: " + lang.getLanguageID());
|
||||||
|
}
|
||||||
|
|
||||||
|
SleighLanguageDescription sld = (SleighLanguageDescription) desc;
|
||||||
|
ResourceFile defsFile = sld.getDefsFile();
|
||||||
|
ResourceFile parentFile = defsFile.getParentFile();
|
||||||
|
ResourceFile gdisOpts = new ResourceFile(parentFile, fileName);
|
||||||
|
SAXBuilder sax = XmlUtilities.createSecureSAXBuilder(false, false);
|
||||||
|
try (InputStream fis = gdisOpts.getInputStream()) {
|
||||||
|
Document doc = sax.build(fis);
|
||||||
|
Element rootElem = doc.getRootElement();
|
||||||
|
Element globalElement = rootElem.getChild("global");
|
||||||
|
if (globalElement != null) {
|
||||||
|
globalDisassemblerOptions = globalElement.getAttributeValue("optstring");
|
||||||
|
}
|
||||||
|
Element contextRegisterElement = rootElem.getChild("context_register");
|
||||||
|
if (contextRegisterElement == null) {
|
||||||
|
//no context_register element found in the xml file
|
||||||
|
//this is not necessarily an error - might only be a global optstring
|
||||||
|
//global optstring has already been parsed, so we're done
|
||||||
|
if (globalElement != null) {
|
||||||
|
Msg.info(this,
|
||||||
|
"no context register element in " + gdisOpts.getAbsolutePath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//no context register element or global element, error
|
||||||
|
throw new JDOMException(
|
||||||
|
"No context_register element or global element in gdis options file");
|
||||||
|
}
|
||||||
|
if (contextRegisterElement.getContentSize() == 0) {
|
||||||
|
throw new JDOMException("No context register name provided.");
|
||||||
|
}
|
||||||
|
String contextRegisterName = contextRegisterElement.getContent(0).getValue();
|
||||||
|
contextRegister = lang.getRegister(contextRegisterName);
|
||||||
|
if (contextRegister == null) {
|
||||||
|
//the context register named in the xml file does not exist in the sleigh language
|
||||||
|
//this is an error
|
||||||
|
throw new JDOMException("Unknown context register " + contextRegisterName +
|
||||||
|
" for language " + lang.getLanguageID().getIdAsString());
|
||||||
|
}
|
||||||
|
valueToOptionString = new HashMap<>();
|
||||||
|
valueToDisplayPrefix = new HashMap<>();
|
||||||
|
Element options = rootElem.getChild("options");
|
||||||
|
List<Element> optList = options.getChildren("option");
|
||||||
|
for (Element opt : optList) {
|
||||||
|
Long value = Long.decode(opt.getAttributeValue("value"));
|
||||||
|
String optString = opt.getAttributeValue("optstring");
|
||||||
|
valueToOptionString.put(value, optString);
|
||||||
|
String displayPrefix = opt.getAttributeValue("display_prefix");
|
||||||
|
valueToDisplayPrefix.put(value, displayPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (JDOMException e) {
|
||||||
|
Msg.error(this, "Error reading " + fileName + ": " + e.getMessage());
|
||||||
|
contextRegister = null;
|
||||||
|
valueToOptionString = null;
|
||||||
|
valueToDisplayPrefix = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the global disassembler options
|
||||||
|
* @return global option string, or {@code null} if the
|
||||||
|
* global is unspecified.
|
||||||
|
*/
|
||||||
|
public String getGlobalDisassemblerOptions() {
|
||||||
|
return globalDisassemblerOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the context register determine by the gdis options file
|
||||||
|
* @return the context register
|
||||||
|
*/
|
||||||
|
public Register getContextRegister() {
|
||||||
|
return contextRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map from context register values to gdis disassembler options
|
||||||
|
* @return map values->options
|
||||||
|
*/
|
||||||
|
public Map<Long, String> getOptionsMap() {
|
||||||
|
return valueToOptionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map from context register values to disassembly display prefixes
|
||||||
|
* @return map values->prefixes
|
||||||
|
*/
|
||||||
|
public Map<Long, String> getDisplayPrefixMap() {
|
||||||
|
return valueToDisplayPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof GdisConfig)) {
|
if (!(obj instanceof GdisConfig)) {
|
||||||
@ -260,7 +400,7 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
|
|
||||||
String bytes = getBytes(byteProvider, blockSize);
|
String bytes = getBytes(byteProvider, blockSize);
|
||||||
|
|
||||||
return runDisassembler(gdisConfig, address, bytes);
|
return runDisassembler(gdisConfig, address, bytes, EMPTY_DISASSEMBLER_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GnuDisassembledInstruction> getBlockDisassembly(Program program, Address addr,
|
public List<GnuDisassembledInstruction> getBlockDisassembly(Program program, Address addr,
|
||||||
@ -272,8 +412,8 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
int blockSize = pow2(blockSizeFactor);
|
int blockSize = pow2(blockSizeFactor);
|
||||||
|
|
||||||
Address blockAddr = addr.getNewAddress(addr.getOffset() & -blockSize); // block
|
Address blockAddr = addr.getNewAddress(addr.getOffset() & -blockSize); // block
|
||||||
// aligned
|
// aligned
|
||||||
// address
|
// address
|
||||||
|
|
||||||
return getBlockDisassembly(program.getLanguage(), blockAddr, blockSizeFactor,
|
return getBlockDisassembly(program.getLanguage(), blockAddr, blockSizeFactor,
|
||||||
new MemoryByteProvider(program.getMemory(), blockAddr));
|
new MemoryByteProvider(program.getMemory(), blockAddr));
|
||||||
@ -301,7 +441,37 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GnuDisassembledInstruction> disassembly = runDisassembler(gdisConfig, address, bytes);
|
String disOptions = EMPTY_DISASSEMBLER_OPTIONS;
|
||||||
|
String globalOptions = gdisConfig.getGlobalDisassemblerOptions();
|
||||||
|
boolean hasGlobal = false;
|
||||||
|
if (globalOptions != null) {
|
||||||
|
hasGlobal = true;
|
||||||
|
//set the disOptions to the global options here in case there are global
|
||||||
|
//options but no options for context register values
|
||||||
|
disOptions = globalOptions;
|
||||||
|
}
|
||||||
|
Register contextRegister = gdisConfig.getContextRegister();
|
||||||
|
if (contextRegister != null) {
|
||||||
|
long value = getContextRegisterValue(cu, contextRegister);
|
||||||
|
String contextRegisterValueOption = gdisConfig.getOptionsMap().get(value);
|
||||||
|
if (contextRegisterValueOption == null) {
|
||||||
|
Msg.warn(this, "No option for value " + value + " of context register " +
|
||||||
|
contextRegister.getName());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//need to put a comma between the global options and the options
|
||||||
|
//for this context register value
|
||||||
|
if (hasGlobal) {
|
||||||
|
disOptions = globalOptions + "," + contextRegisterValueOption;
|
||||||
|
}
|
||||||
|
//no global options, just send the options for this context register
|
||||||
|
else {
|
||||||
|
disOptions = contextRegisterValueOption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<GnuDisassembledInstruction> disassembly =
|
||||||
|
runDisassembler(gdisConfig, address, bytes, disOptions);
|
||||||
|
|
||||||
if (disassembly == null || disassembly.size() == 0 || disassembly.get(0) == null) {
|
if (disassembly == null || disassembly.size() == 0 || disassembly.get(0) == null) {
|
||||||
return "(bad)";
|
return "(bad)";
|
||||||
@ -324,7 +494,7 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
String address = "0x" + Long.toHexString(addressOffset);
|
String address = "0x" + Long.toHexString(addressOffset);
|
||||||
|
|
||||||
List<GnuDisassembledInstruction> disassembly =
|
List<GnuDisassembledInstruction> disassembly =
|
||||||
runDisassembler(gdisConfig, address, bytesString);
|
runDisassembler(gdisConfig, address, bytesString, EMPTY_DISASSEMBLER_OPTIONS);
|
||||||
|
|
||||||
if (disassembly == null || disassembly.isEmpty() || disassembly.get(0) == null) {
|
if (disassembly == null || disassembly.isEmpty() || disassembly.get(0) == null) {
|
||||||
return "(bad)";
|
return "(bad)";
|
||||||
@ -332,14 +502,26 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
return disassembly.get(0).toString();
|
return disassembly.get(0).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long getContextRegisterValue(CodeUnit cu, Register contextRegister) {
|
||||||
|
ProgramContext context = cu.getProgram().getProgramContext();
|
||||||
|
RegisterValue value = context.getRegisterValue(contextRegister, cu.getAddress());
|
||||||
|
if (value != null) {
|
||||||
|
return value.getUnsignedValue().longValue();
|
||||||
|
}
|
||||||
|
//we tried, return 0 to match SLEIGH default
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private String converBytesToString(byte[] bytes) {
|
private String converBytesToString(byte[] bytes) {
|
||||||
String byteString = null;
|
String byteString = null;
|
||||||
for (byte thisByte : bytes) {
|
for (byte thisByte : bytes) {
|
||||||
String thisByteString = Integer.toHexString(thisByte);
|
String thisByteString = Integer.toHexString(thisByte);
|
||||||
if (thisByteString.length() == 1)
|
if (thisByteString.length() == 1) {
|
||||||
thisByteString = "0" + thisByteString; // pad single digits
|
thisByteString = "0" + thisByteString; // pad single digits
|
||||||
if (thisByteString.length() > 2)
|
}
|
||||||
|
if (thisByteString.length() > 2) {
|
||||||
thisByteString = thisByteString.substring(thisByteString.length() - 2);
|
thisByteString = thisByteString.substring(thisByteString.length() - 2);
|
||||||
|
}
|
||||||
// append this byte's hex string to the larger word length string
|
// append this byte's hex string to the larger word length string
|
||||||
byteString = byteString + thisByteString;
|
byteString = byteString + thisByteString;
|
||||||
}
|
}
|
||||||
@ -402,7 +584,7 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<GnuDisassembledInstruction> runDisassembler(GdisConfig gdisConfig,
|
private List<GnuDisassembledInstruction> runDisassembler(GdisConfig gdisConfig,
|
||||||
String addrString, String bytes) throws IOException {
|
String addrString, String bytes, String disassemblerOptions) throws IOException {
|
||||||
|
|
||||||
// if this is the first time running the disassembler process, or a
|
// if this is the first time running the disassembler process, or a
|
||||||
// parameter has changed (notably, not the address--we pass that in
|
// parameter has changed (notably, not the address--we pass that in
|
||||||
@ -414,8 +596,9 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
|
|
||||||
if (disassemblerProcess == null || !sameConfig) {
|
if (disassemblerProcess == null || !sameConfig) {
|
||||||
|
|
||||||
if (!setupDisassembler(gdisConfig))
|
if (!setupDisassembler(gdisConfig)) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
outputWriter = new OutputStreamWriter(disassemblerProcess.getOutputStream());
|
outputWriter = new OutputStreamWriter(disassemblerProcess.getOutputStream());
|
||||||
|
|
||||||
@ -432,7 +615,14 @@ public class GNUExternalDisassembler implements ExternalDisassembler {
|
|||||||
return null; // if process previously died return nothing - quickly
|
return null; // if process previously died return nothing - quickly
|
||||||
}
|
}
|
||||||
|
|
||||||
String disassemblyRequest = addrString + SEPARATOR_CHARACTER + bytes + SEPARATOR_CHARACTER;
|
String disassemblyRequest = addrString + SEPARATOR_CHARACTER + bytes;
|
||||||
|
if (StringUtils.isEmpty(disassemblerOptions)) {
|
||||||
|
disassemblyRequest += '\n';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
disassemblyRequest += OPTIONS_SEPARATOR + disassemblerOptions + SEPARATOR_CHARACTER;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
outputWriter.write(disassemblyRequest);
|
outputWriter.write(disassemblyRequest);
|
||||||
outputWriter.flush();
|
outputWriter.flush();
|
||||||
|
@ -3,6 +3,7 @@ Module.manifest||GHIDRA||||END|
|
|||||||
build.gradle||GHIDRA||||END|
|
build.gradle||GHIDRA||||END|
|
||||||
data/languages/ARM.cspec||GHIDRA||||END|
|
data/languages/ARM.cspec||GHIDRA||||END|
|
||||||
data/languages/ARM.dwarf||GHIDRA||||END|
|
data/languages/ARM.dwarf||GHIDRA||||END|
|
||||||
|
data/languages/ARM.gdis||GHIDRA||||END|
|
||||||
data/languages/ARM.ldefs||GHIDRA||||END|
|
data/languages/ARM.ldefs||GHIDRA||||END|
|
||||||
data/languages/ARM.opinion||GHIDRA||||END|
|
data/languages/ARM.opinion||GHIDRA||||END|
|
||||||
data/languages/ARM.sinc||GHIDRA||||END|
|
data/languages/ARM.sinc||GHIDRA||||END|
|
||||||
|
41
Ghidra/Processors/ARM/data/languages/ARM.gdis
Normal file
41
Ghidra/Processors/ARM/data/languages/ARM.gdis
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!--
|
||||||
|
This file determines the disassembler options sent to the GNU external disassembler.
|
||||||
|
You can see which options are available for all architectures in the objdump man page.
|
||||||
|
Given a version of objdump compiled for a specific architecture, you can see what options
|
||||||
|
are available with "objdump -i -m"
|
||||||
|
|
||||||
|
The options for ARM are:
|
||||||
|
"reg-names-std" (the default)
|
||||||
|
"reg-names-apcs"
|
||||||
|
"reg-names-raw"
|
||||||
|
"reg-names-apcs"
|
||||||
|
"reg-names-special-apcs"
|
||||||
|
"force-thumb" (force thumb disassembly)
|
||||||
|
"no-force-thumb" (force arm disassembly)
|
||||||
|
(see the objdump manpage for the precise details about the different register
|
||||||
|
naming options)
|
||||||
|
|
||||||
|
"optstring" is the string of options, and "display_prefix" is an optional prefix prepended to the
|
||||||
|
external disassembly field. In this file, "A: " is prepended to ARM disassembly, and
|
||||||
|
"T: " is prepended to Thumb disassembly.
|
||||||
|
|
||||||
|
To send multiple options, concatenate them into a CSV list. For example, "no-force-thumb,reg-names-raw"
|
||||||
|
is a valid optstring. You can also have a "global" element whose "optstring" attribute is
|
||||||
|
always sent to the GNU disassembler.
|
||||||
|
|
||||||
|
If there is not a context register defined, the global optstring is sent by itself (see x86-16.gdis for
|
||||||
|
an example). If there is a context register defined, the global optstring is prepended to the
|
||||||
|
optstring determined by a context register value.
|
||||||
|
|
||||||
|
This file must be listed in the .ldefs file for the processor, e.g.
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<gdis>
|
||||||
|
<context_register>TMode</context_register>
|
||||||
|
<options>
|
||||||
|
<option value="0x0" optstring="no-force-thumb" display_prefix = "A: "/>
|
||||||
|
<option value="0x1" optstring="force-thumb" display_prefix = "T: "/>
|
||||||
|
</options>
|
||||||
|
</gdis>
|
||||||
|
|
@ -14,6 +14,7 @@
|
|||||||
<compiler name="default" spec="ARM.cspec" id="default"/>
|
<compiler name="default" spec="ARM.cspec" id="default"/>
|
||||||
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
|
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
|
||||||
<external_name tool="gnu" name="iwmmxt"/>
|
<external_name tool="gnu" name="iwmmxt"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="arm"/>
|
<external_name tool="IDA-PRO" name="arm"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -31,6 +32,7 @@
|
|||||||
<compiler name="default" spec="ARM.cspec" id="default"/>
|
<compiler name="default" spec="ARM.cspec" id="default"/>
|
||||||
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
|
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
|
||||||
<external_name tool="gnu" name="iwmmxt"/>
|
<external_name tool="gnu" name="iwmmxt"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="arm"/>
|
<external_name tool="IDA-PRO" name="arm"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -63,6 +65,7 @@
|
|||||||
<description>Generic ARM/Thumb v8 big endian</description>
|
<description>Generic ARM/Thumb v8 big endian</description>
|
||||||
<compiler name="default" spec="ARM.cspec" id="default"/>
|
<compiler name="default" spec="ARM.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="iwmmxt"/>
|
<external_name tool="gnu" name="iwmmxt"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="armb"/>
|
<external_name tool="IDA-PRO" name="armb"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -96,6 +99,7 @@
|
|||||||
<compiler name="default" spec="ARM.cspec" id="default"/>
|
<compiler name="default" spec="ARM.cspec" id="default"/>
|
||||||
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
|
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
|
||||||
<external_name tool="gnu" name="iwmmxt"/>
|
<external_name tool="gnu" name="iwmmxt"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="arm"/>
|
<external_name tool="IDA-PRO" name="arm"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -128,6 +132,7 @@
|
|||||||
<description>Generic ARM/Thumb v7 big endian</description>
|
<description>Generic ARM/Thumb v7 big endian</description>
|
||||||
<compiler name="default" spec="ARM.cspec" id="default"/>
|
<compiler name="default" spec="ARM.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="iwmmxt"/>
|
<external_name tool="gnu" name="iwmmxt"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="armb"/>
|
<external_name tool="IDA-PRO" name="armb"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -174,6 +179,7 @@
|
|||||||
<description>Generic ARM/Thumb v6 little endian</description>
|
<description>Generic ARM/Thumb v6 little endian</description>
|
||||||
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="xscale"/>
|
<external_name tool="gnu" name="xscale"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="arm"/>
|
<external_name tool="IDA-PRO" name="arm"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
||||||
<!-- change DWARF register mapping to ARMneon.dwarf if VFPv2 is enabled -->
|
<!-- change DWARF register mapping to ARMneon.dwarf if VFPv2 is enabled -->
|
||||||
@ -192,6 +198,7 @@
|
|||||||
<description>Generic ARM/Thumb v6 big endian</description>
|
<description>Generic ARM/Thumb v6 big endian</description>
|
||||||
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="xscale"/>
|
<external_name tool="gnu" name="xscale"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="armb"/>
|
<external_name tool="IDA-PRO" name="armb"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
||||||
<!-- change DWARF register mapping to ARMneon.dwarf if VFPv2 is enabled -->
|
<!-- change DWARF register mapping to ARMneon.dwarf if VFPv2 is enabled -->
|
||||||
@ -210,6 +217,7 @@
|
|||||||
<description>Generic ARM/Thumb v5 little endian (T-variant)</description>
|
<description>Generic ARM/Thumb v5 little endian (T-variant)</description>
|
||||||
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="armv5t"/>
|
<external_name tool="gnu" name="armv5t"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="arm"/>
|
<external_name tool="IDA-PRO" name="arm"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -226,6 +234,7 @@
|
|||||||
<description>Generic ARM/Thumb v5 big endian (T-variant)</description>
|
<description>Generic ARM/Thumb v5 big endian (T-variant)</description>
|
||||||
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="armv5t"/>
|
<external_name tool="gnu" name="armv5t"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="armb"/>
|
<external_name tool="IDA-PRO" name="armb"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -274,6 +283,7 @@
|
|||||||
<description>Generic ARM/Thumb v4 little endian (T-variant)</description>
|
<description>Generic ARM/Thumb v4 little endian (T-variant)</description>
|
||||||
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="armv4t"/>
|
<external_name tool="gnu" name="armv4t"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="arm"/>
|
<external_name tool="IDA-PRO" name="arm"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
@ -290,6 +300,7 @@
|
|||||||
<description>Generic ARM/Thumb v4 big endian (T-variant)</description>
|
<description>Generic ARM/Thumb v4 big endian (T-variant)</description>
|
||||||
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
|
||||||
<external_name tool="gnu" name="armv4t"/>
|
<external_name tool="gnu" name="armv4t"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
|
||||||
<external_name tool="IDA-PRO" name="armb"/>
|
<external_name tool="IDA-PRO" name="armb"/>
|
||||||
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
|
||||||
</language>
|
</language>
|
||||||
|
@ -30,6 +30,7 @@ data/languages/sha.sinc||GHIDRA||||END|
|
|||||||
data/languages/smx.sinc||GHIDRA||||END|
|
data/languages/smx.sinc||GHIDRA||||END|
|
||||||
data/languages/x86-16-real.pspec||GHIDRA||||END|
|
data/languages/x86-16-real.pspec||GHIDRA||||END|
|
||||||
data/languages/x86-16.cspec||GHIDRA||||END|
|
data/languages/x86-16.cspec||GHIDRA||||END|
|
||||||
|
data/languages/x86-16.gdis||GHIDRA||||END|
|
||||||
data/languages/x86-16.pspec||GHIDRA||||END|
|
data/languages/x86-16.pspec||GHIDRA||||END|
|
||||||
data/languages/x86-64-gcc.cspec||GHIDRA||||END|
|
data/languages/x86-64-gcc.cspec||GHIDRA||||END|
|
||||||
data/languages/x86-64-win.cspec||GHIDRA||||END|
|
data/languages/x86-64-win.cspec||GHIDRA||||END|
|
||||||
|
3
Ghidra/Processors/x86/data/languages/x86-16.gdis
Normal file
3
Ghidra/Processors/x86/data/languages/x86-16.gdis
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<gdis>
|
||||||
|
<global optstring="intel"/>
|
||||||
|
</gdis>
|
@ -59,6 +59,8 @@
|
|||||||
<external_name tool="IDA-PRO" name="80486r"/>
|
<external_name tool="IDA-PRO" name="80486r"/>
|
||||||
<external_name tool="IDA-PRO" name="80586r"/>
|
<external_name tool="IDA-PRO" name="80586r"/>
|
||||||
<external_name tool="IDA-PRO" name="metapc"/>
|
<external_name tool="IDA-PRO" name="metapc"/>
|
||||||
|
<external_name tool="gnu" name="i8086"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="x86-16.gdis"/>
|
||||||
</language>
|
</language>
|
||||||
<language processor="x86"
|
<language processor="x86"
|
||||||
endian="little"
|
endian="little"
|
||||||
@ -72,6 +74,8 @@
|
|||||||
<description>Intel/AMD 16-bit x86 Protected Mode</description>
|
<description>Intel/AMD 16-bit x86 Protected Mode</description>
|
||||||
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
<compiler name="default" spec="x86-16.cspec" id="default"/>
|
||||||
<external_name tool="IDA-PRO" name="8086p"/>
|
<external_name tool="IDA-PRO" name="8086p"/>
|
||||||
|
<external_name tool="gnu" name="i8086"/>
|
||||||
|
<external_name tool="gdis.disassembler.options.file" name="x86-16.gdis"/>
|
||||||
</language>
|
</language>
|
||||||
<language processor="x86"
|
<language processor="x86"
|
||||||
endian="little"
|
endian="little"
|
||||||
|
Loading…
Reference in New Issue
Block a user