Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[drcachesim] Provide branch target for branch just prior to signal delivery #4274

Closed
derekbruening opened this issue Apr 22, 2020 · 4 comments · Fixed by #4994
Closed

[drcachesim] Provide branch target for branch just prior to signal delivery #4274

derekbruening opened this issue Apr 22, 2020 · 4 comments · Fixed by #4994
Assignees

Comments

@derekbruening
Copy link
Contributor

For #2638 we aided core simulation of drcachesim traces by guaranteeing that a branch's target immediately followed it and would not be interrupted by a thread switch.

But then in #3937 we allowed a signal to arrive after a branch, and removed the branch target guarantee for that case.

This issue covers addressing that lack of guarantee. DR did execute that branch,
and after the signal it will go to the branch target rather than re-execute
the branch instruction. Yet the core simulator doesn't know the branch
target, especially for an indirect branch. It seems like we should figure out
a solution here. Previously we discarded the idea of explicitly storing the
branch target. Maybe we could insert the branch target as an instruction fetch
entry that gets interrupted and re-executed post-signal (easiest to do this in
the tracer as the post-processor will have a hard time finding the target, just
like a core simulator).

@derekbruening
Copy link
Contributor Author

To get the ind br target: we'd have to augment dr_kernel_xfer_info_t?

@derekbruening derekbruening self-assigned this Jun 22, 2021
@derekbruening
Copy link
Contributor Author

It looks like the current info passed to the kernel xfer event does have
what we want, including indirect branch targets:

$ ctest -V -R histogram.offline
$ ninja && bin64/drrun -t drcachesim -indir suite/tests/tool.histogram.offline.drmemtrace.signal_invariants.2558442.0550.dir -simulator_type view 2>&1 | less

  0x00007f59e9bcfadb  0f 0b                ud2a
<marker: kernel xfer to handler>
<marker: kernel interrupted pc 0x7f59e9bcfadb>
<marker: timestamp 13268857302478344>
<marker: tid 2558442 on core 3>
  0x00007f59e9bcfac4  0f 18 0c 25 01 00 00 prefetcht0 0x01
                      00
  0x00007f59e9bcfacc  e9 8c fc ff ff       jmp    $0x00007f59e9bcf75d


  0x00007f59ed638725  5d                   pop    %rbp
  0x00007f59ed638726  c3                   ret
<marker: kernel xfer to handler>
<marker: kernel interrupted pc 0x7f59e9bcfa13>
<marker: timestamp 13268857302643640>
<marker: tid 2558442 on core 3>
  0x00007f59e9bcfac4  0f 18 0c 25 01 00 00 prefetcht0 0x01
                      00
  0x00007f59e9bcfacc  e9 8c fc ff ff       jmp    $0x00007f59e9bcf75d
  0x00007f59e9bcf75d  55                   push   %rbp
  0x00007f59e9bcf75e  48 89 e5             mov    %rsp, %rbp
  0x00007f59e9bcf761  48 83 ec 40          sub    $0x40, %rsp
  0x00007f59e9bcf765  89 7d dc             mov    %edi, -0x24(%rbp)
  0x00007f59e9bcf768  48 89 75 d0          mov    %rsi, -0x30(%rbp)
  0x00007f59e9bcf76c  48 89 55 c8          mov    %rdx, -0x38(%rbp)
  0x00007f59e9bcf770  83 7d dc 0b          cmp    -0x24(%rbp), $0x0b
  0x00007f59e9bcf774  74 2f                jz     $0x00007f59e9bcf7a5
  0x00007f59e9bcf776  83 7d dc 0b          cmp    -0x24(%rbp), $0x0b
  0x00007f59e9bcf77a  7f 77                jnle   $0x00007f59e9bcf7f3
  0x00007f59e9bcf77c  83 7d dc 04          cmp    -0x24(%rbp), $0x04
  0x00007f59e9bcf780  74 60                jz     $0x00007f59e9bcf7e2
  0x00007f59e9bcf782  83 7d dc 0a          cmp    -0x24(%rbp), $0x0a
  0x00007f59e9bcf786  75 6b                jnz    $0x00007f59e9bcf7f3
  0x00007f59e9bcf788  48 8b 45 c8          mov    -0x38(%rbp), %rax
  0x00007f59e9bcf78c  48 83 c0 28          add    $0x28, %rax
  0x00007f59e9bcf790  48 89 45 f0          mov    %rax, -0x10(%rbp)
  0x00007f59e9bcf794  48 8b 45 f0          mov    -0x10(%rbp), %rax
  0x00007f59e9bcf798  48 8b 80 80 00 00 00 mov    0x80(%rax), %rax
  0x00007f59e9bcf79f  48 89 45 e8          mov    %rax, -0x18(%rbp)
  0x00007f59e9bcf7a3  eb 6d                jmp    $0x00007f59e9bcf812
  0x00007f59e9bcf812  90                   nop
  0x00007f59e9bcf813  c9                   leave
  0x00007f59e9bcf814  c3                   ret
  0x00007f59ed643140  48 c7 c0 0f 00 00 00 mov    $0x0000000f, %rax
  0x00007f59ed643147  0f 05                syscall
<marker: timestamp 13268857302643649>
<marker: tid 2558442 on core 3>
<marker: syscall xfer>
<marker: timestamp 13268857302649042>
<marker: tid 2558444 on core 1>
  0x00007f59ed5360d7  c3                   ret
  0x00007f59e9bcf82f  be 0a 00 00 00       mov    $0x0000000a, %esi
  0x00007f59e9bcf834  89 c7                mov    %eax, %edi
  0x00007f59e9bcf836  e8 c5 f8 ff ff       call   $0x00007f59e9bcf100
  0x00007f59e9bcf100  ff 25 7a 3f 00 00    jmp    <rel> 0x00007f59e9bd3080
  0x00007f59ed4a6080  b8 3e 00 00 00       mov    $0x0000003e, %eax
  0x00007f59ed4a6085  0f 05                syscall
<marker: timestamp 13268857302650069>
<marker: tid 2558442 on core 1>
  0x00007f59e9bcfa13  85 c0                test   %eax, %eax
  0x00007f59e9bcfa15  74 25                jz     $0x00007f59e9bcfa3c

@derekbruening
Copy link
Contributor Author

I was worried about a signal causing an rseq abort -- will int pc have the abort handler instead of the original interrupted pc? But it seems this has already been dealt with by #4041:

        /* i#4041: Provide the actually-interrupted mid-rseq PC to this event. */

derekbruening added a commit that referenced this issue Jun 28, 2021
Adds source context information to the kernel xfer event for rseq
aborts, which was previously missing.  To provide the interrupted rseq
abort PC as the PC of the final committing store, adds logic inside DR
to record that PC when it is discovered during block creation.

Updates the rseq test to check the new information.

Issue: #4274
derekbruening added a commit that referenced this issue Jun 28, 2021
Adds source context information to the kernel xfer event for rseq
aborts, which was previously missing.  To provide the interrupted rseq
abort PC as the PC of the final committing store, adds logic inside DR
to record that PC when it is discovered during block creation.

Updates the rseq test to check the new information.

Issue: #4274
derekbruening added a commit that referenced this issue Jun 30, 2021
The version number in a drmemtrace trace is currently hidden in a
header that the reader hides from analysis tools.  Here we add a new
marker type that exports the version number so that analysis tools can
handle legacy traces.

Adds version awareness to the view tool.

Tested by manually running the view tool:
  $ bin64/drrun -t drcachesim -verbose 3 -- suite/tests/bin/allasm_repstr
  ::4152878.4152878:: marker type 12 value 2
  ::4152878.4152878:: marker type 9 value 64
  ::4152878.4152878:: marker type 10 value 64
  ...
  $ bin64/drrun -t drcachesim -offline -- suite/tests/bin/allasm_repstr
  $ bin64/drrun -t drcachesim -simulator_type view -indir drmemtrace.allasm_repstr.*.dir
  <marker: version 2>
  <marker: filetype 40>
  <marker: cache line size 64>
  <marker: timestamp 13269494545173426>
  <marker: tid 4152931 on core 2>
    0x0000000000401000  48 83 e4 f0          and    $0xf0, %rsp
  ...

Issue: #4274
derekbruening added a commit that referenced this issue Jun 30, 2021
The version number in a drmemtrace trace is currently hidden in a
header that the reader hides from analysis tools.  Here we add a new
marker type that exports the version number so that analysis tools can
handle legacy traces.

