This is an archive of the discontinued LLVM Phabricator instance.

[mips][sanitizer_common] Don't use `ld` in internal_clone() on 32-bit MIPS.
ClosedPublic

Authored by dsanders on Apr 4 2016, 5:49 AM.

Details

Summary

On a 32-bit MIPS, the ld instruction does not exist. However, GAS has an ld
macro that expands to a pair of lw instructions which load to a pair of
registers (reg, and reg+1). This macro is not available in the Integrated
Assembler and its use causes -fintegrated-as builds to fail. Even if it were
available, the behaviour on 32-bit MIPS would be incorrect since the current
usage of ld causes the code to clobber $5 (which is supposed to hold
child_stack). It also clobbers $k0 which is reserved for kernel use.

Aside from enabling builds with the integrated assembler, there is no functional
change since internal_clone() is only used by StopTheWorld() which is only used
by 64-bit sanitizers.

Diff Detail

Event Timeline

dsanders updated this revision to Diff 52544.Apr 4 2016, 5:49 AM
dsanders retitled this revision from to [mips][sanitizer_common] Don't use `ld` in internal_clone() on 32-bit MIPS..
dsanders updated this object.
dsanders added a reviewer: kcc.
dsanders added inline comments.Apr 4 2016, 5:58 AM
lib/sanitizer_common/sanitizer_linux.cc
943–947

It's not directly related to this patch but: The comment says 'store' but the instruction is a load from the compiler-generated stack frame.

960–971

It's not directly related to this patch but I also noticed that some of the load instructions are loading from the compiler-generated stack frame ($29 is $sp). This is likely to be sensitive to compiler changes and the offsets are likely to differ between ABI's.

slthakur added inline comments.Apr 5 2016, 1:33 AM
lib/sanitizer_common/sanitizer_linux.cc
943–947

Yes, thanks for catching that, the instruction should have been a store. None of the 32-bit sanitizers use this code as of now but we will still fix it for the sake of completeness.

960–971

Yes. For the 64-bit part the offsets will differ for N32 and N64. We should probably code it like this:

#if _MIPS_SIM == _MIPS_SIM_NABI32
  "lw $25,0($29);\n"
  "lw $4,4($29);\n"
#else
  "ld $25,0($29);\n"
  "ld $4,8($29);\n"
#endif

Thanks again. If this looks good I will submit a patch for fixing these bugs.

dsanders added inline comments.Apr 7 2016, 5:44 AM
lib/sanitizer_common/sanitizer_linux.cc
960–971

It's also sensitive to compiler version and optimizations at the moment. I think it would be better to let the compiler figure out the address by making the relevant variable (fn?) one of the arguments to the inline assembly statement.

Could you confirm that this is ok to commit? I think it probably is based on the comments but I don't have an LGTM yet.

slthakur accepted this revision.May 11 2016, 5:19 AM
slthakur added a reviewer: slthakur.

LGTM

This revision is now accepted and ready to land.May 11 2016, 5:19 AM
dsanders closed this revision.May 12 2016, 7:27 AM