Skip to content

i#1726: Port Umbra to ARM - #2044

Merged
toshipiazza merged 13 commits into
masterfrom
i1726-port-umbra-arm
Oct 28, 2017
Merged

toshipiazza merged 13 commits into
masterfrom
i1726-port-umbra-arm

Conversation

@toshipiazza

Copy link
Copy Markdown
Contributor

Pulls out shadow_table_insert_app_to_shadow() into 2 arch-specific
methods for x86 and for ARM. Also implements this method for ARM.

Issue: #1726

Pulls out shadow_table_insert_app_to_shadow() into 2 arch-specific
methods for x86 and for ARM. Also implements this method for ARM.

Issue: #1726
Comment thread umbra/umbra_x86.c Outdated
disp_hi >>= 0x10;

/* %reg_idx = table */
PRE(ilist, where, INSTR_CREATE_movw(drcontext,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INSTR_CREATE_load_int() does not load 32-bit ints, so I resorted to using movw and movt. Is there a shorthand for this in the repo already? If not, should there be one?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is instrlist_insert_mov_immed_ptrsz()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, forgot about that method. Done.

@toshipiazza

Copy link
Copy Markdown
Contributor Author

Some questions:

  1. Should we split the files up even more? We're basically using all the same code between x86 and ARM, so maybe it's not worth.
  2. Is the new code sequence alright? It looks non-optimal because it requires a second scratch register, but I haven't been able to get it to use a single scratch register.

I think Umbra on x86 and ARM should now be functionally equivalent, but there are no tests in the repo for it; should I add some tests?

@derekbruening

Copy link
Copy Markdown
Contributor

I think Umbra on x86 and ARM should now be functionally equivalent, but there are no tests in the repo for it; should I add some tests?

This is a hole is the test suite: see #1468. We would love to have some tests added.

- Fixes build error/typo in CMakeLists.txt
- Replaces movw/movt sequence with instrlist_insert_mov_immed_ptrsz()
@toshipiazza

Copy link
Copy Markdown
Contributor Author

I'll add some tests in with this CL then.

@derekbruening derekbruening left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we split the files up even more? We're basically using all the same code between x86 and ARM, so maybe it's not worth.

If we did split I would suggest renaming umbra_x86.c to umbra_32bit.c (or just umbra_32.c?) and having umbra_x86.c and umbra_arm.c contain the differing code. It does seem weird to have ARM use a file named "umbra_x86.c". We could rename that file and not add any others (keeping the ifdef inside it for that one routine)?

Is the new code sequence alright? It looks non-optimal because it requires a second scratch register, but I haven't been able to get it to use a single scratch register.

I put a suggestion that I think gets rid of the 2nd scratch.

Comment thread umbra/umbra_x86.c Outdated
reg_id_t reg_addr, reg_id_t *regs)
{
reg_id_t reg_idx = regs[0];
reg_id_t reg_tmp = regs[1];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this just looks risky: maybe pass in "int num_scratch_regs" and assert on it or sthg. At least a comment next to the regs (I like scratch_regs better) param.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we can do this with 1 reg, the array is no longer passed in.

Comment thread umbra/umbra_x86.c Outdated
#ifdef X86
shadow_table_insert_app_to_shadow_arch(void *drcontext, umbra_map_t *map,
instrlist_t *ilist, instr_t *where,
reg_id_t reg_addr, reg_id_t *regs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/regs/scratch_regs/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we can do this with 1 reg, the array is no longer passed in.

Comment thread umbra/umbra_x86.c Outdated
/* code sequence:
* %reg_idx = table
* %reg_tmp = (%reg_addr >> 0x10)
* %reg_idx += (%reg_tmp << 0x02)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could get rid of reg_tmp by adding (%reg_addr >> 14) here and then zeroing the bottom 2 bits, right?

@toshipiazza toshipiazza Sep 22, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the delay. I think this would only work if the static table already has the bottom 2 bits cleared:

reg_idx  =  0x41414141
reg_idx += (reg_addr >> 14)
reg_idx &= 0xfffffffc

If we simply clear the last two bits of reg_idx, we might overwrite the bottom 2 bits of the address of the shadow table. I guess it's ok to assume that the static table is 4 byte aligned though, so maybe this is fine.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated: there's a confusing variable called static_shadow_table_is_used which is statically set to false, though really the variable should be named static_shadow_table_unused or sthg. Can update this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah that seems to never be written to?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup looks like it's only being used once to determine whether to allocate the shadow table using nonheap_alloc() (if static_shadow_table_is_used is true), but uses the static shadow table if static_shadow_table_is_used is false, hence the confusion.

- Reduces number of regs required for Umbra on ARM
- Renames umbra_x86 to umbra_32, and umbra_x64 to umbra_64
@derekbruening

Copy link
Copy Markdown
Contributor

I think most of the failures are the same ones that hit DR when Travis updated their VM image about 2 weeks ago: DynamoRIO/dynamorio#2632, DynamoRIO/dynamorio#2634, DynamoRIO/dynamorio#2641

I fixed the first two but am still working on the last one: if anyone can reproduce it locally that would help a great deal as it is slow going trying to diagnose through just what I can print out on Travis.

Xref #2050 where @mxmssh is also hitting failures and about to update DR and I think hitting some further warnings from the clang upgrade.

@@ -1,4 +1,4 @@
#!/bin/sh

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my box, /bin/sh -> /bin/dash, and I believe that this script uses a bash-ism. Not sure why I only saw this recently though. Should I change this back?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making it bash seems fine: we did the same thing with git_review.sh

# a function scope, we must set the global vars ahead of time:
configure_DynamoRIO_global(OFF ON)

# We save pdb+dll space by not using libc (xref DRi#714).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umbra pulls in libc, so we can't do this anymore.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, as of dddcfc6 right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That one may have unnecessarily changed Windows too. If I re-instate set(DynamoRIO_USE_LIBC OFF) today and build umbra it builds fine and there are no unusual imports. Missing symbols at runtime are usually a UNIX thing for ELF and !LD_BIND_NOW: on Windows the linker complains at link time.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, should I file an issue and fix in a later CL? Or should I just fix it in this CL (i.e. revert effects of dddcfc6 only for Windows)

@toshipiazza

Copy link
Copy Markdown
Contributor Author

I only added 2 tests, one of which tests umbra_{read,write}_shadow_memory(). I'd also like to test umbra_insert_app_to_shadow() (of course). How would I go about doing this? It was mentioned here that "DrMem detects whether [a pointer from the page table points to] a special block and replaces it with a writable block at that time," but does DrMem do this in a fault handler, or is the only logic for this in umbra_{read,write}_shadow_memory()?

@@ -1,4 +1,4 @@
#!/bin/sh

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making it bash seems fine: we did the same thing with git_review.sh

# a function scope, we must set the global vars ahead of time:
configure_DynamoRIO_global(OFF ON)

# We save pdb+dll space by not using libc (xref DRi#714).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows too?

Comment thread tests/framework/umbra_app.c Outdated
PUSH_SEH(REG_XDI)
sub REG_XSP, FRAME_PADDING /* align */
mov REG_XBP, REG_XSP
sub REG_XSP, 4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operand alignment looks off here and on the line above. The style guide says "place opcodes on column 8 and start operands on column 17" -- hard to tell from this view which one of lines 78 and 79 is correct.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Looks like this was a tabs vs spaces confusion issue.

Comment thread tests/framework/umbra_app.c Outdated
test1:
mov REG_XDI, UMBRA_TEST_1_ASM
mov REG_XDI, UMBRA_TEST_1_ASM
mov [REG_XBP], REG_XDI

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alignment again

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread tests/framework/umbra_app.c Outdated
test2:
mov REG_XDI, UMBRA_TEST_2_ASM
mov REG_XDI, UMBRA_TEST_2_ASM
mov REG_XDI, [REG_XBP]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alignment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread tests/framework/umbra_app.c Outdated
jmp epilog

epilog:
mov REG_XSP, REG_XBP

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alignment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@derekbruening

Copy link
Copy Markdown
Contributor

I only added 2 tests, one of which tests umbra_{read,write}shadow_memory(). I'd also like to test umbra_insert_app_to_shadow() (of course). How would I go about doing this? It was mentioned here that "DrMem detects whether [a pointer from the page table points to] a special block and replaces it with a writable block at that time," but does DrMem do this in a fault handler, or is the only logic for this in umbra{read,write}_shadow_memory()?

For inlined instrumentation, it is a fault handler: e.g., https://github.com/DynamoRIO/drmemory/blob/master/drmemory/fastpath.c#L350. For C code it's sthg like this https://github.com/DynamoRIO/drmemory/blob/master/drmemory/shadow.c#L482

@toshipiazza

Copy link
Copy Markdown
Contributor Author

For inlined instrumentation, it is a fault handler: e.g., https://github.com/DynamoRIO/drmemory/blob/master/drmemory/fastpath.c#L350. For C code it's sthg like this https://github.com/DynamoRIO/drmemory/blob/master/drmemory/shadow.c#L482

Noted. Is there a reason 64-bit Umbra abstracts away the fault handler (i.e. the fault handler appears in umbra_64.c), but 32-bit Umbra does not? Is it due to poor interaction with DrMemory?

@derekbruening

Copy link
Copy Markdown
Contributor

For inlined instrumentation, it is a fault handler: e.g., https://github.com/DynamoRIO/drmemory/blob/master/drmemory/fastpath.c#L350. For C code it's sthg like this https://github.com/DynamoRIO/drmemory/blob/master/drmemory/shadow.c#L482

Noted. Is there a reason 64-bit Umbra abstracts away the fault handler (i.e. the fault handler appears in umbra_64.c), but 32-bit Umbra does not? Is it due to poor interaction with DrMemory?

I don't think there's a good reason: it may just be historical, that DrM has a fault handler there for other reasons. Paging @zhaoqin who wrote umbra -- is there a reason?

- (Hopefully) fixes Windows cmake build error
- Fixes whitespace errors in umbra_app.c
- Re-adds building without libc on Windows
- tests umbra_insert_app_to_shadow()
- tests consistency between umbra_insert_app_to_shadow() and
  umbra_get_shadow_memory()
@toshipiazza

Copy link
Copy Markdown
Contributor Author

The travis Mac build seems to be erroring out with the following message:

/usr/local/Homebrew/Library/Homebrew/brew.rb:12:in `<main>': Homebrew must be run under Ruby 2.3! You're running 2.0.0. (RuntimeError)

@derekbruening

Copy link
Copy Markdown
Contributor

The travis Mac build seems to be erroring out with the following message:

/usr/local/Homebrew/Library/Homebrew/brew.rb:12:in `<main>': Homebrew must be run under Ruby 2.3! You're running 2.0.0. (RuntimeError)

DR hit this last week and I was hoping Travis would fix it by now. Searching shows this Travis issue which lists some workarounds (didn't read it all yet):
travis-ci/travis-ci#8552

@derekbruening

Copy link
Copy Markdown
Contributor

Thanks for trying this here, I'm doing the same thing for DR: DynamoRIO/dynamorio#2672

@toshipiazza

Copy link
Copy Markdown
Contributor Author

Is this ready for merge? Were the last few tests I added reviewed?

@derekbruening derekbruening left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests look good to me. Thanks for adding them!

@toshipiazza
toshipiazza merged commit 3c0c21e into master Oct 28, 2017
@toshipiazza
toshipiazza deleted the i1726-port-umbra-arm branch October 28, 2017 04:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants