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
  • #4933
Closed
Open
Issue created Jun 01, 2021 by Abhinav Anil Sharma@abhinav92003Contributor

[x86] drreg: aflags not preserved on fault if xax dead

On x86, the aflags restore logic seems broken if xax is dead and doesn't need to be spilled.

The current condition for detecting aflags_in_xax needs xax to be spilled prior to the lahf. https://github.com/DynamoRIO/dynamorio/blob/e8fc651f485f858127bf2394defc382d5cdff641/ext/drreg/drreg.c#L1912

PR #4932 demonstrates the issue. drreg-test fails:

196: drreg-test running
196: ERROR: spilled flags value was not preserved in test #17!
196: drreg-test finished

Before:

TAG  0x00007fe0ffe9bd67
+0    L3 @0x00007fdebffeefc8  48 c7 c2 17 f1 00 00 mov    $0x000000000000f117 -> %rdx
+7    L3 @0x00007fdebffe1348  48 c7 c2 17 f1 00 00 mov    $0x000000000000f117 -> %rdx
+14   L3 @0x00007fdebff71ec0  b4 d7                mov    $0xd7 -> %ah
+16   L3 @0x00007fdebffdc928  9e                   sahf   %ah
+17   L3 @0x00007fdebff77a90  90                   nop
+18   L3 @0x00007fdebff71120  48 c7 c1 00 00 00 00 mov    $0x0000000000000000 -> %rcx
+25   L3 @0x00007fdebffdd1b0  48 8b 09             mov    (%rcx)[8byte] -> %rcx
+28   L3 @0x00007fdebff74b10  48 c7 c0 34 12 00 00 mov    $0x0000000000001234 -> %rax // rax dead
+35   L3 @0x00007fdebffde9c0  eb 00                jmp    $0x00007fe0ffe9bd8c
END 0x00007fe0ffe9bd67

After:

TAG  0x00007fe0ffe9bd67
+0    L3 @0x00007fdebffeefc8  48 c7 c2 17 f1 00 00 mov    $0x000000000000f117 -> %rdx
+7    L3 @0x00007fdebffe1348  48 c7 c2 17 f1 00 00 mov    $0x000000000000f117 -> %rdx
+14   m4 @0x00007fdebff77178                       <label>
+14   L3 @0x00007fdebff71ec0  b4 d7                mov    $0xd7 -> %ah
+16   L3 @0x00007fdebffdc928  9e                   sahf   %ah
+17   m4 @0x00007fdebffdd7b8  9f                   lahf    -> %ah // aflags spill
+18   m4 @0x00007fdebffea2d0  0f 90 c0             seto    -> %al
+21   m4 @0x00007fdebffdcfb0  48 3b c1             cmp    %rax %rcx // overwrite aflags
+24   L3 @0x00007fdebff77a90  90                   nop
+25   L3 @0x00007fdebff71120  48 c7 c1 00 00 00 00 mov    $0x0000000000000000 -> %rcx
+32   L3 @0x00007fdebffdd1b0  48 8b 09             mov    (%rcx)[8byte] -> %rcx // fault
+35   m4 @0x00007fdebffde940  65 48 a3 e0 00 00 00 mov    %rax -> %gs:0x000000e0[8byte]
                              00 00 00 00
+46   m4 @0x00007fdebffdcec8                       <label>
+46   L3 @0x00007fdebff74b10  48 c7 c0 34 12 00 00 mov    $0x0000000000001234 -> %rax // rax dead so no need to spill xax to slot
+53   m4 @0x00007fdebff763f0  65 48 a3 e8 00 00 00 mov    %rax -> %gs:0x000000e8[8byte]
                              00 00 00 00
+64   m4 @0x00007fdebff76af8                       <label>
+64   m4 @0x00007fdebff77a10  65 48 a1 e0 00 00 00 mov    %gs:0x000000e0[8byte] -> %rax
                              00 00 00 00
+75   m4 @0x00007fdebff53e40  3c 81                cmp    %al $0x81
+77   m4 @0x00007fdebff50a50  9e                   sahf   %ah
+78   m4 @0x00007fdebfff1480  65 48 a1 e8 00 00 00 mov    %gs:0x000000e8[8byte] -> %rax
                              00 00 00 00
+89   m4 @0x00007fdebffefea8                       <label>
+89   L3 @0x00007fdebffde9c0  eb 00                jmp    $0x00007fe0ffe9bd8c
END 0x00007fe0ffe9bd67

As expected, if I remove the mov $0x0000000000001234 -> %rax app instr that's causing rax to be dead, drreg-test passes. This is because then xax is spilled to a slot prior to the lahf.

TAG  0x00007f96f3e6fd67
+0    L3 @0x00007f94b3fb29c0  48 c7 c2 17 f1 00 00 mov    $0x000000000000f117 -> %rdx
+7    L3 @0x00007f94b3f45120  48 c7 c2 17 f1 00 00 mov    $0x000000000000f117 -> %rdx
+14   m4 @0x00007f94b3fb17b8                       <label>
+14   L3 @0x00007f94b3fb11b0  b4 d7                mov    $0xd7 -> %ah
+16   L3 @0x00007f94b3f48b10  9e                   sahf   %ah
+17   m4 @0x00007f94b3fb0ec8  65 48 a3 e8 00 00 00 mov    %rax -> %gs:0x000000e8[8byte] // xax spilled to slot as it's not dead
                              00 00 00 00
+28   m4 @0x00007f94b3f4a3f0                       <label>
+28   m4 @0x00007f94b3f4aaf8  9f                   lahf    -> %ah
+29   m4 @0x00007f94b3f24a50  0f 90 c0             seto    -> %al
+32   m4 @0x00007f94b3f4ba10  48 3b c1             cmp    %rax %rcx
+35   L3 @0x00007f94b3f4b178  90                   nop
+36   L3 @0x00007f94b3fbe2d0  48 c7 c1 00 00 00 00 mov    $0x0000000000000000 -> %rcx
+43   L3 @0x00007f94b3fb0fb0  48 8b 09             mov    (%rcx)[8byte] -> %rcx
+46   m4 @0x00007f94b3f27e40  3c 81                cmp    %al $0x81
+48   m4 @0x00007f94b3fc2fc8  9e                   sahf   %ah
+49   m4 @0x00007f94b3fc5480  65 48 a1 e8 00 00 00 mov    %gs:0x000000e8[8byte] -> %rax
                              00 00 00 00
+60   m4 @0x00007f94b3fc3ea8                       <label>
+60   L3 @0x00007f94b3fb2940  eb 00                jmp    $0x00007f96f3e6fd85
END 0x00007f96f3e6fd67
Assignee
Assign to
Time tracking