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
  • Issues
  • #5316
Closed
Open
Issue created Feb 01, 2022 by Derek Bruening@derekbrueningContributor

AArch64 fails to encode OP_ldr with pc-relative operand

For porting drbbdup to AArchXX for #4134 (closed) I changed the drbbdup tests to use rel-addr operands instead of abs-addr operands (via OPND_CREATE_ABSMEM) (xref #5295) and it all worked on AArch64: the tests pass. But they fail on ARM trying to encode the load of the rel-addr since it does not reach:

ERROR: Could not find encoding for: ldr    <rel> 0xb6fb2008[4byte] -> %r0

When I went to see how a64 worked: when logging is enabled it hits an assert:

SYSLOG_ERROR: Application /home/derek/dr/build/suite/tests/bin/simple_app (3952044).  Internal Error: DynamoRIO debug check failure: /home/derek/dr/
src/core/ir/disassemble_shared.c:1520 nxt_pc != NULL

Yet without logging it works!

In the debugger we have:

(gdb) x/90i targetf->start_pc
   0xffffb3fb0008:	ldp	x0, x1, [x28]
   0xffffb3fb000c:	str	x1, [x28, #360]
   0xffffb3fb0010:	mrs	x0, nzcv
   0xffffb3fb0014:	str	x0, [x28, #344]
   0xffffb3fb0018:	mov	x0, #0xe080                	// #57472
   0xffffb3fb001c:	movk	x0, #0xb3f9, lsl #16
   0xffffb3fb0020:	movk	x0, #0xffff, lsl #32
   0xffffb3fb0024:	ldr	x0, [x0]
   0xffffb3fb0028:	cmp	x0, #0x1
   0xffffb3fb002c:	b.ne	0xffffb3fb0048  // b.any

The instrumentation had just a ldr with a rel-addr opnd: so who inserted the mov;movk;movk?

Disabling the disassembly assert (looks like it only really needs it for the length: so maybe we should remove the encode there for a64) logging now works

after instrumentation:
TAG  0x0000ffffb38840c0
 +0    m4 @0x0000fffd6f8e50e8  6d6d7564   str    %x1 -> +0x0168(%x28)[8byte]
 +4    m4 @0x0000fffd6f8e4da0  6d6d7564   mrs    %nzcv -> %x0
 +8    m4 @0x0000fffd6f8e4cd8  6d6d7564   str    %x0 -> +0x0158(%x28)[8byte]
 +12   m4 @0x0000fffd6f8e4c58  6d6d7564   ldr    <rel> 0x0000ffff6f856080[8byte] -> %x0
 +16   m4 @0x0000fffd6f8e4e20  6d6d7564   <label>
 +20   m4 @0x0000fffd6f8e4bd8  6d6d7564   subs   %x0 $0x0000000000000001 lsl $0x0000000000000000 -> %xzr
 +24   m4 @0x0000fffd6f8e4b10  6d6d7564   b.ne   @0x0000fffd6f8e4fa0[8byte]
...

bb ilist after mangling:
TAG  0x0000ffffb38840c0
 +0    m4 @0x0000fffd6f8e50e8  6d6d7564   str    %x1 -> +0x0168(%x28)[8byte]
 +4    m4 @0x0000fffd6f8e4da0  6d6d7564   mrs    %nzcv -> %x0
 +8    m4 @0x0000fffd6f8e4cd8  6d6d7564   str    %x0 -> +0x0158(%x28)[8byte]
 +12   m4 @0x0000fffd6f8e4418  6d6d7564   movz   $0x6080 lsl $0x00 -> %x0
 +16   m4 @0x0000fffd6f8e4350  6d6d7564   movk   %x0 $0x6f85 lsl $0x10 -> %x0
 +20   m4 @0x0000fffd6f8e42d0  6d6d7564   movk   %x0 $0xffff lsl $0x20 -> %x0
 +24   m4 @0x0000fffd6f8e4208  6d6d7564   ldr    (%x0)[8byte] -> %x0
 +28   m4 @0x0000fffd6f8e4e20  6d6d7564   <label>
 +32   m4 @0x0000fffd6f8e4bd8  6d6d7564   subs   %x0 $0x0000000000000001 lsl $0x0000000000000000 -> %xzr
 +36   m4 @0x0000fffd6f8e4b10  6d6d7564   b.ne   @0x0000fffd6f8e4fa0[8byte]
...

It looks like the a64 mangling does the immediate-into-reg expansion. But this is tool code: why is it being mangled? Here we go:

        if (instr_has_rel_addr_reference(instr)
            /* XXX i#1834: it should be up to the app to re-relativize, yet on amd64
             * our own samples are relying on DR re-relativizing (and we just haven't
             * run big enough apps to hit reachability problems) so for now we continue
             * mangling meta instrs for x86 builds.
             */
            IF_ARM(&&instr_is_app(instr))) {
            instr_t *res = mangle_rel_addr(dcontext, ilist, instr, next_instr);

So the IF_ARM doesn't apply to a64.

#1834 is confusingly closed: I re-opened it since it does not seem completely resolved.

This issue covers the disas assert and specific aarchxx issues. The rest overlaps with #1834.

Assignee
Assign to
Time tracking