Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • D dynamorio
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,467
    • Issues 1,467
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 44
    • Merge requests 44
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • DynamoRIO
  • dynamorio
  • Merge requests
  • !5065

Fix normalize_ldm edge case when ldm writes to base and pc

  • Review changes

  • Download
  • Email patches
  • Plain diff
Open Ivan Gulakov requested to merge github/fork/ispras/ldm-mangle-edge-case into master Aug 30, 2021
  • Overview 11
  • Commits 1
  • Pipelines 0
  • Changes 1

So I'm trying to fix an issue with this instruction:

ldm (%sp)[40byte] -> %r4 %r5 %r6 %r7 %r8 %r9 %r10 %r11 %sp %pc

Assuming the comment above ASSERT_NOT_IMPLEMENTED

    /* FIXME i#1551: NYI on case like "ldm r10, {r10, pc}": if base reg
     * is clobbered, "ldr pc [base, disp]" will use wrong base value.
     * It seems the only solution is load the target value first and store
     * it into some TLS slot for later "ldr pc".
     */

we have to store value from base+pc_reg_offset to TLS and then restore it back to PC at the end of BB.

The problem is that I'm not sure we can restore it using dr_insert_read_tls_field. It doesn't work as excepted, restoring only random trash to pc.

Here is a fragment from log file:

exit_branch_type=0x6 bb->exit_target=0x4ecfc180
bb ilist before mangling:
TAG  0xb6f65438
 +0    L3 @0x4ed4538c  e51b2034   ldr    -0x34(%r11)[4byte] -> %r2
 +4    L3 @0x4ed44d24  e3a03000   mov    $0x00000000 -> %r3
 +8    L3 @0x4ed454c0  e590c000   ldr    (%r0)[4byte] -> %r12
 +12   L3 @0x4ed451b8  e5802004   str    %r2 -> +0x04(%r0)[4byte]
 +16   L3 @0x4ed452ec  e08c1001   add    %r12 %r1  $0x00 -> %r1
 +20   L3 @0x4ed43cb8  e5801000   str    %r1 -> (%r0)[4byte]
 +24   L3 @0x4ed44a48  e1a00003   mov    %r3 -> %r0
 +28   L3 @0x4ed43b78  e24bd028   sub    %r11 $0x00000028 -> %sp
 +32   L3 @0x4ed45510  e89daff0   ldm    (%sp)[40byte] -> %r4 %r5 %r6 %r7 %r8 %r9 %r10 %r11 %sp %pc
 +36   L4 @0x4ed44650  eafeed4a   b      $0x4ecfc180 <shared_bb_ibl_ret>
END 0xb6f65438

skip restore stolen reg app value for: ldm    (%sp) -> %r4 %r5 %r6 %r7 %r8 %r9 %r10 %r11 %sp
bb ilist after mangling:
TAG  0xb6f65438
 +0    L3 @0x4ed4538c  e51b2034   ldr    -0x34(%r11)[4byte] -> %r2
 +4    L3 @0x4ed44d24  e3a03000   mov    $0x00000000 -> %r3
 +8    L3 @0x4ed454c0  e590c000   ldr    (%r0)[4byte] -> %r12
 +12   L3 @0x4ed451b8  e5802004   str    %r2 -> +0x04(%r0)[4byte]
 +16   L3 @0x4ed452ec  e08c1001   add    %r12 %r1  $0x00 -> %r1
 +20   L3 @0x4ed43cb8  e5801000   str    %r1 -> (%r0)[4byte]
 +24   L3 @0x4ed44a48  e1a00003   mov    %r3 -> %r0
 +28   L3 @0x4ed43b78  e24bd028   sub    %r11 $0x00000028 -> %sp
 +32   m4 @0x4ed46b64  e58a0000   str    %r0 -> (%r10)[4byte]
 +36   m4 @0x4ed439bc  e1a0000a   mov    %r10 -> %r0
 +40   m4 @0x4ed45644  e58a0008   str    %r0 -> +0x08(%r10)[4byte]
 +44   L4 @0x4ed46e4c  e59d0024   ldr    +0x24(%sp)[4byte] -> %r0
 +48   m4 @0x4ed44b88  e58a1000   str    %r1 -> (%r10)[4byte]
 +52   m4 @0x4ed43d08  e59a101c   ldr    +0x1c(%r10)[4byte] -> %r1
 +56   m4 @0x4ed4438c  e5911260   ldr    +0x0260(%r1)[4byte] -> %r1
 +60   m4 @0x4ed44914  e5810000   str    %r0 -> (%r1)[4byte]
 +64   m4 @0x4ed43da8  e59a1000   ldr    (%r10)[4byte] -> %r1
 +68   m4 @0x4ed43fc0  e59a0008   ldr    +0x08(%r10)[4byte] -> %r0
 +72   L4 @0x4ed45510  e89d2ff0   ldm    (%sp) -> %r4 %r5 %r6 %r7 %r8 %r9 %r10 %r11 %sp
 +76   m4 @0x4ed43e8c  e580a018   str    %r10 -> +0x18(%r0)[4byte]
 +80   m4 @0x4ed44874  e1a0a000   mov    %r0 -> %r10
 +84   m4 @0x4ed4442c  e59a0000   ldr    (%r10)[4byte] -> %r0
 +88   m4 @0x4ed45118  e59af01c   ldr    +0x1c(%r10)[4byte] -> %pc
 +92   m4 @0x4ed45420  e59ff260   ldr    +0x0260(%pc)[4byte] -> %pc
 +96   m4 @0x4ed4433c  e59ff000   ldr    (%pc)[4byte] -> %pc
 +100  L4 @0x4ed44650  eafeed4a   b      $0x4ecfc180 <shared_bb_ibl_ret>
END 0xb6f65438

.........

master_signal_handler: thread=1108, sig=11, xsp=0x4ed5bc88, retaddr=0x0000000b
siginfo: sig = 11, pid = 1322344512, status = 0, errno = 0, si_code = 2
	r0  =0x612d0743
	r1  =0x612d0743
	r2  =0x2a720870
	r3  =0x00000000
	r4  =0x00000000
	r5  =0xb6f64000
	r6  =0xbefffa24
	r7  =0x00000000
	r8  =0x00000000
	r9  =0x00000000
	r10 =0x4ed2c000
	r11 =0xbefffa0c
	r12 =0x612d0743
	sp  =0xbefff9e8
	r14 =0x00153904
	pc  =0x4ed16040
	cpsr=0x800a0010
computing memory target for 0x4ed16040 causing SIGSEGV, kernel claims it is 0x4ed16040
fault_address: 0x4ed16040
compute_memory_target: falling back to racy protection checks

It remains impossible to mov from random register to pc: we cannot restore it from spill, since we will already rewrite PC.

code from this PR seems legit to me (maybe it needs some cleanup). Any hints to solve this problem?

P.S. armv7, running app under drrun

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: github/fork/ispras/ldm-mangle-edge-case