-
Notifications
You must be signed in to change notification settings - Fork 262
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
i#2016: Port the umbra_64.c class to work on aarch64 #2404
Conversation
This is a subsection of the larger ongoing aarch64 port of DRMemory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR! Nice to see support for AARCH64.
I think it is best that we have some tests just to ensure all is working, and avoid regression.
umbra/umbra_64.c
Outdated
@@ -354,6 +358,37 @@ static ptr_uint_t map_disp_win81[] = { | |||
* We check conflicts later when creating shadow memory. | |||
*/ | |||
#ifdef LINUX | |||
#ifdef AARCH64 | |||
static const app_segment_t app_segments_initial[] = { | |||
/* We split app3 [0x7F0000000000, 0x800000000000) into two parts: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that a big chunk of this comment block was copied from that below. Consider condensing to avoid duplicate text, as future updates would then require double changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed comment.
umbra/umbra_64.c
Outdated
@@ -839,7 +875,7 @@ umbra_map_arch_init(umbra_map_t *map, umbra_map_options_t *ops) | |||
ASSERT(map->shadow_block_size >= ALLOC_UNIT_SIZE && | |||
map->app_block_size >= ALLOC_UNIT_SIZE, | |||
"block size too small"); | |||
map->mask = segment_mask(num_seg_bits) | seg_index_mask(num_seg_bits); | |||
map->mask = IF_AARCH64_ELSE(0xfffffffffffffffc, segment_mask(num_seg_bits) | seg_index_mask(num_seg_bits)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Avoid magic values in code as this hinders readability.
- Is it possible to have segment_mask() return the mask, rather than have the IF_AARCH64_ELSE macro here?
- Finally, add a comment on how this mask was derived.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have now made these changes.
I was hoping the fact that the existing umbra tests pass with the full port, might suffice. But we could add more specific tests. |
@derekbruening Does Dr. Memory's CI run tests for AArch64? IIRC, they used to run prior to the switch to Github Actions? |
If I recall correctly prior to this body of work DRMemory didn't even compile on AArch64. It only had 32 bit arm support. However this might have changed since I started working on it, or perhaps I misunderstood. |
Sorry, I meant 32-bit ARM. What we need now is to run AArch64 umbra tests. |
On Travis there was a 32-bit ARM cross-compile job, but no execution. What should be done is to add both a32 and a64 QEMU runs (at least some simple tests are likely to run on QEMU given that they do for plain DR) and maybe reuse the DR Jenkins machine and setup to run a64 tests as support is added. |
I see... Okay, so in that case, unfortunately we will punt test for this PR. @derekbruening Is there an issue page regarding the above? I couldn't find it. |
@gregcawthorne No rush, just let me know when ready for me to take another look at the PR. |
Probably not yet in the DrM tracker: the DR QEMU issue is DynamoRIO/dynamorio#4719 |
I have made the changes you have suggested, but haven't added a new test. I am currently unsure of the ci-windows/vs2017-32 build failure in CI. |
umbra/umbra_64.c
Outdated
@@ -354,6 +363,18 @@ static ptr_uint_t map_disp_win81[] = { | |||
* We check conflicts later when creating shadow memory. | |||
*/ | |||
#ifdef LINUX | |||
#ifdef AARCH64 | |||
static const app_segment_t app_segments_initial[] = { | |||
{(app_pc)0x0000ff0000000000, (app_pc)0x0001000000000000, 0}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just having another look, and I don't understand why the layout needs to be different from the existing one. Can you explain, or provide a reference, regarding how you defined this app segment layout please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay I will review this section and get back to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay so I when you start up DRMemory does a scan of all the current memory blocks. I am pretty sure I simply looked at the default ones I was getting every time on my taishan AArch64 system and copied them in.
@gregcawthorne Thank you for the changes. Yes, we will skip tests due to limitations of the CI, but I am assuming you tried the code locally, and all works fine, right? |
@gregcawthorne Ignore the failure on the Windows machine. It failed due to a known flaky test (ref: #2361) |
umbra/umbra_64.c
Outdated
} | ||
instru_insert_mov_pc(drcontext, ilist, where, opnd_create_reg(tmp), | ||
OPND_CREATE_INT64(map->mask)); | ||
PRE(ilist, where, INSTR_CREATE_and(drcontext, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you place the and
instruction last here, in contrast to the existing code below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I have done:
add => shift => and
rather than the existing:
and => add => shift
My understanding is that the purpose of the mapping is to shift and scale into some other distinct space range with the correct scale. The order of operations doesn't matter too much as long as 'a' mapping was achieved.
AArch64 doesn't use the same segmentation scheme as x86 as far as I know.
Therefore I am using the mask variable to simply mask off the lower 2 bits of the address in order to secure a valid address (as commented), and this makes sense to be done as the final operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes I have done:
add => shift => andrather than the existing:
and => add => shiftMy understanding is that the purpose of the mapping is to shift and scale into some other distinct space range with the correct scale. The order of operations doesn't matter too much as long as 'a' mapping was achieved.
I think it can make a difference. The and
is used to mask the address, the add
is used to include a displacement value to reach a shadow region, and the shift
is intended for scaling. While it may not make a difference in some cases, having the and
last might clear information injected earlier by the displacement/scaling if we make future changes.
In any case, it is much better to have the same code sequence as other platforms if possible, as otherwise it appears we are doing something special and potentially arises confusion.
AArch64 doesn't use the same segmentation scheme as x86 as far as I know.
Therefore I am using the mask variable to simply mask off the lower 2 bits of the address in order to secure a valid address (as commented), and this makes sense to be done as the final operation.
The mask and displacement values are critically set up in order to have shadow memory regions not collide with app regions. These values were carefully crafted, and some recently generated with the help of automated tools (https://github.com/DynamoRIO/drmemory/blob/master/tools/umbra_layout.py).
Maybe I am missing something, but I still don't understand why we can't use the existing segment mapping for Linux?
Hi guys. Just giving this a nudge. |
Hey thanks for the nudge. I was under the impression that I am still awaiting my above comments to be addressed. Particularly: #2404 (comment) |
Yes I will address that. I was thinking too sequentially. |
Sure, no problem! Thank you. I added another comment (#2404 (comment)) relating to the above. |
Hi. Sorry for my lateness on this, was out for a week and also missed the notifications. I took onboard what you have said and have reverted the behaviour you were questioning (different initial segment map + incorrect order of the and/add/shift) and re ran the tests we have ported and we are getting the same tests passing/failing. I will chalk this up to my early brash guess work when I first started orienting myself. Thank you! |
I can't see currently how my changes could necessarily break x86 on only osx. |
@gregcawthorne You're right. The failure doesn't concern your code; it concerns this issue: #2379 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had another look. Seems like we are progressing well.
Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these are the final comments and once they are fixed, we will be very close to merging. Thank you.
Okay, do you guys have any preferences of which part of the larger initial aarch64 port would be 'best' to upstream next? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you!
Not really, just try to keep the PRs as small as possible to facilitate reviewing! It would be great if we consider adding the testing architecture for aarch64 before adding more code.(See: #2404 (comment)). If you can help with this, it would be really appreciated (but I understand if you are busy). |
@gregcawthorne Merged! Thanks again for the PR! |
Hi John, I can add any changes I have made to the tests next sure. The port actually depends on dynamorio patch I have which is to add the ability to use memory references as arguments in clean calls. I will work to get that upstreamed too. |
Okay, no problem. Feel free to request me as a reviewer for the DR patch if you wish. |
Enables shadow memory tracking on AArch64.
This is a subsection of the larger ongoing AArch64 port of DRMemory.
Issue: #2016