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
  • #2351
Closed
Open
Issue created Apr 16, 2017 by Derek Bruening@derekbrueningContributor

drreg eflags restoration is destructive and destroys the value when kept in eax

I split this from #511 because it is interesting and worth documenting and may affect how core DR or other components handle eflags.

In 00d39c73 I changed drreg to keep aflags in eax where possible on x86, something that Dr. Memory was already doing. Thus there's only one spill (zero if eax is dead) and no need to store the app eflags value to memory. We saved the 6 arithmetic flags ("aflags") via the technique developed for DR:

lahf
seto %al

However, when doing this, if we need to restore the app's value to the eflags register, we were again using the technique developed inside DR:

add 0x7f, %al
sahf

The problem is, that add is destructive: it changes al, and that's our only copy of the overflow flag, thus corrupting our saved flags.

This shows up when I add a simple test to drreg-test.dll.c, which reserves and unreserves aflags before every app instr:

            res = drreg_reserve_aflags(drcontext, bb, inst);
            CHECK(res == DRREG_SUCCESS, "reserve of aflags should work");
            res = drreg_unreserve_aflags(drcontext, bb, inst);
            CHECK(res == DRREG_SUCCESS, "unreserve of aflags");

This messes up drreg-test.c (in an interesting way):

$ bin64/drrun -c suite/tests/bin/libclient.drreg-test.dll.so -- suite/tests/bin/client.drreg-test                 
<Starting application /work/dr/git/build_x64_dbg_tests/suite/tests/bin/client.drreg-test (11121)>
FATAL: kernel too old
<Stopping application /work/dr/git/build_x64_dbg_tests/suite/tests/bin/client.drreg-test (11121)>

To solve this there is a better, non-destructive method for restoring the flags, to use a cmp instead of an add:

cmp 0x81, %al
sahf
Assignee
Assign to
Time tracking