Skip to content

Commit af3ec25

Browse files
committed
CHB: aggregate for LSL/ASR
1 parent f432c9d commit af3ec25

File tree

4 files changed

+224
-23
lines changed

4 files changed

+224
-23
lines changed

CodeHawk/CHB/bchlibarm32/bCHARMInstructionAggregate.ml

Lines changed: 187 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ open BCHLoadStoreMultipleSequence
4646
open BCHThumbITSequence
4747

4848

49+
module TR = CHTraceResult
50+
51+
4952
let arm_aggregate_kind_to_string (k: arm_aggregate_kind_t) =
5053
match k with
5154
| ARMJumptable jt ->
@@ -56,6 +59,8 @@ let arm_aggregate_kind_to_string (k: arm_aggregate_kind_t) =
5659
^ " target addresses"
5760
| ThumbITSequence it -> it#toString
5861
| LDMSTMSequence s -> s#toString
62+
| PseudoLDRSB (i1, _, _) -> "Pseudo LDRSB at " ^ i1#get_address#to_hex_string
63+
| PseudoLDRSH (i1, _, _) -> "Pseudo LDRSH at " ^ i1#get_address#to_hex_string
5964
| BXCall (_, i2) -> "BXCall at " ^ i2#get_address#to_hex_string
6065

6166

@@ -115,6 +120,16 @@ object (self)
115120
| BXCall _ -> true
116121
| _ -> false
117122

123+
method is_pseudo_ldrsh =
124+
match self#kind with
125+
| PseudoLDRSH _ -> true
126+
| _ -> false
127+
128+
method is_pseudo_ldrsb =
129+
match self#kind with
130+
| PseudoLDRSH _ -> true
131+
| _ -> false
132+
118133
method write_xml (_node: xml_element_int) = ()
119134

120135
method toCHIF (_faddr: doubleword_int) = []
@@ -191,6 +206,32 @@ let make_bx_call_aggregate
191206
~anchor:bxinstr
192207

193208

209+
let make_pseudo_ldrsh_aggregate
210+
(ldrhinstr: arm_assembly_instruction_int)
211+
(lslinstr: arm_assembly_instruction_int)
212+
(asrinstr: arm_assembly_instruction_int): arm_instruction_aggregate_int =
213+
let kind = PseudoLDRSH (ldrhinstr, lslinstr, asrinstr) in
214+
make_arm_instruction_aggregate
215+
~kind
216+
~instrs:[ldrhinstr; lslinstr; asrinstr]
217+
~entry:ldrhinstr
218+
~exitinstr:asrinstr
219+
~anchor:asrinstr
220+
221+
222+
let make_pseudo_ldrsb_aggregate
223+
(ldrbinstr: arm_assembly_instruction_int)
224+
(lslinstr: arm_assembly_instruction_int)
225+
(asrinstr: arm_assembly_instruction_int): arm_instruction_aggregate_int =
226+
let kind = PseudoLDRSB (ldrbinstr, lslinstr, asrinstr) in
227+
make_arm_instruction_aggregate
228+
~kind
229+
~instrs:[ldrbinstr; lslinstr; asrinstr]
230+
~entry:ldrbinstr
231+
~exitinstr:asrinstr
232+
~anchor:asrinstr
233+
234+
194235
let disassemble_arm_instructions
195236
(ch: pushback_stream_int) (iaddr: doubleword_int) (n: int) =
196237
for _i = 1 to n do
@@ -296,30 +337,153 @@ let identify_bx_call
296337
| _ -> None
297338

298339

340+
(* format of pseudo LDRSH (in ARM)
341+
342+
An LDRH combined with LSL 16, ASR 16 converts into (effectively) an
343+
LDRSH:
344+
345+
LDRH Rx, mem
346+
LSL Rx, Rx, #0x10
347+
ASR Rx, Rx, #0x10
348+
*)
349+
let identify_pseudo_ldrsh
350+
(ch: pushback_stream_int)
351+
(instr: arm_assembly_instruction_int):
352+
(arm_assembly_instruction_int
353+
* arm_assembly_instruction_int
354+
* arm_assembly_instruction_int) option =
355+
let sixteen = CHNumerical.mkNumerical 16 in
356+
match instr#get_opcode with
357+
| ArithmeticShiftRight (_, ACCAlways, rd, rs, imm, _)
358+
when imm#is_immediate
359+
&& imm#to_numerical#equal sixteen
360+
&& (rd#get_register = rs#get_register) ->
361+
let addr = instr#get_address in
362+
let lslinstr_r = get_arm_assembly_instruction (addr#add_int (-4)) in
363+
let ldrhinstr_r = get_arm_assembly_instruction (addr#add_int (-8)) in
364+
(match (TR.to_option lslinstr_r, TR.to_option ldrhinstr_r) with
365+
| (Some lslinstr, Some ldrhinstr) ->
366+
if
367+
(match lslinstr#get_opcode with
368+
| LogicalShiftLeft (_, ACCAlways, rd1, rs1, imm, _)
369+
when imm#is_immediate
370+
&& imm#to_numerical#equal sixteen
371+
&& (rd1#get_register = rd#get_register)
372+
&& (rs1#get_register = rd#get_register) -> true
373+
| _ -> false)
374+
&& (match ldrhinstr#get_opcode with
375+
| LoadRegisterHalfword (ACCAlways, rd2, _, _, _, _)
376+
when rd2#get_register = rd#get_register -> true
377+
| _ -> false)
378+
then
379+
Some (TR.tget_ok ldrhinstr_r, TR.tget_ok lslinstr_r, instr)
380+
else
381+
None
382+
| _ -> None)
383+
| _ -> None
384+
385+
386+
(* format of pseudo LDRSB (in ARM)
387+
388+
An LDRH combined with LSL 16, ASR 16 converts into (effectively) an
389+
LDRSH:
390+
391+
LDRB Rx, mem
392+
LSL Rx, Rx, #0x18
393+
ASR Rx, Rx, #0x18
394+
*)
395+
let identify_pseudo_ldrsb
396+
(ch: pushback_stream_int)
397+
(instr: arm_assembly_instruction_int):
398+
(arm_assembly_instruction_int
399+
* arm_assembly_instruction_int
400+
* arm_assembly_instruction_int) option =
401+
let twentyfour = CHNumerical.mkNumerical 24 in
402+
match instr#get_opcode with
403+
| ArithmeticShiftRight (_, ACCAlways, rd, rs, imm, _)
404+
when imm#is_immediate
405+
&& imm#to_numerical#equal twentyfour
406+
&& (rd#get_register = rs#get_register) ->
407+
let addr = instr#get_address in
408+
let lslinstr_r = get_arm_assembly_instruction (addr#add_int (-4)) in
409+
let ldrbinstr_r = get_arm_assembly_instruction (addr#add_int (-8)) in
410+
(match (TR.to_option lslinstr_r, TR.to_option ldrbinstr_r) with
411+
| (Some lslinstr, Some ldrbinstr) ->
412+
if
413+
(match lslinstr#get_opcode with
414+
| LogicalShiftLeft (_, ACCAlways, rd1, rs1, imm, _)
415+
when imm#is_immediate
416+
&& imm#to_numerical#equal twentyfour
417+
&& (rd1#get_register = rd#get_register)
418+
&& (rs1#get_register = rd#get_register) -> true
419+
| _ -> false)
420+
&& (match ldrbinstr#get_opcode with
421+
| LoadRegisterByte (ACCAlways, rd2, _, _, _, _)
422+
when rd2#get_register = rd#get_register -> true
423+
| _ -> false)
424+
then
425+
Some (TR.tget_ok ldrbinstr_r, TR.tget_ok lslinstr_r, instr)
426+
else
427+
None
428+
| _ -> None)
429+
| _ -> None
430+
431+
432+
299433
let identify_arm_aggregate
300434
(ch: pushback_stream_int)
301435
(instr: arm_assembly_instruction_int):
302436
arm_instruction_aggregate_int option =
303-
match identify_jumptable ch instr with
304-
| Some (instrs, jt) ->
305-
let anchor = List.nth instrs ((List.length instrs) - 1) in
306-
let entry = List.hd instrs in
307-
let exitinstr = anchor in
308-
Some (make_arm_jumptable_aggregate ~jt ~instrs ~entry ~exitinstr ~anchor)
309-
| _ ->
310-
match identify_it_sequence ch instr with
311-
| Some its ->
312-
let instrs = its#instrs in
313-
let entry = List.hd instrs in
314-
let exitinstr = List.hd (List.rev instrs) in
315-
Some (make_it_sequence_aggregate
316-
~its ~instrs ~entry ~exitinstr ~anchor:entry)
317-
| _ ->
318-
match identify_ldmstm_sequence ch instr with
319-
| Some ldmstmseq ->
320-
Some (make_ldm_stm_sequence_aggregate ldmstmseq)
321-
| _ ->
322-
match identify_bx_call ch instr with
323-
| Some (movinstr, bxinstr) ->
324-
Some (make_bx_call_aggregate movinstr bxinstr)
325-
| _ -> None
437+
let result =
438+
match identify_jumptable ch instr with
439+
| Some (instrs, jt) ->
440+
let anchor = List.nth instrs ((List.length instrs) - 1) in
441+
let entry = List.hd instrs in
442+
let exitinstr = anchor in
443+
Some (make_arm_jumptable_aggregate ~jt ~instrs ~entry ~exitinstr ~anchor)
444+
| _ -> None in
445+
let result =
446+
match result with
447+
| Some _ -> result
448+
| _ ->
449+
match identify_it_sequence ch instr with
450+
| Some its ->
451+
let instrs = its#instrs in
452+
let entry = List.hd instrs in
453+
let exitinstr = List.hd (List.rev instrs) in
454+
Some (make_it_sequence_aggregate
455+
~its ~instrs ~entry ~exitinstr ~anchor:entry)
456+
| _ -> None in
457+
let result =
458+
match result with
459+
| Some _ -> result
460+
| _ ->
461+
match identify_ldmstm_sequence ch instr with
462+
| Some ldmstmseq ->
463+
Some (make_ldm_stm_sequence_aggregate ldmstmseq)
464+
| _ -> None in
465+
let result =
466+
match result with
467+
| Some _ -> result
468+
| _ ->
469+
match identify_bx_call ch instr with
470+
| Some (movinstr, bxinstr) ->
471+
Some (make_bx_call_aggregate movinstr bxinstr)
472+
| _ -> None in
473+
let result =
474+
match result with
475+
| Some _ -> result
476+
| _ ->
477+
match identify_pseudo_ldrsh ch instr with
478+
| Some (ldrhinstr, lslinstr, asrinstr) ->
479+
Some (make_pseudo_ldrsh_aggregate ldrhinstr lslinstr asrinstr)
480+
| _ -> None in
481+
let result =
482+
match result with
483+
| Some _ -> result
484+
| _ ->
485+
match identify_pseudo_ldrsb ch instr with
486+
| Some (ldrbinstr, lslinstr, asrinstr) ->
487+
Some (make_pseudo_ldrsb_aggregate ldrbinstr lslinstr asrinstr)
488+
| _ -> None in
489+
result

CodeHawk/CHB/bchlibarm32/bCHARMTypes.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,14 @@ type arm_aggregate_kind_t =
15231523
| ARMJumptable of arm_jumptable_int
15241524
| ThumbITSequence of thumb_it_sequence_int
15251525
| LDMSTMSequence of ldm_stm_sequence_int
1526+
| PseudoLDRSH of
1527+
arm_assembly_instruction_int
1528+
* arm_assembly_instruction_int
1529+
* arm_assembly_instruction_int
1530+
| PseudoLDRSB of
1531+
arm_assembly_instruction_int
1532+
* arm_assembly_instruction_int
1533+
* arm_assembly_instruction_int
15261534
| BXCall of arm_assembly_instruction_int * arm_assembly_instruction_int
15271535

15281536

@@ -1546,6 +1554,8 @@ class type arm_instruction_aggregate_int =
15461554
method is_it_sequence: bool
15471555
method is_ldm_stm_sequence: bool
15481556
method is_bx_call: bool
1557+
method is_pseudo_ldrsh: bool
1558+
method is_pseudo_ldrsb: bool
15491559

15501560
(* i/o *)
15511561
method write_xml: xml_element_int -> unit

CodeHawk/CHB/bchlibarm32/bCHFnARMDictionary.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ object (self)
643643
~useshigh:[get_def_use_high vrd]
644644
() in
645645
let (tags, args) = add_optional_instr_condition tagstring args c in
646+
let tags = add_optional_subsumption tags in
646647
(tags, args)
647648

648649
| BitFieldClear (c, rd, _, _, _) ->
@@ -1310,6 +1311,11 @@ object (self)
13101311
addr_r
13111312
else
13121313
(tags, args) in
1314+
let tags =
1315+
match instr#is_in_aggregate with
1316+
| Some dw when (get_aggregate dw)#is_pseudo_ldrsb ->
1317+
add_subsumption_dependents (get_aggregate dw) tags
1318+
| _ -> tags in
13131319
(tags, args)
13141320

13151321
| LoadRegisterDual (c, rt, rt2, rn, rm, mem, mem2) ->
@@ -1426,6 +1432,11 @@ object (self)
14261432
addr_r
14271433
else
14281434
(tags, args) in
1435+
let tags =
1436+
match instr#is_in_aggregate with
1437+
| Some dw when (get_aggregate dw)#is_pseudo_ldrsh ->
1438+
add_subsumption_dependents (get_aggregate dw) tags
1439+
| _ -> tags in
14291440
(tags, args)
14301441

14311442
| LoadRegisterSignedByte (c, rt, rn, rm, mem, _) ->

CodeHawk/CHB/bchlibarm32/bCHTranslateARMToCHIF.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,14 @@ let translate_arm_instruction
899899
| ACCAlways -> default cmds
900900
| _ -> make_conditional_commands c cmds)
901901

902+
| ArithmeticShiftRight _
903+
when (match instr#is_in_aggregate with
904+
| Some dw ->
905+
let agg = get_aggregate dw in
906+
agg#is_pseudo_ldrsh || agg#is_pseudo_ldrsb
907+
| _ -> false) ->
908+
default []
909+
902910
| ArithmeticShiftRight(_, c, rd, rn, rm, _) ->
903911
let floc = get_floc loc in
904912
let rdreg = rd#to_register in
@@ -1890,6 +1898,14 @@ let translate_arm_instruction
18901898
| ACCAlways -> default cmds
18911899
| _ -> make_conditional_commands c cmds)
18921900

1901+
| LogicalShiftLeft _
1902+
when (match instr#is_in_aggregate with
1903+
| Some dw ->
1904+
let agg = get_aggregate dw in
1905+
agg#is_pseudo_ldrsh || agg#is_pseudo_ldrsb
1906+
| _ -> false) ->
1907+
default []
1908+
18931909
| LogicalShiftLeft (_, c, rd, rn, rm, _) when rm#is_small_immediate ->
18941910
let floc = get_floc loc in
18951911
let vrd = rd#to_register in

0 commit comments

Comments
 (0)