[PATCH] D54154: [ELF][MIPS] Use MIPS R6 `sigrie` as a trap instruction
James Clarke via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 6 15:38:13 PST 2018
jrtc27 added a comment.
In https://reviews.llvm.org/D54154#1289551, @ruiu wrote:
> Yeah, we could alternatively represent a trap instruction as an ArrayRef<uint8_t> which can vary in size, but that's somewhat minor point, and I believe always writing 4 bytes using memcpy is much faster than copying ArrayRef contents because the former can be highly optimized by a compiler that can inline memcpy function.
Yeah, I considered that as a possibility, but it doesn't seem worth it. Your `uint8_t[4]` proposal seems like the best option overall to me, and can always be revisited if it turns out to be a problem (I don't suppose we'll be seeing an IA-64 backend needing 16 bytes for its instruction!).
================
Comment at: ELF/Arch/Mips.cpp:61
+ // Set `sigrie 1` as a trap instruction.
+ if (Config->IsLE == sys::IsLittleEndianHost)
+ write32le(&TrapInstr, 0x04170001);
----------------
jrtc27 wrote:
> atanasyan wrote:
> > jrtc27 wrote:
> > > Maybe I'm being stupid, but won't this do the wrong thing on a big-endian host? If, say, we're building for mips64 on mips64, `Config->IsLE` and `sys::IsLittleEndianHost` will both be false, so we'll take the `write32le` path, which will write `0x04170001` (represented in-memory natively as big-endian) as a little-endian value, i.e. incorrectly byte-swapping? It seems to me like this should be just a check for `if (Config->IsLE)`?
> > Thanks a lot. The only remaining question - how could I write this nice piece of code? :)
> I went and verified this because, despite having many dealings with it, it's too easy to get confused about endianness-related code. So, yes, my belief was correct, and I didn't inadvertently mislead you :) Running on powerpc64-linux-gnu:
>
> ```
> -- Testing: 1 tests, 1 threads --
> FAIL: lld :: ELF/mips-got16-relocatable.s (1 of 1)
> ******************** TEST 'lld :: ELF/mips-got16-relocatable.s' FAILED ********************
> Script:
> --
> : 'RUN: at line 5'; /home/jrtc27/src/llvm/Build/bin/llvm-mc -filetype=obj -triple=mips-unknown-linux -mcpu=mips32r6 -o /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp.o /home/jrtc27/src/llvm/llvm/tools/lld/test/ELF/mips-got16-relocatable.s
> : 'RUN: at line 6'; /home/jrtc27/src/llvm/Build/bin/ld.lld -r -o /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp.o /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp.o
> : 'RUN: at line 7'; /home/jrtc27/src/llvm/Build/bin/llvm-objdump -d -r /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp | /home/jrtc27/src/llvm/Build/bin/FileCheck -check-prefix=OBJ /home/jrtc27/src/llvm/llvm/tools/lld/test/ELF/mips-got16-relocatable.s
> : 'RUN: at line 8'; /home/jrtc27/src/llvm/Build/bin/ld.lld -shared -o /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp.so /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp
> : 'RUN: at line 9'; /home/jrtc27/src/llvm/Build/bin/llvm-objdump -d /home/jrtc27/src/llvm/Build/tools/lld/test/ELF/Output/mips-got16-relocatable.s.tmp.so | /home/jrtc27/src/llvm/Build/bin/FileCheck -check-prefix=SO /home/jrtc27/src/llvm/llvm/tools/lld/test/ELF/mips-got16-relocatable.s
> --
> Exit Code: 1
>
> Command Output (stderr):
> --
> /home/jrtc27/src/llvm/llvm/tools/lld/test/ELF/mips-got16-relocatable.s:17:13: error: OBJ-NEXT: expected string not found in input
> # OBJ-NEXT: 8: 04 17 00 01 sigrie 1
> ^
> <stdin>:10:2: note: scanning from here
> 8: 01 00 17 04 <unknown>
> ^
>
> --
>
> ********************
> Testing Time: 0.22s
> ********************
> Failing Tests (1):
> lld :: ELF/mips-got16-relocatable.s
>
> Unexpected Failures: 1
> ```
... and finally if I change this line to just `if (Config->IsLE)` it does indeed pass as expected on powerpc64-linux-gnu, so LGTM from my (unimportant) point of view once that's fixed. Alternatively you could use your `Config->IsLE == sys::IsLittleEndianHost` check, but explicitly do the byte swapping when they don't match (i.e. your `write32le` becomes the identity, and `write32be` becomes a byte swap, but both inlined and constant propagated), like the PPC64 target.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D54154
More information about the llvm-commits
mailing list