Adds version awareness to the view tool.

Tested by manually running the view tool:
  $ bin64/drrun -t drcachesim -verbose 3 -- suite/tests/bin/allasm_repstr
  ::4152878.4152878:: marker type 12 value 2
  ::4152878.4152878:: marker type 9 value 64
  ::4152878.4152878:: marker type 10 value 64
  ...
  $ bin64/drrun -t drcachesim -offline -- suite/tests/bin/allasm_repstr
  $ bin64/drrun -t drcachesim -simulator_type view -indir drmemtrace.allasm_repstr.*.dir
  <marker: version 2>
  <marker: filetype 40>
  <marker: cache line size 64>
  <marker: timestamp 13269494545173426>
  <marker: tid 4152931 on core 2>
    0x0000000000401000  48 83 e4 f0          and    $0xf0, %rsp
  ...

Issue: #4274
derekbruening added a commit that referenced this issue Jul 2, 2021
For online traces, adds the interrupted PC to kernel event entries.

For offline traces, updates the existing module offset stored inside
kernel events (and previously used only for raw2trace) to become an
absolute PC to help in core simulators and other trace consumers who
want to know branch targets prior to kernel events.

This is a version change for offline traces, and the version is
updated, with a named constant for the old version.

The raw offline's module offset is upgraded to become an index;offset
pair, as that format is better suited for raw2trace and it avoids
needing an extra entry nearly all of the time.  The raw2trace
postprocessing converts it to an absolute PC for the final trace.
Since the 49 bits can take two raw entries, raw2trace is augmented to
handle unreading such a double entry.

Adds a new TRACE_MARKER_TYPE_RSEQ_ABORT marker to further identify an
rseq abort, in order to roll back the committing store in raw2trace
(previously it used the lack of interrupted-PC to identify an rseq
abort).

Adds support to the view tool for displaying the interrupted PC
depending on the version.

Updates the drcachesim documentation with the new output of the
interrupted PC from the view tool.

Fixes an issue in the reader where the first switch to a thread has
the prior thread's identity in the two leading marker entries for
version and filetype.

Adds tests of the interrupted PC to the trace_invariants test for
signals, as well as ensuring that raw2trace has rolled back an rseq
abort final instruction so that the abort appears to occur at a
legitimate place inside the region.

Adds a test of the legacy version with just offsets by checking in raw
files from a signal_invariants run, with fake libdrmemtrace.so and
lidynamorio.so to keep the size down.

Fixes #4274
derekbruening added a commit that referenced this issue Jul 8, 2021
…ts (#4994)

For online traces, adds the interrupted PC to kernel event entries.

For offline traces, updates the existing module offset stored inside
kernel events (and previously used only for raw2trace) to become an
absolute PC to help in core simulators and other trace consumers who
want to know branch targets prior to kernel events.

This is a version change for offline traces, and the version is
updated, with a named constant for the old version.

The raw offline's module offset is upgraded to become an index;offset
pair (for 64-bit), as that format is better suited for raw2trace and it avoids
needing an extra entry nearly all of the time.  The raw2trace
postprocessing converts it to an absolute PC for the final trace.
Since the 49 bits can take two raw entries, raw2trace is augmented to
handle unreading such a double entry.

Adds a new TRACE_MARKER_TYPE_RSEQ_ABORT marker to further identify an
rseq abort, in order to roll back the committing store in raw2trace
(previously it used the lack of interrupted-PC to identify an rseq
abort).

Adds support to the view tool for displaying the interrupted PC
depending on the version.

Updates the drcachesim documentation with the new output of the
interrupted PC from the view tool.

Fixes an issue in the reader where the first switch to a thread has
the prior thread's identity in the two leading marker entries for
version and filetype.

Adds tests of the interrupted PC to the trace_invariants test for
signals, as well as ensuring that raw2trace has rolled back an rseq
abort final instruction so that the abort appears to occur at a
legitimate place inside the region.

Adds a test of the legacy version with just offsets by checking in raw
files from a signal_invariants run, with fake libdrmemtrace.so and
lidynamorio.so to keep the size down.

Fixes #4274
@derekbruening
Copy link
Contributor Author

A final task here is to regenerate the traces in DynamoRIO/drmemtrace_samples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant