mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GP-4152 msp430 improvements
This commit is contained in:
parent
1281fb979b
commit
1e82a772c5
14 changed files with 692 additions and 66 deletions
|
@ -460,16 +460,30 @@ PCodeTest({
|
|||
PCodeTest({
|
||||
'name': 'msp430x',
|
||||
'build_all': 1,
|
||||
'toolchain': 'TI/msp430-elf',
|
||||
'ccflags': '-g -mmcu=msp430x -mlarge -mhwmult=none -fno-builtin -Wl,-T,msp430x.ld -L %(toolchain_dir)s/lib/gcc/msp430-elf/%(gcc_version)s/large/ -lgcc -lmul_none',
|
||||
'toolchain': 'TI/msp430-gcc-9.3.1.11_linux64',
|
||||
'ccflags': '-g -mcpu=msp430x -mlarge -mhwmult=none -fno-builtin -Wl,-T,msp430x.ld -L %(toolchain_dir)s/lib/gcc/msp430-elf/%(gcc_version)s/large/ -lgcc -lmul_none',
|
||||
'language_id': 'TI_MSP430X:LE:32:default',
|
||||
'processor': 'TI',
|
||||
'architecture_test': 'MSP430X',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_float': 1,
|
||||
'has_double': 1,
|
||||
'has_longlong': 0,
|
||||
'small_build': 1,
|
||||
'skip_files': ['PointerManipulation.test', 'misc.out'],
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'msp430',
|
||||
'build_all': 1,
|
||||
'toolchain': 'TI/msp430-gcc-9.3.1.11_linux64',
|
||||
'ccflags': '-g -mcpu=msp430 -fno-builtin -mhwmult=none -lgcc -lmul_none',
|
||||
'language_id': 'TI_MSP430:LE:16:default',
|
||||
'processor': 'TI',
|
||||
'architecture_test': 'MSP430',
|
||||
'has_float': 1,
|
||||
'has_double': 1,
|
||||
'has_longlong': 0,
|
||||
'small_build': 1,
|
||||
'skip_files': ['PointerManipulation.test', 'misc.test'],
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
|
|
|
@ -836,7 +836,7 @@ public interface Memory extends AddressSetView {
|
|||
throws MemoryAccessException;
|
||||
|
||||
/**
|
||||
* Write short at addr in big endian order.
|
||||
* Write short at addr in default endian order.
|
||||
*
|
||||
* @param addr the Address of the short.
|
||||
* @param value the data to write.
|
||||
|
@ -857,7 +857,7 @@ public interface Memory extends AddressSetView {
|
|||
public void setShort(Address addr, short value, boolean bigEndian) throws MemoryAccessException;
|
||||
|
||||
/**
|
||||
* Write int at addr.
|
||||
* Write int at addr in the default endian order.
|
||||
*
|
||||
* @param addr the Address of the int.
|
||||
* @param value the data to write.
|
||||
|
@ -879,7 +879,7 @@ public interface Memory extends AddressSetView {
|
|||
public void setInt(Address addr, int value, boolean bigEndian) throws MemoryAccessException;
|
||||
|
||||
/**
|
||||
* Write long at addr.
|
||||
* Write long at addr in the default endian order.
|
||||
*
|
||||
* @param addr the Address of the long.
|
||||
* @param value the data to write.
|
||||
|
|
|
@ -14,8 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/jacocoProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
|
||||
apply plugin: 'eclipse'
|
||||
|
||||
eclipse.project.name = 'Processors TI_MSP430'
|
||||
|
||||
dependencies {
|
||||
api project(':Base')
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
# The original way of using sub-tables to breakout the addressing modes does not
|
||||
# work for these instructions
|
||||
|
||||
:^instruction is opext_11_5=0x3 & ctx_haveext=0 & dest_0_4 & src_ext & al & zc & ad; instruction [ ctx_haveext=1; ctx_ctregdest=dest_0_4; ctx_regsrc=src_ext; ctx_al=al; ctx_num=ad; ] {$(CARRY)=$(CARRY) * (zc:1 == 0); build instruction;}
|
||||
#constructor recognizing the presence of an extension word
|
||||
:^instruction is opext_11_5=0x3 & ctx_haveext=0 & dest_0_4 & src_ext & al & zc & ad; instruction [ ctx_haveext=1; ctx_ctregdest=dest_0_4; ctx_regsrc=src_ext; ctx_al=al; ctx_num=ad; ctx_zc=zc;] { build instruction;}
|
||||
|
||||
|
||||
#:^instruction is ctx_haveext=1 & instruction & as=1 & src_8_4=3 [ctx_haveext=2;] {build instruction;}
|
||||
|
@ -291,6 +292,17 @@ XDEST_A_AD: "&"^val is dest=0x2 & ad=0x1 & bow=0x1 & as=0x1 & ((src16_8_
|
|||
XDEST_A_AD: "&"^val is dest=0x2 & ad=0x1 & bow=0x1 & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16 [val=(ctx_ctregdest << 16) | indexExt2Word16_0_16; ]
|
||||
{export *:$(REG_SIZE) val; } # Absolute
|
||||
|
||||
#Use repeat_carry with a build directive at the beginning of a RPT loop
|
||||
|
||||
#use existing value of carry bit
|
||||
repeat_carry: is ctx_zc = 0 {}
|
||||
|
||||
#in this case the repeated instruction uses 0 as the value of the carry bit
|
||||
#after repeated instruction executes, value of carry bit is defined by the result of
|
||||
#last operation, so building this constructor at the beginning of RPT loop can accurately
|
||||
#model the semantics
|
||||
repeat_carry: is ctx_zc = 1 {$(CARRY) = 0;}
|
||||
|
||||
macro setaddflags(ans, in1, in2)
|
||||
{
|
||||
tmp1:$(REG_SIZE) = zext(in1[0,20]);
|
||||
|
@ -310,7 +322,6 @@ macro setsubflags(ans, in1, in2)
|
|||
$(OVERFLOW) = ((in1 s< 0) & (in2 s>= 0) & (ans s< 0)) | ((in1 s>= 0) & (in2 s< 0) & (ans s>= 0));
|
||||
$(SIGN) = (ans s< 0);
|
||||
$(ZERO) = (ans == 0);
|
||||
|
||||
}
|
||||
|
||||
#################
|
||||
|
@ -1115,7 +1126,7 @@ POPWR0: is ctx_mreg=0x0 & POPWR1 [ctx_count=ctx_count-1; ctx_mreg=ctx_mreg+
|
|||
call [PC];
|
||||
}
|
||||
|
||||
:CALLA imms_0_16^"(PC)" is ctx_haveext=0 & op16_8_8=0x13 & op16_4_4=0x9 & imms_0_16 {
|
||||
:CALLA imms_0_16^"(PC)" is ctx_haveext=0 & op16_8_8=0x13 & op16_4_4=0x9 ; imms_0_16 {
|
||||
SP = SP - 0x4;
|
||||
*:4 SP = inst_next;
|
||||
tmp:$(REG_SIZE) = inst_start + sext(imms_0_16:2);
|
||||
|
@ -1275,8 +1286,9 @@ macro wzero(full, word)
|
|||
#
|
||||
#############################
|
||||
# Repeat enabled
|
||||
:ADCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0x6 & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=1 & postIncrementStore & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:ADCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0x6 & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=1 & postIncrementStore & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
tmp_carry:1 = carry(DST8_0_4,$(CARRY)); #C Flag
|
||||
$(OVERFLOW) = scarry(DST8_0_4,$(CARRY)); #V Flag
|
||||
|
@ -1293,8 +1305,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:ADCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0x6 & src16_8_4=0x3 & as=0x0 & bow=0 & ctx_al=1 & postIncrementStore & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:ADCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0x6 & src16_8_4=0x3 & as=0x0 & bow=0 & ctx_al=1 & postIncrementStore & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
tmp_carry:1 = carry(DST16_0_4,zext($(CARRY))); #C Flag
|
||||
$(OVERFLOW) = scarry(DST16_0_4,zext($(CARRY))); #V Flag
|
||||
|
@ -1311,8 +1324,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:ADCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0x6 & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=0 & postIncrementStore & dest_0_4 {
|
||||
:ADCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0x6 & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=0 & postIncrementStore & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
tmpd:$(REG_SIZE) = dest_0_4;
|
||||
tmpc:$(REG_SIZE) = zext($(CARRY));
|
||||
tmp:$(REG_SIZE) = tmpc + dest_0_4;
|
||||
|
@ -1372,8 +1386,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:ADDCX.B XRSRC_B_AS, DST8_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=1 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:ADDCX.B XRSRC_B_AS, DST8_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=1 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
tmp_carry:1 = (carry(XRSRC_B_AS, $(CARRY)) || carry(DST8_0_4,XRSRC_B_AS + $(CARRY))); #C Flag
|
||||
$(OVERFLOW) = (scarry(XRSRC_B_AS, $(CARRY)) || scarry(DST8_0_4,XRSRC_B_AS + $(CARRY))); #V Flag
|
||||
|
@ -1390,8 +1405,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:ADDCX.W XRSRC_W_AS, DST16_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=0 & ctx_al=1 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:ADDCX.W XRSRC_W_AS, DST16_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=0 & ctx_al=1 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
tmp_carry:1 = (carry(XRSRC_W_AS,zext($(CARRY))) || carry(DST16_0_4,XRSRC_W_AS + zext($(CARRY)))); #C Flag
|
||||
$(OVERFLOW) = (scarry(XRSRC_W_AS,zext($(CARRY))) || scarry(DST16_0_4,XRSRC_W_AS + zext($(CARRY)))); #V Flag
|
||||
|
@ -1408,8 +1424,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:ADDCX.A XRSRC_A_AS, dest_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=0 & postIncrementStore & XRSRC_A_AS & dest_0_4 {
|
||||
:ADDCX.A XRSRC_A_AS, dest_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=0 & postIncrementStore & XRSRC_A_AS & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
tmpd:$(REG_SIZE) = dest_0_4;
|
||||
tmps:$(REG_SIZE) = XRSRC_A_AS + zext($(CARRY));
|
||||
tmp:$(REG_SIZE) = tmps + dest_0_4;
|
||||
|
@ -1661,12 +1678,12 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:DADCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0xA & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=1 & postIncrementStore & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:DADCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0xA & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=1 & postIncrementStore & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
$(CARRY) = 0; # This should be overflow
|
||||
# Operation...
|
||||
DST8_0_4 = bcd_add(DST8_0_4);
|
||||
build repeat_carry;
|
||||
local temp:4 = zext(DST8_0_4);
|
||||
DST8_0_4 = bcd_add(temp, $(CARRY));
|
||||
$(CARRY) = temp >= 0x99;
|
||||
bzero(reg_Direct16_0_4,DST8_0_4);
|
||||
# Result Flags...
|
||||
$(SIGN) = (DST8_0_4 s< 0x0); # S Flag
|
||||
|
@ -1677,12 +1694,12 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:DADCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0xA & src16_8_4=0x3 & as=0x0 & bow=0 & ctx_al=1 & postIncrementStore & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:DADCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0xA & src16_8_4=0x3 & as=0x0 & bow=0 & ctx_al=1 & postIncrementStore & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
$(CARRY) = 0; # Don't currently have BCD overflow op
|
||||
# Operation...
|
||||
DST16_0_4 = bcd_add(DST16_0_4);
|
||||
build repeat_carry;
|
||||
local temp:4 = zext(DST16_0_4);
|
||||
DST16_0_4 = bcd_add(temp, $(CARRY));
|
||||
$(CARRY) = temp >= 0x9999;
|
||||
wzero(reg_Direct16_0_4,DST16_0_4);
|
||||
# Result Flags...
|
||||
$(SIGN) = (DST16_0_4 s< 0x0); # S Flag
|
||||
|
@ -1693,12 +1710,12 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:DADCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0xA & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=0 & postIncrementStore & dest_0_4 {
|
||||
:DADCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0xA & src16_8_4=0x3 & as=0x0 & bow=1 & ctx_al=0 & postIncrementStore & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
$(CARRY) = 0; # Don't currently have BCD overflow op
|
||||
# Operation...
|
||||
dest_0_4 = bcd_add(dest_0_4);
|
||||
build repeat_carry;
|
||||
local temp:4 = zext(dest_0_4);
|
||||
dest_0_4 = bcd_add(temp, $(CARRY));
|
||||
$(CARRY) = temp >= 0x99999;
|
||||
dest_0_4 = sext(dest_0_4[0,20]);
|
||||
# Result Flags...
|
||||
$(SIGN) = (dest_0_4 s< 0x0); # S Flag
|
||||
|
@ -1709,48 +1726,54 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:DADDX.B XRSRC_B_AS, DST8_0_4 is ctx_haveext=4 & op16_12_4=0xA & bow=1 & ctx_al=1 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:DADDX.B XRSRC_B_AS, DST8_0_4 is ctx_haveext=4 & op16_12_4=0xA & bow=1 & ctx_al=1 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
$(CARRY) = 0; # This should be overflow
|
||||
# Operation...
|
||||
DST8_0_4 = bcd_add(XRSRC_B_AS,DST8_0_4);
|
||||
build repeat_carry;
|
||||
local temp_src:4 = zext(XRSRC_B_AS);
|
||||
local temp_dest:4 = zext(DST8_0_4);
|
||||
local temp_carry:4 = zext($(CARRY));
|
||||
DST8_0_4 = bcd_add(temp_src,temp_dest, temp_carry);
|
||||
bzero(reg_Direct16_0_4,DST8_0_4);
|
||||
# Result Flags...
|
||||
$(SIGN) = (DST8_0_4 s< 0x0); # S Flag
|
||||
$(ZERO) = (DST8_0_4 == 0x0); # Z Flag
|
||||
$(CARRY) = (temp_src + temp_dest + temp_carry) > 0x99;
|
||||
build postIncrementStore;
|
||||
if (CNT == 0) goto inst_next;
|
||||
CNT = CNT - 1;
|
||||
goto <top>;
|
||||
}
|
||||
|
||||
:DADDX.W XRSRC_W_AS, DST16_0_4 is ctx_haveext=4 & op16_12_4=0xA & bow=0 & ctx_al=1 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:DADDX.W XRSRC_W_AS, DST16_0_4 is ctx_haveext=4 & op16_12_4=0xA & bow=0 & ctx_al=1 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
$(CARRY) = 0; # Don't currently have BCD overflow op
|
||||
# Operation...
|
||||
DST16_0_4 = bcd_add(XRSRC_W_AS ,DST16_0_4);
|
||||
build repeat_carry;
|
||||
local temp_src:4 = zext(XRSRC_W_AS);
|
||||
local temp_dest:4 = zext(DST16_0_4);
|
||||
local temp_carry:4 = zext($(CARRY));
|
||||
DST16_0_4 = bcd_add(temp_src, temp_dest, temp_carry);
|
||||
wzero(reg_Direct16_0_4,DST16_0_4);
|
||||
# Result Flags...
|
||||
$(SIGN) = (DST16_0_4 s< 0x0); # S Flag
|
||||
$(ZERO) = (DST16_0_4 == 0x0); # Z Flag
|
||||
$(CARRY) = (temp_src + temp_dest + temp_carry) > 0x9999;
|
||||
build postIncrementStore;
|
||||
if (CNT == 0) goto inst_next;
|
||||
CNT = CNT - 1;
|
||||
goto <top>;
|
||||
}
|
||||
|
||||
:DADDX.A XRSRC_A_AS, dest_0_4 is ctx_haveext=4 & op16_12_4=0xA & bow=1 & ctx_al=0 & postIncrementStore & XRSRC_A_AS & dest_0_4 {
|
||||
:DADDX.A XRSRC_A_AS, dest_0_4 is ctx_haveext=4 & op16_12_4=0xA & bow=1 & ctx_al=0 & postIncrementStore & XRSRC_A_AS & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
$(CARRY) = 0; # Don't currently have BCD overflow op
|
||||
# Operation...
|
||||
dest_0_4 = bcd_add(XRSRC_A_AS ,dest_0_4);
|
||||
build repeat_carry;
|
||||
local temp_src:4 = zext(XRSRC_A_AS);
|
||||
local temp_dest:4 = zext(dest_0_4);
|
||||
local temp_carry:4 = zext($(CARRY));
|
||||
dest_0_4 = bcd_add(temp_src, temp_dest, temp_carry);
|
||||
dest_0_4 = sext(dest_0_4[0,20]);
|
||||
# Result Flags...
|
||||
$(SIGN) = (dest_0_4 s< 0x0); # S Flag
|
||||
$(ZERO) = (dest_0_4 == 0x0); # Z Flag
|
||||
$(CARRY) = (temp_src + temp_dest + temp_carry) > 0x99999;
|
||||
build postIncrementStore;
|
||||
if (CNT == 0) goto inst_next;
|
||||
CNT = CNT - 1;
|
||||
|
@ -2103,8 +2126,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:RLCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=1 & src_Direct16_8_4=dest_Direct16_0_4 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:RLCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=1 & src_Direct16_8_4=dest_Direct16_0_4 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
tmp_carry:1 = (carry(DST8_0_4, $(CARRY)) || carry(DST8_0_4,DST8_0_4 + $(CARRY))); #C Flag
|
||||
$(OVERFLOW) = (scarry(DST8_0_4, $(CARRY)) || scarry(DST8_0_4,DST8_0_4 + $(CARRY))); #V Flag
|
||||
|
@ -2121,8 +2145,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:RLCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=0 & ctx_al=1 & src_Direct16_8_4=dest_Direct16_0_4 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:RLCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=0 & ctx_al=1 & src_Direct16_8_4=dest_Direct16_0_4 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
tmp_carry:1 = (carry(DST16_0_4,zext($(CARRY))) || carry(DST16_0_4,DST16_0_4 + zext($(CARRY)))); #C Flag
|
||||
$(OVERFLOW) = (scarry(DST16_0_4,zext($(CARRY))) || scarry(DST16_0_4,DST16_0_4 + zext($(CARRY)))); #V Flag
|
||||
|
@ -2139,8 +2164,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:RLCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=0 & src_Direct16_8_4=dest_Direct16_0_4 & postIncrementStore & XRSRC_A_AS & dest_0_4 {
|
||||
:RLCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0x6 & bow=1 & ctx_al=0 & src_Direct16_8_4=dest_Direct16_0_4 & postIncrementStore & XRSRC_A_AS & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
tmpd:$(REG_SIZE) = dest_0_4;
|
||||
tmps:$(REG_SIZE) = dest_0_4 + zext($(CARRY));
|
||||
tmp:$(REG_SIZE) = tmps + dest_0_4;
|
||||
|
@ -2153,8 +2179,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:SBCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=1 & src16_8_4=0x3 & as=0x0 & postIncrementStore & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:SBCX.B DST8_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=1 & src16_8_4=0x3 & as=0x0 & postIncrementStore & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
brw:1 = 1 - $(CARRY);
|
||||
$(CARRY) = (brw <= DST8_0_4); # Carry flag is NOT set if there is a borrow
|
||||
|
@ -2171,8 +2198,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:SBCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=0 & ctx_al=1 & src16_8_4=0x3 & as=0x0 & postIncrementStore & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:SBCX.W DST16_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=0 & ctx_al=1 & src16_8_4=0x3 & as=0x0 & postIncrementStore & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
brw:2 = 1 - zext( $(CARRY) );
|
||||
$(CARRY) = (brw <= DST16_0_4); # Carry flag is NOT set if there is a borrow
|
||||
|
@ -2189,8 +2217,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:SBCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=0 & src16_8_4=0x3 & as=0x0 & postIncrementStore & dest_0_4 {
|
||||
:SBCX.A dest_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=0 & src16_8_4=0x3 & as=0x0 & postIncrementStore & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
brw:$(REG_SIZE) = 1 - zext( $(CARRY) );
|
||||
tmpd:$(REG_SIZE) = dest_0_4;
|
||||
tmp:$(REG_SIZE) = dest_0_4 - brw;
|
||||
|
@ -2203,8 +2232,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:SUBCX.B XRSRC_B_AS, DST8_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=1 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 {
|
||||
:SUBCX.B XRSRC_B_AS, DST8_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=1 & postIncrementStore & XRSRC_B_AS & DST8_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
brw:1 = 1 - $(CARRY);
|
||||
$(CARRY) = ((brw + XRSRC_B_AS) <= DST8_0_4); # Carry flag is NOT set if there is a borrow
|
||||
|
@ -2221,8 +2251,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:SUBCX.W XRSRC_W_AS, DST16_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=0 & ctx_al=1 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 {
|
||||
:SUBCX.W XRSRC_W_AS, DST16_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=0 & ctx_al=1 & postIncrementStore & XRSRC_W_AS & DST16_0_4 & reg_Direct16_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
brw:2 = 1 - zext( $(CARRY) );
|
||||
$(CARRY) = ((brw + XRSRC_W_AS) <= DST16_0_4); # Carry flag is NOT set if there is a borrow
|
||||
|
@ -2239,8 +2270,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:SUBCX.A XRSRC_A_AS, dest_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=0 & postIncrementStore & XRSRC_A_AS & dest_0_4 {
|
||||
:SUBCX.A XRSRC_A_AS, dest_0_4 is ctx_haveext=4 & op16_12_4=0x7 & bow=1 & ctx_al=0 & postIncrementStore & XRSRC_A_AS & dest_0_4 & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
brw:$(REG_SIZE) = 1 - zext( $(CARRY) );
|
||||
tmpd:$(REG_SIZE) = dest_0_4;
|
||||
tmps:$(REG_SIZE) = XRSRC_A_AS + brw;
|
||||
|
@ -3222,9 +3254,11 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:RRCX.B XRREG_B_AS_DEST is ctx_haveext=4 & ctx_al=1 & op16_12_4=0x1 & op16_8_4=0x0 & bow=0x1 & postRegIncrement & XRREG_B_AS_DEST {
|
||||
:RRCX.B XRREG_B_AS_DEST is ctx_haveext=4 & ctx_al=1 & ctx_zc & op16_12_4=0x1 & op16_8_4=0x0 & bow=0x1 & postRegIncrement & XRREG_B_AS_DEST & repeat_carry {
|
||||
<top>
|
||||
# Operation Flags...
|
||||
build repeat_carry;
|
||||
$(CARRY) = $(CARRY) * ctx_zc;
|
||||
$(OVERFLOW) = ((XRREG_B_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
|
||||
# Operation...
|
||||
tmp:1 = $(CARRY);
|
||||
|
@ -3239,8 +3273,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:RRCX.W XRREG_W_AS_DEST is ctx_haveext=4 & ctx_al=1 & op16_12_4=0x1 & op16_8_4=0x0 & bow=0x0 & postRegIncrement & XRREG_W_AS_DEST {
|
||||
:RRCX.W XRREG_W_AS_DEST is ctx_haveext=4 & ctx_al=1 & op16_12_4=0x1 & op16_8_4=0x0 & bow=0x0 & postRegIncrement & XRREG_W_AS_DEST & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
$(OVERFLOW) = ((XRREG_W_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
|
||||
# Operation...
|
||||
|
@ -3256,8 +3291,9 @@ macro wzero(full, word)
|
|||
goto <top>;
|
||||
}
|
||||
|
||||
:RRCX.A XRREG_A_AS_DEST is ctx_haveext=4 & ctx_al=0 & op16_12_4=0x1 & op16_8_4=0x0 & bow=0x1 & postRegIncrement & XRREG_A_AS_DEST {
|
||||
:RRCX.A XRREG_A_AS_DEST is ctx_haveext=4 & ctx_al=0 & op16_12_4=0x1 & op16_8_4=0x0 & bow=0x1 & postRegIncrement & XRREG_A_AS_DEST & repeat_carry {
|
||||
<top>
|
||||
build repeat_carry;
|
||||
# Operation Flags...
|
||||
$(OVERFLOW) = ((XRREG_A_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
|
||||
# Operation...
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
endian="little"
|
||||
size="16"
|
||||
variant="default"
|
||||
version="1.4"
|
||||
version="1.5"
|
||||
slafile="TI_MSP430.sla"
|
||||
processorspec="TI_MSP430.pspec"
|
||||
manualindexfile="../manuals/MSP430.idx"
|
||||
|
@ -20,7 +20,7 @@
|
|||
endian="little"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="1.4"
|
||||
version="1.5"
|
||||
slafile="TI_MSP430X.sla"
|
||||
processorspec="TI_MSP430.pspec"
|
||||
manualindexfile="../manuals/MSP430.idx"
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
</constraint>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
|
||||
<constraint primary="105" processor="TI_MSP430" endian="little" size="16"/>
|
||||
</constraint>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
|
||||
<constraint primary="105" processor="TI_MSP430X" endian="little" size="32" />
|
||||
<constraint primary="105" secondary="0x2d" processor="TI_MSP430X" endian="little" size="32"/>
|
||||
</constraint>
|
||||
</opinions>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.elf.relocation;
|
||||
|
||||
/**
|
||||
* class for elf_msp430x_reloc_type (from binutils source)
|
||||
*/
|
||||
public class TI_MSP430X_ElfRelocationConstants {
|
||||
// Note: some of the msp430x relocation types have "msp430" (without the x)
|
||||
// in their names
|
||||
public static final int R_MSP430_NONE = 0; // No calculation
|
||||
public static final int R_MSP430_ABS32 = 1;// S + A
|
||||
public static final int R_MSP430_ABS16 = 2; // S + A
|
||||
public static final int R_MSP430_ABS8 = 3; // S + A
|
||||
public static final int R_MSP430_PCR16 = 4; // S + A - PC
|
||||
public static final int R_MSP430X_PCR20_EXT_SRC = 5; // S + A - PC
|
||||
public static final int R_MSP430X_PCR20_EXT_DST = 6; // S + A - PC
|
||||
public static final int R_MSP430X_PCR20_EXT_ODST = 7; // S + A - PC
|
||||
public static final int R_MSP430X_ABS20_EXT_SRC = 8; // S + A
|
||||
public static final int R_MSP430X_ABS20_EXT_DST = 9; // S + A
|
||||
public static final int R_MSP430X_ABS20_EXT_ODST = 10; // S + A
|
||||
public static final int R_MSP430X_ABS20_ADR_SRC = 11; // S + A
|
||||
public static final int R_MSP430X_ABS20_ADR_DST = 12; // S + A
|
||||
public static final int R_MSP430X_PCR16 = 13; // S + A - PC
|
||||
public static final int R_MSP430X_PCR20_CALL = 14; // S + A - PC
|
||||
public static final int R_MSP430X_ABS16 = 15; // S + A
|
||||
public static final int R_MSP430_ABS_HI16 = 16; // S + A (Rela only)
|
||||
public static final int R_MSP430_PREL31 = 17; // S + A - PC
|
||||
public static final int R_MSP430_EHTYPE = 18; // encodes typeinfo addresses in exception tables
|
||||
public static final int R_MSP430X_10_PCREL = 19; // Red Hat invention.
|
||||
public static final int R_MSP430X_2X_PCREL = 20; // Red Hat invention
|
||||
public static final int R_MSP430X_SYM_DIFF = 21; // Red Hat invention*/
|
||||
public static final int R_MSP430X_SET_ULEB128 = 22; // GNU only
|
||||
public static final int R_MSP430X_SUB_ULEB128 = 23; // GNU only
|
||||
|
||||
private TI_MSP430X_ElfRelocationConstants() {
|
||||
//class not for instantiation
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.elf.relocation;
|
||||
|
||||
import ghidra.app.util.bin.format.elf.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.reloc.Relocation.Status;
|
||||
import ghidra.program.model.reloc.RelocationResult;
|
||||
import ghidra.util.exception.NotFoundException;
|
||||
|
||||
public class TI_MSP430X_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
public static final int E_MSP430_MACH_MSP430X = 45;
|
||||
|
||||
@Override
|
||||
public boolean canRelocate(ElfHeader elf) {
|
||||
return (elf.e_machine() == ElfConstants.EM_MSP430) &&
|
||||
((elf.e_flags() & 0xff) == E_MSP430_MACH_MSP430X);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
|
||||
ElfRelocation relocation, Address relocationAddress)
|
||||
throws MemoryAccessException, NotFoundException {
|
||||
int type = relocation.getType();
|
||||
if (type == TI_MSP430X_ElfRelocationConstants.R_MSP430_NONE) {
|
||||
return RelocationResult.SKIPPED;
|
||||
}
|
||||
|
||||
Program program = elfRelocationContext.getProgram();
|
||||
Memory memory = program.getMemory();
|
||||
int symbolIndex = relocation.getSymbolIndex();
|
||||
long addend = relocation.getAddend(); // will be 0 for REL case
|
||||
long offset = relocationAddress.getOffset();
|
||||
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
|
||||
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
|
||||
long symbolValue = elfRelocationContext.getSymbolValue(sym);
|
||||
int byteLength = 0;
|
||||
|
||||
switch (type) {
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430_ABS32:
|
||||
int newIntValue = (int) (symbolValue + addend);
|
||||
memory.setInt(relocationAddress, newIntValue);
|
||||
byteLength = 4;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430_ABS16:
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_ABS16:
|
||||
short newShortValue = (short) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430_ABS8:
|
||||
byte newByteValue = (byte) (symbolValue + addend);
|
||||
memory.setByte(relocationAddress, newByteValue);
|
||||
byteLength = 1;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430_PCR16:
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_PCR16:
|
||||
newShortValue = (short) (symbolValue + addend - offset);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_EXT_SRC:
|
||||
newIntValue = (int) (symbolValue + addend - offset - 4);
|
||||
memory.setShort(relocationAddress.add(4), (short) (newIntValue));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf0;
|
||||
short highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xff0f;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 3;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_EXT_DST:
|
||||
newIntValue = (int) (symbolValue + addend - offset - 4);
|
||||
memory.setShort(relocationAddress.add(4), (short) (newIntValue));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xfff0;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 3;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_EXT_ODST:
|
||||
newIntValue = (int) (symbolValue + addend - offset - 4);
|
||||
memory.setShort(relocationAddress.add(6), (short) (newIntValue));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xfff0;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 4;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_EXT_SRC:
|
||||
newIntValue = (int) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress.add(4), (short) (newIntValue));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf0;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xff0f;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 3;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_EXT_DST:
|
||||
newIntValue = (int) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress.add(4), (short) (newIntValue));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xfff0;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 3;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_EXT_ODST:
|
||||
newIntValue = (int) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress.add(6), (short) (newIntValue));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xfff0;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 4;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_ABS20_ADR_DST:
|
||||
newIntValue = (int) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress.add(2), (short) (newIntValue & 0xffff));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xfff0;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 3;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_PCR20_CALL:
|
||||
newIntValue = (int) (symbolValue + addend - offset);
|
||||
memory.setShort(relocationAddress.add(2), (short) (newIntValue & 0xffff));
|
||||
newIntValue >>= 16;
|
||||
newIntValue &= 0xf;
|
||||
highWord = memory.getShort(relocationAddress);
|
||||
highWord &= 0xfff0;
|
||||
highWord |= newIntValue;
|
||||
memory.setShort(relocationAddress, highWord);
|
||||
byteLength = 3;
|
||||
break;
|
||||
case TI_MSP430X_ElfRelocationConstants.R_MSP430X_10_PCREL:
|
||||
short oldShortValue = memory.getShort(relocationAddress);
|
||||
oldShortValue &= 0xfc00;
|
||||
newShortValue = (short) (symbolValue + addend - offset - 2);
|
||||
newShortValue >>= 1;
|
||||
newShortValue &= 0x3ff;
|
||||
newShortValue = (short) (oldShortValue | newShortValue);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
default:
|
||||
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
|
||||
elfRelocationContext.getLog());
|
||||
return RelocationResult.UNSUPPORTED;
|
||||
}
|
||||
return new RelocationResult(Status.APPLIED, byteLength);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.elf.relocation;
|
||||
|
||||
/**
|
||||
* class for elf_msp430_reloc_type (from binutils source)
|
||||
*/
|
||||
public class TI_MSP430_ElfRelocationConstants {
|
||||
public static final int R_MSP430_NONE = 0;
|
||||
public static final int R_MSP430_32 = 1;
|
||||
public static final int R_MSP430_10_PCREL = 2;
|
||||
public static final int R_MSP430_16 = 3;
|
||||
public static final int R_MSP430_16_PCREL = 4;
|
||||
public static final int R_MSP430_16_BYTE = 5;
|
||||
public static final int R_MSP430_16_PCREL_BYTE = 6;
|
||||
public static final int R_MSP430_2X_PCREL = 7;
|
||||
public static final int R_MSP430_RL_PCREL = 8;
|
||||
public static final int R_MSP430_8 = 9;
|
||||
public static final int R_MSP430_SYM_DIFF = 10;
|
||||
public static final int R_MSP430_SET_ULEB128 = 11; // GNU only.
|
||||
public static final int R_MSP430_SUB_ULEB128 = 12; // GNU only
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.bin.format.elf.relocation;
|
||||
|
||||
import ghidra.app.util.bin.format.elf.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.program.model.reloc.Relocation.Status;
|
||||
import ghidra.program.model.reloc.RelocationResult;
|
||||
import ghidra.util.exception.NotFoundException;
|
||||
|
||||
public class TI_MSP430_ElfRelocationHandler extends ElfRelocationHandler {
|
||||
|
||||
@Override
|
||||
public boolean canRelocate(ElfHeader elf) {
|
||||
return (elf.e_machine() == ElfConstants.EM_MSP430) &&
|
||||
((elf.e_flags() & 0xff) != TI_MSP430X_ElfRelocationHandler.E_MSP430_MACH_MSP430X);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RelocationResult relocate(ElfRelocationContext elfRelocationContext,
|
||||
ElfRelocation relocation, Address relocationAddress)
|
||||
throws MemoryAccessException, NotFoundException {
|
||||
int type = relocation.getType();
|
||||
if (type == TI_MSP430_ElfRelocationConstants.R_MSP430_NONE) {
|
||||
return RelocationResult.SKIPPED;
|
||||
}
|
||||
|
||||
Program program = elfRelocationContext.getProgram();
|
||||
Memory memory = program.getMemory();
|
||||
int symbolIndex = relocation.getSymbolIndex();
|
||||
long addend = relocation.getAddend(); // will be 0 for REL case
|
||||
long offset = relocationAddress.getOffset();
|
||||
ElfSymbol sym = elfRelocationContext.getSymbol(symbolIndex); // may be null
|
||||
String symbolName = elfRelocationContext.getSymbolName(symbolIndex);
|
||||
long symbolValue = elfRelocationContext.getSymbolValue(sym);
|
||||
|
||||
int byteLength = 0;
|
||||
|
||||
switch (type) {
|
||||
case TI_MSP430_ElfRelocationConstants.R_MSP430_32:
|
||||
int newIntValue = (int) (symbolValue + addend);
|
||||
memory.setInt(relocationAddress, newIntValue);
|
||||
byteLength = 4;
|
||||
break;
|
||||
case TI_MSP430_ElfRelocationConstants.R_MSP430_10_PCREL:
|
||||
short oldShortValue = memory.getShort(relocationAddress);
|
||||
oldShortValue &= 0xfc00;
|
||||
short newShortValue = (short) (symbolValue + addend - offset - 2);
|
||||
newShortValue >>= 1;
|
||||
newShortValue &= 0x3ff;
|
||||
newShortValue = (short) (oldShortValue | newShortValue);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
case TI_MSP430_ElfRelocationConstants.R_MSP430_16:
|
||||
newShortValue = (short) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
//case TI_MSP430_ElfRelocationConstants.R_MSP430_16_PCREL:
|
||||
case TI_MSP430_ElfRelocationConstants.R_MSP430_16_BYTE:
|
||||
newShortValue = (short) (symbolValue + addend);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
case TI_MSP430_ElfRelocationConstants.R_MSP430_16_PCREL_BYTE:
|
||||
newShortValue = (short) (symbolValue + addend - offset);
|
||||
memory.setShort(relocationAddress, newShortValue);
|
||||
byteLength = 2;
|
||||
break;
|
||||
//case TI_MSP430_ElfRelocationConstants.R_MSP430_2X_PCREL:
|
||||
//case TI_MSP430_ElfRelocationConstants.R_MSP430_RL_PCREL:
|
||||
case TI_MSP430_ElfRelocationConstants.R_MSP430_8:
|
||||
byte newByteValue = (byte) (symbolValue + addend);
|
||||
memory.setByte(relocationAddress, newByteValue);
|
||||
byteLength = 1;
|
||||
break;
|
||||
//case TI_MSP430_ElfRelocationConstants.R_MSP430_SYM_DIFF:
|
||||
//case TI_MSP430_ElfRelocationConstants.R_MSP430_SET_ULEB128:
|
||||
//case TI_MSP430_ElfRelocationConstants.R_MSP430_SUB_ULEB128:
|
||||
default:
|
||||
markAsUnhandled(program, relocationAddress, type, symbolIndex, symbolName,
|
||||
elfRelocationContext.getLog());
|
||||
return RelocationResult.UNSUPPORTED;
|
||||
}
|
||||
return new RelocationResult(Status.APPLIED, byteLength);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors;
|
||||
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.test.processors.support.EmulatorTestRunner;
|
||||
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
|
||||
import junit.framework.Test;
|
||||
|
||||
public class MSP430X_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
|
||||
|
||||
private static final String LANGUAGE_ID = "TI_MSP430X:LE:32:default";
|
||||
private static final String COMPILER_SPEC_ID = "default";
|
||||
|
||||
private static final String[] REG_DUMP_SET = new String[] {};
|
||||
|
||||
public MSP430X_O0_EmulatorTest(String name) throws Exception {
|
||||
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProcessorDesignator() {
|
||||
return "MSP430X_GCC_O0";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeState(EmulatorTestRunner testRunner, Program program)
|
||||
throws Exception {
|
||||
super.initializeState(testRunner, program);
|
||||
testRunner.setRegister("SP", 0xFF80L);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(MSP430X_O0_EmulatorTest.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors;
|
||||
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.test.processors.support.EmulatorTestRunner;
|
||||
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
|
||||
import junit.framework.Test;
|
||||
|
||||
public class MSP430X_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
|
||||
|
||||
private static final String LANGUAGE_ID = "TI_MSP430X:LE:32:default";
|
||||
private static final String COMPILER_SPEC_ID = "default";
|
||||
|
||||
private static final String[] REG_DUMP_SET = new String[] {};
|
||||
|
||||
public MSP430X_O3_EmulatorTest(String name) throws Exception {
|
||||
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProcessorDesignator() {
|
||||
return "MSP430X_GCC_O3";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeState(EmulatorTestRunner testRunner, Program program)
|
||||
throws Exception {
|
||||
super.initializeState(testRunner, program);
|
||||
testRunner.setRegister("SP", 0xFF80L);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(MSP430X_O3_EmulatorTest.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors;
|
||||
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.test.processors.support.EmulatorTestRunner;
|
||||
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
|
||||
import junit.framework.Test;
|
||||
|
||||
public class MSP430_O0_EmulatorTest extends ProcessorEmulatorTestAdapter {
|
||||
|
||||
private static final String LANGUAGE_ID = "TI_MSP430:LE:16:default";
|
||||
private static final String COMPILER_SPEC_ID = "default";
|
||||
|
||||
private static final String[] REG_DUMP_SET = new String[] {};
|
||||
|
||||
public MSP430_O0_EmulatorTest(String name) throws Exception {
|
||||
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProcessorDesignator() {
|
||||
return "MSP430_GCC_O0";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeState(EmulatorTestRunner testRunner, Program program)
|
||||
throws Exception {
|
||||
super.initializeState(testRunner, program);
|
||||
testRunner.setRegister("SP", 0xFF80L);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(MSP430_O0_EmulatorTest.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors;
|
||||
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.test.processors.support.EmulatorTestRunner;
|
||||
import ghidra.test.processors.support.ProcessorEmulatorTestAdapter;
|
||||
import junit.framework.Test;
|
||||
|
||||
public class MSP430_O3_EmulatorTest extends ProcessorEmulatorTestAdapter {
|
||||
|
||||
private static final String LANGUAGE_ID = "TI_MSP430:LE:16:default";
|
||||
private static final String COMPILER_SPEC_ID = "default";
|
||||
|
||||
private static final String[] REG_DUMP_SET = new String[] {};
|
||||
|
||||
public MSP430_O3_EmulatorTest(String name) throws Exception {
|
||||
super(name, LANGUAGE_ID, COMPILER_SPEC_ID, REG_DUMP_SET);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getProcessorDesignator() {
|
||||
return "MSP430_GCC_O3";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeState(EmulatorTestRunner testRunner, Program program)
|
||||
throws Exception {
|
||||
super.initializeState(testRunner, program);
|
||||
testRunner.setRegister("SP", 0xFF80L);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return ProcessorEmulatorTestAdapter.buildEmulatorTestSuite(MSP430_O3_EmulatorTest.class);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue