Skip to content

Commit 3fea317

Browse files
committed
CHB:ARM: add aggregate for BX indirect call
1 parent ac9cd48 commit 3fea317

File tree

5 files changed

+102
-4
lines changed

5 files changed

+102
-4
lines changed

CodeHawk/CHB/bchlibarm32/bCHARMInstructionAggregate.ml

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ let arm_aggregate_kind_to_string (k: arm_aggregate_kind_t) =
5656
^ " target addresses"
5757
| ThumbITSequence it -> it#toString
5858
| LDMSTMSequence s -> s#toString
59+
| BXCall (_, i2) -> "BXCall at " ^ i2#get_address#to_hex_string
5960

6061

6162
class arm_instruction_aggregate_t
@@ -109,6 +110,11 @@ object (self)
109110
| LDMSTMSequence _ -> true
110111
| _ -> false
111112

113+
method is_bx_call =
114+
match self#kind with
115+
| BXCall _ -> true
116+
| _ -> false
117+
112118
method write_xml (_node: xml_element_int) = ()
113119

114120
method toCHIF (_faddr: doubleword_int) = []
@@ -173,6 +179,18 @@ let make_ldm_stm_sequence_aggregate
173179
~anchor:(List.hd (List.tl ldmstmseq#instrs))
174180

175181

182+
let make_bx_call_aggregate
183+
(movinstr: arm_assembly_instruction_int)
184+
(bxinstr: arm_assembly_instruction_int): arm_instruction_aggregate_int =
185+
let kind = BXCall (movinstr, bxinstr) in
186+
make_arm_instruction_aggregate
187+
~kind
188+
~instrs:[movinstr; bxinstr]
189+
~entry:movinstr
190+
~exitinstr:bxinstr
191+
~anchor:bxinstr
192+
193+
176194
let disassemble_arm_instructions
177195
(ch: pushback_stream_int) (iaddr: doubleword_int) (n: int) =
178196
for _i = 1 to n do
@@ -232,6 +250,52 @@ let identify_ldmstm_sequence
232250
| _ -> None
233251

234252

253+
(* format of BX-Call (in ARM)
254+
255+
An indirect jump combined with a MOV of the PC into the LR converts
256+
into an indirect call (because PC holds the instruction-address + 8)
257+
258+
MOV LR, PC
259+
BX Rx
260+
*)
261+
let identify_bx_call
262+
(ch: pushback_stream_int)
263+
(instr: arm_assembly_instruction_int):
264+
(arm_assembly_instruction_int * arm_assembly_instruction_int) option =
265+
let disassemble (iaddr: doubleword_int) =
266+
let instrpos = ch#pos in
267+
let bytes = ch#read_doubleword in
268+
let opcode =
269+
try
270+
disassemble_arm_instruction ch iaddr bytes
271+
with
272+
| _ ->
273+
let _ =
274+
chlog#add
275+
"bx-call disassemble-instruction"
276+
(LBLOCK [iaddr#toPretty]) in
277+
OpInvalid in
278+
let instrbytes = ch#sub instrpos 4 in
279+
let instr = make_arm_assembly_instruction iaddr true opcode instrbytes in
280+
begin
281+
set_arm_assembly_instruction instr;
282+
instr
283+
end in
284+
match instr#get_opcode with
285+
| Move (_, ACCAlways, dst, src, _, _)
286+
when src#is_register
287+
&& dst#get_register = ARLR
288+
&& src#get_register = ARPC ->
289+
begin
290+
let bxinstr = disassemble (instr#get_address#add_int 4) in
291+
match bxinstr#get_opcode with
292+
| BranchExchange (ACCAlways, op) when op#is_register ->
293+
Some (instr, bxinstr)
294+
| _ -> None
295+
end
296+
| _ -> None
297+
298+
235299
let identify_arm_aggregate
236300
(ch: pushback_stream_int)
237301
(instr: arm_assembly_instruction_int):
@@ -254,4 +318,8 @@ let identify_arm_aggregate
254318
match identify_ldmstm_sequence ch instr with
255319
| Some ldmstmseq ->
256320
Some (make_ldm_stm_sequence_aggregate ldmstmseq)
257-
| _ -> None
321+
| _ ->
322+
match identify_bx_call ch instr with
323+
| Some (movinstr, bxinstr) ->
324+
Some (make_bx_call_aggregate movinstr bxinstr)
325+
| _ -> None

CodeHawk/CHB/bchlibarm32/bCHARMTypes.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,7 @@ 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+
| BXCall of arm_assembly_instruction_int * arm_assembly_instruction_int
15261527

15271528

15281529
class type arm_instruction_aggregate_int =
@@ -1544,6 +1545,7 @@ class type arm_instruction_aggregate_int =
15441545
method is_jumptable: bool
15451546
method is_it_sequence: bool
15461547
method is_ldm_stm_sequence: bool
1548+
method is_bx_call: bool
15471549

15481550
(* i/o *)
15491551
method write_xml: xml_element_int -> unit

CodeHawk/CHB/bchlibarm32/bCHConstructARMFunction.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,8 @@ let get_successors
256256
else
257257
let floc = get_floc_by_address faddr instr#get_address in
258258
begin
259-
floc#f#set_unknown_jumptarget instr#get_address#to_hexstring;
259+
floc#f#set_unknown_jumptarget
260+
instr#get_address#to_hex_string;
260261
[]
261262
end)
262263
[]

CodeHawk/CHB/bchlibarm32/bCHDisassembleARM.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,8 @@ let set_block_boundaries () =
719719
| Branch _ | BranchExchange _ ->
720720
(* Don't break up TBB/TBH and other jumptable sequences *)
721721
(match instr#is_in_aggregate with
722-
| Some dw -> not (get_aggregate dw)#is_jumptable
722+
| Some dw when (get_aggregate dw)#is_jumptable -> false
723+
| Some dw when (get_aggregate dw)#is_bx_call -> false
723724
| _ -> true)
724725
| CompareBranchZero _ | CompareBranchNonzero _ -> true
725726
| LoadRegister (_, dst, _, _, _, _)

CodeHawk/CHB/bchlibarm32/bCHFnARMDictionary.ml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,20 @@ object (self)
403403
agginstr#get_address#to_hex_string :: acc) [] agg#instrs in
404404
tags @ ("subsumes" :: deps) in
405405

406+
let add_bx_call_defs
407+
?(xprs: xpr_t list = [])
408+
?(rdefs: int list = [])
409+
(tags: string list)
410+
(args: int list): (string list * int list) =
411+
let tagstring = List.hd tags in
412+
let xprcount = List.length xprs in
413+
let rdefcount = List.length rdefs in
414+
let tagstring = tagstring ^ (string_repeat "x" xprcount) in
415+
let tagstring = tagstring ^ (string_repeat "r" rdefcount) in
416+
let args = args @ (List.map xd#index_xpr xprs) @ rdefs in
417+
let tags = (tagstring :: (List.tl tags)) @ ["bx-call"] in
418+
(tags, args) in
419+
406420
let register_function_prototype (name: string) =
407421
if function_summary_library#has_so_function name then
408422
let fs = function_summary_library#get_so_function name in
@@ -844,7 +858,7 @@ object (self)
844858
let tags = add_optional_subsumption [tagstring] in
845859
(tags, args)
846860

847-
| BranchExchange _ when instr#is_aggregate_anchor ->
861+
| BranchExchange (_, tgt) when instr#is_aggregate_anchor ->
848862
let iaddr = instr#get_address in
849863
let agg = (!arm_assembly_instructions)#get_aggregate iaddr in
850864
if agg#is_jumptable then
@@ -861,6 +875,18 @@ object (self)
861875
let tags = tagstring :: ["agg-jt"] in
862876
let tags = add_subsumption_dependents agg tags in
863877
(tags, args)
878+
else if agg#is_bx_call then
879+
let (tags, args) = callinstr_key() in
880+
let xtgt = tgt#to_expr floc in
881+
let xxtgt = rewrite_expr xtgt in
882+
let rdefs = (get_rdef xtgt) :: (get_all_rdefs xxtgt) in
883+
let (tags, args) =
884+
add_bx_call_defs ~xprs:[xtgt; xxtgt] ~rdefs tags args in
885+
(* let (tagstring, args) =
886+
mk_instrx_data ~xprs:[xtgt; xxtgt] ~rdefs () in
887+
let tags = tagstring :: ["agg-bxcall"] in *)
888+
let tags = add_subsumption_dependents agg tags in
889+
(tags, args)
864890
else
865891
raise
866892
(BCH_failure

0 commit comments

Comments
 (0)