* rseq/arm32: choosing rseq code signature @ 2019-04-09 19:32 Mathieu Desnoyers 2019-04-10 20:29 ` Mathieu Desnoyers 2019-04-11 12:24 ` Florian Weimer 0 siblings, 2 replies; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-09 19:32 UTC (permalink / raw) To: Will Deacon; +Cc: libc-alpha, linux-kernel, Carlos O'Donell Hi Will, We are about to include the code signature required prior to restartable sequences abort handlers into glibc, which will make this ABI choice final. We need architecture maintainer input on that signature value. That code signature is placed before each abort handler, so the kernel can validate that it is indeed jumping to an abort handler (and not some arbitrary attacker-chosen code). The signature is never executed. The current discussion thread on the glibc mailing list leads us towards using a trap with uncommon immediate operand, which simplifies integration with disassemblers, emulators, makes it easier to debug if the control flow gets redirected there by mistake, and is nicer for some architecture's speculative execution. We can have different signatures for each sub-architecture, as long as they don't have to co-exist within the same process. We can special-case with #ifdef for each sub-architecture and endianness if need be. If the architecture has instruction set extensions that can co-exist with the architecture instruction set within the same process (e.g. thumb for arm), we need to take into account to which instruction the chosen signature value would map (and possibly decide if we need to extend rseq to support many signatures). Here is an example of rseq signature definition template: /* * TODO: document trap instruction objdump output on each sub-architecture * instruction sets, as well as instruction set extensions. */ #define RSEQ_SIG 0x######## Ideally we'd need a patch on top of the Linux kernel tools/testing/selftests/rseq/rseq-arm.h file that updates the signature value, so I can then pick it up for the glibc patchset. Thanks! Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-09 19:32 rseq/arm32: choosing rseq code signature Mathieu Desnoyers @ 2019-04-10 20:29 ` Mathieu Desnoyers 2019-04-11 16:42 ` Will Deacon 2019-04-11 12:24 ` Florian Weimer 1 sibling, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-10 20:29 UTC (permalink / raw) To: Will Deacon; +Cc: libc-alpha, linux-kernel, carlos ----- On Apr 9, 2019, at 3:32 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > Hi Will, > > We are about to include the code signature required prior to restartable > sequences abort handlers into glibc, which will make this ABI choice final. > We need architecture maintainer input on that signature value. > > That code signature is placed before each abort handler, so the kernel can > validate that it is indeed jumping to an abort handler (and not some > arbitrary attacker-chosen code). The signature is never executed. > > The current discussion thread on the glibc mailing list leads us towards > using a trap with uncommon immediate operand, which simplifies integration > with disassemblers, emulators, makes it easier to debug if the control > flow gets redirected there by mistake, and is nicer for some architecture's > speculative execution. > > We can have different signatures for each sub-architecture, as long as they > don't have to co-exist within the same process. We can special-case with > #ifdef for each sub-architecture and endianness if need be. If the architecture > has instruction set extensions that can co-exist with the architecture > instruction set within the same process (e.g. thumb for arm), we need to take > into account to which instruction the chosen signature value would map (and > possibly decide if we need to extend rseq to support many signatures). > > Here is an example of rseq signature definition template: > > /* > * TODO: document trap instruction objdump output on each sub-architecture > * instruction sets, as well as instruction set extensions. > */ > #define RSEQ_SIG 0x######## > > Ideally we'd need a patch on top of the Linux kernel > tools/testing/selftests/rseq/rseq-arm.h file that updates > the signature value, so I can then pick it up for the glibc > patchset. Would the following diff work for you ? If so, can I get your acked-by ? diff --git a/tools/testing/selftests/rseq/rseq-arm.h b/tools/testing/selftests/rseq/rseq-arm.h index 5f262c54364f..1f261ad2ac1b 100644 --- a/tools/testing/selftests/rseq/rseq-arm.h +++ b/tools/testing/selftests/rseq/rseq-arm.h @@ -5,7 +5,17 @@ * (C) Copyright 2016-2018 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> */ -#define RSEQ_SIG 0x53053053 +/* + * RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand + * value 0x5305. This traps if user-space reaches this instruction by mistake, + * and the uncommon operand ensures the kernel does not move the instruction + * pointer to attacker-controlled code on rseq abort. + * + * The instruction pattern is: + * + * e7f530f5 udf #21253 ; 0x5305 + */ +#define RSEQ_SIG 0xe7f530f5 #define rseq_smp_mb() __asm__ __volatile__ ("dmb" ::: "memory", "cc") #define rseq_smp_rmb() __asm__ __volatile__ ("dmb" ::: "memory", "cc") @@ -78,7 +88,8 @@ do { \ __rseq_str(table_label) ":\n\t" \ ".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ ".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \ - ".word " __rseq_str(RSEQ_SIG) "\n\t" \ + ".arm\n\t" \ + ".inst " __rseq_str(RSEQ_SIG) "\n\t" \ __rseq_str(label) ":\n\t" \ teardown \ "b %l[" __rseq_str(abort_label) "]\n\t" > > Thanks! > > Mathieu > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-10 20:29 ` Mathieu Desnoyers @ 2019-04-11 16:42 ` Will Deacon 2019-04-11 17:51 ` Mathieu Desnoyers 0 siblings, 1 reply; 15+ messages in thread From: Will Deacon @ 2019-04-11 16:42 UTC (permalink / raw) To: Mathieu Desnoyers Cc: libc-alpha, linux-kernel, carlos, peter.maydell, richard.earnshaw Hi Mathieu, On Wed, Apr 10, 2019 at 04:29:19PM -0400, Mathieu Desnoyers wrote: > ----- On Apr 9, 2019, at 3:32 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > > We are about to include the code signature required prior to restartable > > sequences abort handlers into glibc, which will make this ABI choice final. > > We need architecture maintainer input on that signature value. > > > > That code signature is placed before each abort handler, so the kernel can > > validate that it is indeed jumping to an abort handler (and not some > > arbitrary attacker-chosen code). The signature is never executed. > > > > The current discussion thread on the glibc mailing list leads us towards > > using a trap with uncommon immediate operand, which simplifies integration > > with disassemblers, emulators, makes it easier to debug if the control > > flow gets redirected there by mistake, and is nicer for some architecture's > > speculative execution. > > > > We can have different signatures for each sub-architecture, as long as they > > don't have to co-exist within the same process. We can special-case with > > #ifdef for each sub-architecture and endianness if need be. If the architecture > > has instruction set extensions that can co-exist with the architecture > > instruction set within the same process (e.g. thumb for arm), we need to take > > into account to which instruction the chosen signature value would map (and > > possibly decide if we need to extend rseq to support many signatures). > > > > Here is an example of rseq signature definition template: > > > > /* > > * TODO: document trap instruction objdump output on each sub-architecture > > * instruction sets, as well as instruction set extensions. > > */ > > #define RSEQ_SIG 0x######## > > > > Ideally we'd need a patch on top of the Linux kernel > > tools/testing/selftests/rseq/rseq-arm.h file that updates > > the signature value, so I can then pick it up for the glibc > > patchset. > > Would the following diff work for you ? If so, can I get your > acked-by ? I had a quick chat with Richard and Peter (CC'd), since they're much more familiar with the A32 instruction set than I am and also have a better view of what might already be in use. Peter suggests that anything of the form 0xe7fxdefx should trap in both A32 and T32, although it does assemble to UDF; B <imm11> in T16. I'm not sure we should get too obsessed with trying to encode a signature that universally decodes to a trap. Whatever you choose, it would be worth checking that it doesn't clash with other allocations such as software breakpoints in GDB. Will > diff --git a/tools/testing/selftests/rseq/rseq-arm.h b/tools/testing/selftests/rseq/rseq-arm.h > index 5f262c54364f..1f261ad2ac1b 100644 > --- a/tools/testing/selftests/rseq/rseq-arm.h > +++ b/tools/testing/selftests/rseq/rseq-arm.h > @@ -5,7 +5,17 @@ > * (C) Copyright 2016-2018 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> > */ > > -#define RSEQ_SIG 0x53053053 > +/* > + * RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand > + * value 0x5305. This traps if user-space reaches this instruction by mistake, > + * and the uncommon operand ensures the kernel does not move the instruction > + * pointer to attacker-controlled code on rseq abort. > + * > + * The instruction pattern is: > + * > + * e7f530f5 udf #21253 ; 0x5305 > + */ > +#define RSEQ_SIG 0xe7f530f5 > > #define rseq_smp_mb() __asm__ __volatile__ ("dmb" ::: "memory", "cc") > #define rseq_smp_rmb() __asm__ __volatile__ ("dmb" ::: "memory", "cc") > @@ -78,7 +88,8 @@ do { \ > __rseq_str(table_label) ":\n\t" \ > ".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \ > ".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \ > - ".word " __rseq_str(RSEQ_SIG) "\n\t" \ > + ".arm\n\t" \ > + ".inst " __rseq_str(RSEQ_SIG) "\n\t" \ > __rseq_str(label) ":\n\t" \ > teardown \ > "b %l[" __rseq_str(abort_label) "]\n\t" ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-11 16:42 ` Will Deacon @ 2019-04-11 17:51 ` Mathieu Desnoyers 2019-04-11 19:55 ` Peter Maydell 0 siblings, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-11 17:51 UTC (permalink / raw) To: Will Deacon Cc: libc-alpha, linux-kernel, carlos, peter maydell, richard earnshaw ----- On Apr 11, 2019, at 12:42 PM, Will Deacon will.deacon@arm.com wrote: > Hi Mathieu, > > On Wed, Apr 10, 2019 at 04:29:19PM -0400, Mathieu Desnoyers wrote: >> ----- On Apr 9, 2019, at 3:32 PM, Mathieu Desnoyers >> mathieu.desnoyers@efficios.com wrote: >> > We are about to include the code signature required prior to restartable >> > sequences abort handlers into glibc, which will make this ABI choice final. >> > We need architecture maintainer input on that signature value. >> > >> > That code signature is placed before each abort handler, so the kernel can >> > validate that it is indeed jumping to an abort handler (and not some >> > arbitrary attacker-chosen code). The signature is never executed. >> > >> > The current discussion thread on the glibc mailing list leads us towards >> > using a trap with uncommon immediate operand, which simplifies integration >> > with disassemblers, emulators, makes it easier to debug if the control >> > flow gets redirected there by mistake, and is nicer for some architecture's >> > speculative execution. >> > >> > We can have different signatures for each sub-architecture, as long as they >> > don't have to co-exist within the same process. We can special-case with >> > #ifdef for each sub-architecture and endianness if need be. If the architecture >> > has instruction set extensions that can co-exist with the architecture >> > instruction set within the same process (e.g. thumb for arm), we need to take >> > into account to which instruction the chosen signature value would map (and >> > possibly decide if we need to extend rseq to support many signatures). >> > >> > Here is an example of rseq signature definition template: >> > >> > /* >> > * TODO: document trap instruction objdump output on each sub-architecture >> > * instruction sets, as well as instruction set extensions. >> > */ >> > #define RSEQ_SIG 0x######## >> > >> > Ideally we'd need a patch on top of the Linux kernel >> > tools/testing/selftests/rseq/rseq-arm.h file that updates >> > the signature value, so I can then pick it up for the glibc >> > patchset. >> >> Would the following diff work for you ? If so, can I get your >> acked-by ? > > I had a quick chat with Richard and Peter (CC'd), since they're much more > familiar with the A32 instruction set than I am and also have a better view > of what might already be in use. > > Peter suggests that anything of the form 0xe7fxdefx should trap in both A32 > and T32, although it does assemble to UDF; B <imm11> in T16. I'm not sure we > should get too obsessed with trying to encode a signature that universally > decodes to a trap. That's a nice trick. > > Whatever you choose, it would be worth checking that it doesn't clash with > other allocations such as software breakpoints in GDB. GDB seems to have [1] : #define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} #define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} #define THUMB_LE_BREAKPOINT {0xbe,0xbe} #define THUMB_BE_BREAKPOINT {0xbe,0xbe} None of which match the value you hint at. So I could pick "0xe7f5def3", which would map to the following comment: /* * RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand * value 0x5de3. This traps if user-space reaches this instruction by mistake, * and the uncommon operand ensures the kernel does not move the instruction * pointer to attacker-controlled code on rseq abort. * * The instruction pattern in the A32 instruction set is: * * e7f5def3 udf #24035 ; 0x5de3 * * This translates to the following instruction pattern in the T16 instruction * set: * * little endian: * def3 udf #243 ; 0xf3 * e7f5 b.n <7f5> * * big endian: * e7f5 b.n <7f5> * def3 udf #243 ; 0xf3 */ #define RSEQ_SIG 0xe7f5def3 Thoughts ? Thanks! Mathieu [1] https://github.com/bminor/binutils-gdb/blob/master/gdb/arm-tdep.c#L7705-L7742 -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-11 17:51 ` Mathieu Desnoyers @ 2019-04-11 19:55 ` Peter Maydell 2019-04-15 13:11 ` Mathieu Desnoyers 0 siblings, 1 reply; 15+ messages in thread From: Peter Maydell @ 2019-04-11 19:55 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Will Deacon, libc-alpha, linux-kernel, carlos, richard earnshaw On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote: > ----- On Apr 11, 2019, at 12:42 PM, Will Deacon will.deacon@arm.com wrote: > > Peter suggests that anything of the form 0xe7fxdefx should trap in both A32 > > and T32, although it does assemble to UDF; B <imm11> in T16. I'm not sure we > > should get too obsessed with trying to encode a signature that universally > > decodes to a trap. > > That's a nice trick. > > > > > Whatever you choose, it would be worth checking that it doesn't clash with > > other allocations such as software breakpoints in GDB. > > GDB seems to have [1] : > > #define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} > #define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} > #define THUMB_LE_BREAKPOINT {0xbe,0xbe} > #define THUMB_BE_BREAKPOINT {0xbe,0xbe} > > None of which match the value you hint at. Hmm? The ARM BPs match 0xe7fxdefx when considered with the appropriate endianness (clearly somebody has been down this line of thought before). Still, as long as we pick different values for the 8 bits of freedom we have it should be fine. > /* > * RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand > * value 0x5de3. This traps if user-space reaches this instruction by mistake, > * and the uncommon operand ensures the kernel does not move the instruction > * pointer to attacker-controlled code on rseq abort. > * > * The instruction pattern in the A32 instruction set is: > * > * e7f5def3 udf #24035 ; 0x5de3 > * > * This translates to the following instruction pattern in the T16 instruction > * set: > * > * little endian: > * def3 udf #243 ; 0xf3 > * e7f5 b.n <7f5> > * > * big endian: > * e7f5 b.n <7f5> > * def3 udf #243 ; 0xf3 Do we really care about big-endian instruction-ordering for Thumb? It requires (AIUI) either an ARMv7R CPU which implements and sets SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to be even rarer than normal BE8 big-endian... thanks -- PMM ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-11 19:55 ` Peter Maydell @ 2019-04-15 13:11 ` Mathieu Desnoyers 2019-04-15 13:30 ` Peter Maydell 0 siblings, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-15 13:11 UTC (permalink / raw) To: peter maydell Cc: Will Deacon, libc-alpha, linux-kernel, carlos, richard earnshaw ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: > On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers > <mathieu.desnoyers@efficios.com> wrote: >> ----- On Apr 11, 2019, at 12:42 PM, Will Deacon will.deacon@arm.com wrote: >> > Peter suggests that anything of the form 0xe7fxdefx should trap in both A32 >> > and T32, although it does assemble to UDF; B <imm11> in T16. I'm not sure we >> > should get too obsessed with trying to encode a signature that universally >> > decodes to a trap. >> >> That's a nice trick. >> >> > >> > Whatever you choose, it would be worth checking that it doesn't clash with >> > other allocations such as software breakpoints in GDB. >> >> GDB seems to have [1] : >> >> #define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} >> #define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} >> #define THUMB_LE_BREAKPOINT {0xbe,0xbe} >> #define THUMB_BE_BREAKPOINT {0xbe,0xbe} >> >> None of which match the value you hint at. > > Hmm? The ARM BPs match 0xe7fxdefx when considered with > the appropriate endianness (clearly somebody has > been down this line of thought before). Still, as long as > we pick different values for the 8 bits of freedom we > have it should be fine. Right. I selected 0xe7f5def3, which should ensure we are distinct from gdb's choice. > >> /* >> * RSEQ_SIG uses the udf A32 instruction with an uncommon immediate operand >> * value 0x5de3. This traps if user-space reaches this instruction by mistake, >> * and the uncommon operand ensures the kernel does not move the instruction >> * pointer to attacker-controlled code on rseq abort. >> * >> * The instruction pattern in the A32 instruction set is: >> * >> * e7f5def3 udf #24035 ; 0x5de3 >> * >> * This translates to the following instruction pattern in the T16 instruction >> * set: >> * >> * little endian: >> * def3 udf #243 ; 0xf3 >> * e7f5 b.n <7f5> >> * >> * big endian: >> * e7f5 b.n <7f5> >> * def3 udf #243 ; 0xf3 > > Do we really care about big-endian instruction-ordering for Thumb? > It requires (AIUI) either an ARMv7R CPU which implements and sets > SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to > be even rarer than normal BE8 big-endian... I don't think we care enough about it to look for a trick to turn the branch into something else (which would not branch away from the udf instruction), but considering this signature will be ABI, it's good to be thorough documentation-wise and cover all existing cases. Thoughts ? Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-15 13:11 ` Mathieu Desnoyers @ 2019-04-15 13:30 ` Peter Maydell 2019-04-15 13:37 ` Mathieu Desnoyers 0 siblings, 1 reply; 15+ messages in thread From: Peter Maydell @ 2019-04-15 13:30 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Will Deacon, libc-alpha, linux-kernel, carlos, richard earnshaw On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers <mathieu.desnoyers@efficios.com> wrote: > > ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: > > > On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers > > <mathieu.desnoyers@efficios.com> wrote: > >> * This translates to the following instruction pattern in the T16 instruction > >> * set: > >> * > >> * little endian: > >> * def3 udf #243 ; 0xf3 > >> * e7f5 b.n <7f5> > >> * > >> * big endian: > >> * e7f5 b.n <7f5> > >> * def3 udf #243 ; 0xf3 > > > > Do we really care about big-endian instruction-ordering for Thumb? > > It requires (AIUI) either an ARMv7R CPU which implements and sets > > SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to > > be even rarer than normal BE8 big-endian... > > I don't think we care enough about it to look for a trick to > turn the branch into something else (which would not branch away from the > udf instruction), but considering this signature will be ABI, it's good to > be thorough documentation-wise and cover all existing cases. I think if you want to document it it would be helpful to readers to make it clear that this is the ultra-rare big-endian-instruction-order "big endian Thumb", not the only moderately-rare little-endian-instructions-big-endian-data "big endian Thumb". thanks -- PMM ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-15 13:30 ` Peter Maydell @ 2019-04-15 13:37 ` Mathieu Desnoyers 2019-04-16 13:39 ` Mathieu Desnoyers 0 siblings, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-15 13:37 UTC (permalink / raw) To: peter maydell Cc: Will Deacon, libc-alpha, linux-kernel, carlos, richard earnshaw ----- On Apr 15, 2019, at 9:30 AM, peter maydell peter.maydell@linaro.org wrote: > On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers > <mathieu.desnoyers@efficios.com> wrote: >> >> ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: >> >> > On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers >> > <mathieu.desnoyers@efficios.com> wrote: >> >> * This translates to the following instruction pattern in the T16 instruction >> >> * set: >> >> * >> >> * little endian: >> >> * def3 udf #243 ; 0xf3 >> >> * e7f5 b.n <7f5> >> >> * >> >> * big endian: >> >> * e7f5 b.n <7f5> >> >> * def3 udf #243 ; 0xf3 >> > >> > Do we really care about big-endian instruction-ordering for Thumb? >> > It requires (AIUI) either an ARMv7R CPU which implements and sets >> > SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to >> > be even rarer than normal BE8 big-endian... >> >> I don't think we care enough about it to look for a trick to >> turn the branch into something else (which would not branch away from the >> udf instruction), but considering this signature will be ABI, it's good to >> be thorough documentation-wise and cover all existing cases. > > I think if you want to document it it would be helpful to > readers to make it clear that this is the ultra-rare > big-endian-instruction-order "big endian Thumb", not the only > moderately-rare little-endian-instructions-big-endian-data > "big endian Thumb". I'm actually very much concerned about environments with big endian data and little endian code. Which gcc compiler flags do I need to use to test it ? I'm concerned about a signature mismatch between what is passed to the rseq system call ("data-endian signature") and what is generated in the code ("instruction-endian signature"). Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-15 13:37 ` Mathieu Desnoyers @ 2019-04-16 13:39 ` Mathieu Desnoyers 2019-04-17 10:37 ` Richard Earnshaw (lists) 0 siblings, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-16 13:39 UTC (permalink / raw) To: peter maydell Cc: Will Deacon, libc-alpha, linux-kernel, carlos, richard earnshaw ----- On Apr 15, 2019, at 9:37 AM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > ----- On Apr 15, 2019, at 9:30 AM, peter maydell peter.maydell@linaro.org wrote: > >> On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers >> <mathieu.desnoyers@efficios.com> wrote: >>> >>> ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: >>> >>> > On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers >>> > <mathieu.desnoyers@efficios.com> wrote: >>> >> * This translates to the following instruction pattern in the T16 instruction >>> >> * set: >>> >> * >>> >> * little endian: >>> >> * def3 udf #243 ; 0xf3 >>> >> * e7f5 b.n <7f5> >>> >> * >>> >> * big endian: >>> >> * e7f5 b.n <7f5> >>> >> * def3 udf #243 ; 0xf3 >>> > >>> > Do we really care about big-endian instruction-ordering for Thumb? >>> > It requires (AIUI) either an ARMv7R CPU which implements and sets >>> > SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to >>> > be even rarer than normal BE8 big-endian... >>> >>> I don't think we care enough about it to look for a trick to >>> turn the branch into something else (which would not branch away from the >>> udf instruction), but considering this signature will be ABI, it's good to >>> be thorough documentation-wise and cover all existing cases. >> >> I think if you want to document it it would be helpful to >> readers to make it clear that this is the ultra-rare >> big-endian-instruction-order "big endian Thumb", not the only >> moderately-rare little-endian-instructions-big-endian-data >> "big endian Thumb". > > I'm actually very much concerned about environments with big endian > data and little endian code. Which gcc compiler flags do I need to > use to test it ? > > I'm concerned about a signature mismatch between what is passed to > the rseq system call ("data-endian signature") and what is generated > in the code ("instruction-endian signature"). Based on this page: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CDFBBCHB.html My understanding is that the situation is as follows (please confirm): - Prior to ARMv6, you could build and run code that is either big or little endian, given you had a matching Linux kernel endianness. Code and data endianness needed to match, - Starting from ARMv6, only little endian code is supported. The endianness for data access can be changed through bit [9], the E bit, of the Program Status Register, (mixed endianness) Looking at ARM build options for gcc, it seems you can select either big or little endian (-mbig-endian or -mlittle-endian (default)) which affects both instruction and data endianness. So I suspect the -mbig-endian option is really only useful for pre-ARMv6. For ARMv6+ mixed-endianness, it seems to be a mode that temporarily swap endianness of load/store instructions for specific memory accesses communicating with DMA devices, so I don't see any scenario where we can generate a binary that has little endian code and big endian data. If that is true, then it should be fine to declare the signature with ".arm .inst" and expect the data endianness to be the same as code endianness. Am I missing something ? Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-16 13:39 ` Mathieu Desnoyers @ 2019-04-17 10:37 ` Richard Earnshaw (lists) 2019-04-17 14:43 ` Mathieu Desnoyers 0 siblings, 1 reply; 15+ messages in thread From: Richard Earnshaw (lists) @ 2019-04-17 10:37 UTC (permalink / raw) To: Mathieu Desnoyers, peter maydell Cc: Will Deacon, libc-alpha, linux-kernel, carlos On 16/04/2019 14:39, Mathieu Desnoyers wrote: > ----- On Apr 15, 2019, at 9:37 AM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > >> ----- On Apr 15, 2019, at 9:30 AM, peter maydell peter.maydell@linaro.org wrote: >> >>> On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers >>> <mathieu.desnoyers@efficios.com> wrote: >>>> >>>> ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: >>>> >>>>> On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers >>>>> <mathieu.desnoyers@efficios.com> wrote: >>>>>> * This translates to the following instruction pattern in the T16 instruction >>>>>> * set: >>>>>> * >>>>>> * little endian: >>>>>> * def3 udf #243 ; 0xf3 >>>>>> * e7f5 b.n <7f5> >>>>>> * >>>>>> * big endian: >>>>>> * e7f5 b.n <7f5> >>>>>> * def3 udf #243 ; 0xf3 >>>>> >>>>> Do we really care about big-endian instruction-ordering for Thumb? >>>>> It requires (AIUI) either an ARMv7R CPU which implements and sets >>>>> SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to >>>>> be even rarer than normal BE8 big-endian... >>>> >>>> I don't think we care enough about it to look for a trick to >>>> turn the branch into something else (which would not branch away from the >>>> udf instruction), but considering this signature will be ABI, it's good to >>>> be thorough documentation-wise and cover all existing cases. >>> >>> I think if you want to document it it would be helpful to >>> readers to make it clear that this is the ultra-rare >>> big-endian-instruction-order "big endian Thumb", not the only >>> moderately-rare little-endian-instructions-big-endian-data >>> "big endian Thumb". >> >> I'm actually very much concerned about environments with big endian >> data and little endian code. Which gcc compiler flags do I need to >> use to test it ? >> >> I'm concerned about a signature mismatch between what is passed to >> the rseq system call ("data-endian signature") and what is generated >> in the code ("instruction-endian signature"). > > Based on this page: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CDFBBCHB.html > > My understanding is that the situation is as follows (please confirm): > > - Prior to ARMv6, you could build and run code that is either big or little endian, > given you had a matching Linux kernel endianness. Code and data endianness needed > to match, > - Starting from ARMv6, only little endian code is supported. The endianness for data > access can be changed through bit [9], the E bit, of the Program Status Register, > (mixed endianness) > > Looking at ARM build options for gcc, it seems you can select either big or little > endian (-mbig-endian or -mlittle-endian (default)) which affects both instruction and > data endianness. So I suspect the -mbig-endian option is really only useful for > pre-ARMv6. -mbig-endian is still correct, even on later architectures. The linker gets involved, however, and (using the mapping symbol information) swaps the code segments to little-endian form (this is why you have to use .inst rather than .word when inserting instructions, so that the correct mapping symbols are inserted). > > For ARMv6+ mixed-endianness, it seems to be a mode that temporarily swap endianness > of load/store instructions for specific memory accesses communicating with DMA devices, > so I don't see any scenario where we can generate a binary that has little endian code > and big endian data. If that is true, then it should be fine to declare the signature > with ".arm .inst" and expect the data endianness to be the same as code endianness. > > Am I missing something ? > > Thanks, > > Mathieu > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-17 10:37 ` Richard Earnshaw (lists) @ 2019-04-17 14:43 ` Mathieu Desnoyers 2019-04-17 15:30 ` Mathieu Desnoyers 0 siblings, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-17 14:43 UTC (permalink / raw) To: richard earnshaw Cc: peter maydell, Will Deacon, libc-alpha, linux-kernel, carlos ----- On Apr 17, 2019, at 6:37 AM, richard earnshaw Richard.Earnshaw@arm.com wrote: > On 16/04/2019 14:39, Mathieu Desnoyers wrote: >> ----- On Apr 15, 2019, at 9:37 AM, Mathieu Desnoyers >> mathieu.desnoyers@efficios.com wrote: >> >>> ----- On Apr 15, 2019, at 9:30 AM, peter maydell peter.maydell@linaro.org wrote: >>> >>>> On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers >>>> <mathieu.desnoyers@efficios.com> wrote: >>>>> >>>>> ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: >>>>> >>>>>> On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers >>>>>> <mathieu.desnoyers@efficios.com> wrote: >>>>>>> * This translates to the following instruction pattern in the T16 instruction >>>>>>> * set: >>>>>>> * >>>>>>> * little endian: >>>>>>> * def3 udf #243 ; 0xf3 >>>>>>> * e7f5 b.n <7f5> >>>>>>> * >>>>>>> * big endian: >>>>>>> * e7f5 b.n <7f5> >>>>>>> * def3 udf #243 ; 0xf3 >>>>>> >>>>>> Do we really care about big-endian instruction-ordering for Thumb? >>>>>> It requires (AIUI) either an ARMv7R CPU which implements and sets >>>>>> SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to >>>>>> be even rarer than normal BE8 big-endian... >>>>> >>>>> I don't think we care enough about it to look for a trick to >>>>> turn the branch into something else (which would not branch away from the >>>>> udf instruction), but considering this signature will be ABI, it's good to >>>>> be thorough documentation-wise and cover all existing cases. >>>> >>>> I think if you want to document it it would be helpful to >>>> readers to make it clear that this is the ultra-rare >>>> big-endian-instruction-order "big endian Thumb", not the only >>>> moderately-rare little-endian-instructions-big-endian-data >>>> "big endian Thumb". >>> >>> I'm actually very much concerned about environments with big endian >>> data and little endian code. Which gcc compiler flags do I need to >>> use to test it ? >>> >>> I'm concerned about a signature mismatch between what is passed to >>> the rseq system call ("data-endian signature") and what is generated >>> in the code ("instruction-endian signature"). >> >> Based on this page: >> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CDFBBCHB.html >> >> My understanding is that the situation is as follows (please confirm): >> >> - Prior to ARMv6, you could build and run code that is either big or little >> endian, >> given you had a matching Linux kernel endianness. Code and data endianness >> needed >> to match, >> - Starting from ARMv6, only little endian code is supported. The endianness for >> data >> access can be changed through bit [9], the E bit, of the Program Status >> Register, >> (mixed endianness) >> >> Looking at ARM build options for gcc, it seems you can select either big or >> little >> endian (-mbig-endian or -mlittle-endian (default)) which affects both >> instruction and >> data endianness. So I suspect the -mbig-endian option is really only useful for >> pre-ARMv6. > > -mbig-endian is still correct, even on later architectures. The linker > gets involved, however, and (using the mapping symbol information) swaps > the code segments to little-endian form (this is why you have to use > .inst rather than .word when inserting instructions, so that the correct > mapping symbols are inserted). So what you're saying is that if I have: void main() { asm volatile ( ".arm\n\t" ".inst 0xe7f5def3\n\t" ".long 0xe7f5def3\n\t"); } and compile it with: arm-linux-gnueabihf-gcc -mbig-endian -march=armv6 -c -o arm-big-endianv6.o arm-test-endian.c It's expected that the generated .o will have big endian instructions, matching the endianness of the data, e.g.: hexdump arm-big-endianv6.o [...] 0000030 0a00 0900 80b5 00af f5e7 f3de f5e7 f3de But it's then at the linking stage that the linker will reverse the endianness of the ".inst" (but not .long). Let's see: arm-linux-gnueabihf-gcc -nodefaultlibs -nostdlib -mbig-endian -march=armv6 -o arm-big-endianv6 arm-big-endianv6.o /usr/lib/gcc-cross/arm-linux-gnueabihf/7/../../../../arm-linux-gnueabihf/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000000001b0 hexdump gives me: [...] 00001b0 80b5 00af f5e7 f3de f5e7 f3de c046 bd46 So it has not reversed the instruction endianness. What am I doing wrong ? I'm using: gcc version 7.3.0 (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) GNU ld (GNU Binutils for Ubuntu) 2.30 Thanks, Mathieu > >> >> For ARMv6+ mixed-endianness, it seems to be a mode that temporarily swap >> endianness >> of load/store instructions for specific memory accesses communicating with DMA >> devices, >> so I don't see any scenario where we can generate a binary that has little >> endian code >> and big endian data. If that is true, then it should be fine to declare the >> signature >> with ".arm .inst" and expect the data endianness to be the same as code >> endianness. >> >> Am I missing something ? >> >> Thanks, >> >> Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-17 14:43 ` Mathieu Desnoyers @ 2019-04-17 15:30 ` Mathieu Desnoyers 2019-04-18 16:18 ` Richard Earnshaw (lists) 0 siblings, 1 reply; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-17 15:30 UTC (permalink / raw) To: richard earnshaw Cc: peter maydell, Will Deacon, libc-alpha, linux-kernel, carlos ----- On Apr 17, 2019, at 10:43 AM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > ----- On Apr 17, 2019, at 6:37 AM, richard earnshaw Richard.Earnshaw@arm.com > wrote: > >> On 16/04/2019 14:39, Mathieu Desnoyers wrote: >>> ----- On Apr 15, 2019, at 9:37 AM, Mathieu Desnoyers >>> mathieu.desnoyers@efficios.com wrote: >>> >>>> ----- On Apr 15, 2019, at 9:30 AM, peter maydell peter.maydell@linaro.org wrote: >>>> >>>>> On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers >>>>> <mathieu.desnoyers@efficios.com> wrote: >>>>>> >>>>>> ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: >>>>>> >>>>>>> On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers >>>>>>> <mathieu.desnoyers@efficios.com> wrote: >>>>>>>> * This translates to the following instruction pattern in the T16 instruction >>>>>>>> * set: >>>>>>>> * >>>>>>>> * little endian: >>>>>>>> * def3 udf #243 ; 0xf3 >>>>>>>> * e7f5 b.n <7f5> >>>>>>>> * >>>>>>>> * big endian: >>>>>>>> * e7f5 b.n <7f5> >>>>>>>> * def3 udf #243 ; 0xf3 >>>>>>> >>>>>>> Do we really care about big-endian instruction-ordering for Thumb? >>>>>>> It requires (AIUI) either an ARMv7R CPU which implements and sets >>>>>>> SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to >>>>>>> be even rarer than normal BE8 big-endian... >>>>>> >>>>>> I don't think we care enough about it to look for a trick to >>>>>> turn the branch into something else (which would not branch away from the >>>>>> udf instruction), but considering this signature will be ABI, it's good to >>>>>> be thorough documentation-wise and cover all existing cases. >>>>> >>>>> I think if you want to document it it would be helpful to >>>>> readers to make it clear that this is the ultra-rare >>>>> big-endian-instruction-order "big endian Thumb", not the only >>>>> moderately-rare little-endian-instructions-big-endian-data >>>>> "big endian Thumb". >>>> >>>> I'm actually very much concerned about environments with big endian >>>> data and little endian code. Which gcc compiler flags do I need to >>>> use to test it ? >>>> >>>> I'm concerned about a signature mismatch between what is passed to >>>> the rseq system call ("data-endian signature") and what is generated >>>> in the code ("instruction-endian signature"). >>> >>> Based on this page: >>> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CDFBBCHB.html >>> >>> My understanding is that the situation is as follows (please confirm): >>> >>> - Prior to ARMv6, you could build and run code that is either big or little >>> endian, >>> given you had a matching Linux kernel endianness. Code and data endianness >>> needed >>> to match, >>> - Starting from ARMv6, only little endian code is supported. The endianness for >>> data >>> access can be changed through bit [9], the E bit, of the Program Status >>> Register, >>> (mixed endianness) >>> >>> Looking at ARM build options for gcc, it seems you can select either big or >>> little >>> endian (-mbig-endian or -mlittle-endian (default)) which affects both >>> instruction and >>> data endianness. So I suspect the -mbig-endian option is really only useful for >>> pre-ARMv6. >> >> -mbig-endian is still correct, even on later architectures. The linker >> gets involved, however, and (using the mapping symbol information) swaps >> the code segments to little-endian form (this is why you have to use >> .inst rather than .word when inserting instructions, so that the correct >> mapping symbols are inserted). > > So what you're saying is that if I have: > > void main() > { > asm volatile ( > ".arm\n\t" > ".inst 0xe7f5def3\n\t" > ".long 0xe7f5def3\n\t"); > } > > and compile it with: > > arm-linux-gnueabihf-gcc -mbig-endian -march=armv6 -c -o arm-big-endianv6.o > arm-test-endian.c > > It's expected that the generated .o will have big endian instructions, matching > the endianness of the data, e.g.: > > hexdump arm-big-endianv6.o > > [...] > 0000030 0a00 0900 80b5 00af f5e7 f3de f5e7 f3de > > But it's then at the linking stage that the linker will > reverse the endianness of the ".inst" (but not .long). > > Let's see: > > arm-linux-gnueabihf-gcc -nodefaultlibs -nostdlib -mbig-endian -march=armv6 -o > arm-big-endianv6 arm-big-endianv6.o > /usr/lib/gcc-cross/arm-linux-gnueabihf/7/../../../../arm-linux-gnueabihf/bin/ld: > warning: cannot find entry symbol _start; defaulting to 00000000000001b0 > > hexdump gives me: > [...] > 00001b0 80b5 00af f5e7 f3de f5e7 f3de c046 bd46 > > So it has not reversed the instruction endianness. > > What am I doing wrong ? It seems to be specific to using armv6 and armv7* with gcc 7. gcc 8 seems to indeed reverse the code vs data endianness. So we need to figure out whether .inst is the right things to do to declare a signature, or if it's better to use ".long" which would probably generate an invalid instruction on BE... Thanks, Mathieu > > I'm using: > > gcc version 7.3.0 (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) > GNU ld (GNU Binutils for Ubuntu) 2.30 > > Thanks, > > Mathieu > >> >>> >>> For ARMv6+ mixed-endianness, it seems to be a mode that temporarily swap >>> endianness >>> of load/store instructions for specific memory accesses communicating with DMA >>> devices, >>> so I don't see any scenario where we can generate a binary that has little >>> endian code >>> and big endian data. If that is true, then it should be fine to declare the >>> signature >>> with ".arm .inst" and expect the data endianness to be the same as code >>> endianness. >>> >>> Am I missing something ? >>> >>> Thanks, >>> >>> Mathieu > > -- > Mathieu Desnoyers > EfficiOS Inc. > http://www.efficios.com -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-17 15:30 ` Mathieu Desnoyers @ 2019-04-18 16:18 ` Richard Earnshaw (lists) 0 siblings, 0 replies; 15+ messages in thread From: Richard Earnshaw (lists) @ 2019-04-18 16:18 UTC (permalink / raw) To: Mathieu Desnoyers Cc: peter maydell, Will Deacon, libc-alpha, linux-kernel, carlos On 17/04/2019 16:30, Mathieu Desnoyers wrote: > ----- On Apr 17, 2019, at 10:43 AM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote: > >> ----- On Apr 17, 2019, at 6:37 AM, richard earnshaw Richard.Earnshaw@arm.com >> wrote: >> >>> On 16/04/2019 14:39, Mathieu Desnoyers wrote: >>>> ----- On Apr 15, 2019, at 9:37 AM, Mathieu Desnoyers >>>> mathieu.desnoyers@efficios.com wrote: >>>> >>>>> ----- On Apr 15, 2019, at 9:30 AM, peter maydell peter.maydell@linaro.org wrote: >>>>> >>>>>> On Mon, 15 Apr 2019 at 14:11, Mathieu Desnoyers >>>>>> <mathieu.desnoyers@efficios.com> wrote: >>>>>>> >>>>>>> ----- On Apr 11, 2019, at 3:55 PM, peter maydell peter.maydell@linaro.org wrote: >>>>>>> >>>>>>>> On Thu, 11 Apr 2019 at 18:51, Mathieu Desnoyers >>>>>>>> <mathieu.desnoyers@efficios.com> wrote: >>>>>>>>> * This translates to the following instruction pattern in the T16 instruction >>>>>>>>> * set: >>>>>>>>> * >>>>>>>>> * little endian: >>>>>>>>> * def3 udf #243 ; 0xf3 >>>>>>>>> * e7f5 b.n <7f5> >>>>>>>>> * >>>>>>>>> * big endian: >>>>>>>>> * e7f5 b.n <7f5> >>>>>>>>> * def3 udf #243 ; 0xf3 >>>>>>>> >>>>>>>> Do we really care about big-endian instruction-ordering for Thumb? >>>>>>>> It requires (AIUI) either an ARMv7R CPU which implements and sets >>>>>>>> SCTLR.IE to 1, or a v6-or-earlier CPU using BE32, and it's going to >>>>>>>> be even rarer than normal BE8 big-endian... >>>>>>> >>>>>>> I don't think we care enough about it to look for a trick to >>>>>>> turn the branch into something else (which would not branch away from the >>>>>>> udf instruction), but considering this signature will be ABI, it's good to >>>>>>> be thorough documentation-wise and cover all existing cases. >>>>>> >>>>>> I think if you want to document it it would be helpful to >>>>>> readers to make it clear that this is the ultra-rare >>>>>> big-endian-instruction-order "big endian Thumb", not the only >>>>>> moderately-rare little-endian-instructions-big-endian-data >>>>>> "big endian Thumb". >>>>> >>>>> I'm actually very much concerned about environments with big endian >>>>> data and little endian code. Which gcc compiler flags do I need to >>>>> use to test it ? >>>>> >>>>> I'm concerned about a signature mismatch between what is passed to >>>>> the rseq system call ("data-endian signature") and what is generated >>>>> in the code ("instruction-endian signature"). >>>> >>>> Based on this page: >>>> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CDFBBCHB.html >>>> >>>> My understanding is that the situation is as follows (please confirm): >>>> >>>> - Prior to ARMv6, you could build and run code that is either big or little >>>> endian, >>>> given you had a matching Linux kernel endianness. Code and data endianness >>>> needed >>>> to match, >>>> - Starting from ARMv6, only little endian code is supported. The endianness for >>>> data >>>> access can be changed through bit [9], the E bit, of the Program Status >>>> Register, >>>> (mixed endianness) >>>> >>>> Looking at ARM build options for gcc, it seems you can select either big or >>>> little >>>> endian (-mbig-endian or -mlittle-endian (default)) which affects both >>>> instruction and >>>> data endianness. So I suspect the -mbig-endian option is really only useful for >>>> pre-ARMv6. >>> >>> -mbig-endian is still correct, even on later architectures. The linker >>> gets involved, however, and (using the mapping symbol information) swaps >>> the code segments to little-endian form (this is why you have to use >>> .inst rather than .word when inserting instructions, so that the correct >>> mapping symbols are inserted). >> >> So what you're saying is that if I have: >> >> void main() >> { >> asm volatile ( >> ".arm\n\t" >> ".inst 0xe7f5def3\n\t" >> ".long 0xe7f5def3\n\t"); >> } >> >> and compile it with: >> >> arm-linux-gnueabihf-gcc -mbig-endian -march=armv6 -c -o arm-big-endianv6.o >> arm-test-endian.c >> >> It's expected that the generated .o will have big endian instructions, matching >> the endianness of the data, e.g.: >> >> hexdump arm-big-endianv6.o >> >> [...] >> 0000030 0a00 0900 80b5 00af f5e7 f3de f5e7 f3de >> >> But it's then at the linking stage that the linker will >> reverse the endianness of the ".inst" (but not .long). >> >> Let's see: >> >> arm-linux-gnueabihf-gcc -nodefaultlibs -nostdlib -mbig-endian -march=armv6 -o >> arm-big-endianv6 arm-big-endianv6.o >> /usr/lib/gcc-cross/arm-linux-gnueabihf/7/../../../../arm-linux-gnueabihf/bin/ld: >> warning: cannot find entry symbol _start; defaulting to 00000000000001b0 >> >> hexdump gives me: >> [...] >> 00001b0 80b5 00af f5e7 f3de f5e7 f3de c046 bd46 >> >> So it has not reversed the instruction endianness. >> >> What am I doing wrong ? > > It seems to be specific to using armv6 and armv7* with gcc 7. > gcc 8 seems to indeed reverse the code vs data endianness. > > So we need to figure out whether .inst is the right things to > do to declare a signature, or if it's better to use ".long" > which would probably generate an invalid instruction on BE... If you used .long the value would then be left as data, but tools that scanned for data in the text segment (some environments forbid this) would then fault the object as 'impure'. So using an instruction would be preferable, but on a BE8 image you'll need to byte-swap the 'value' before comparing it. Such images will have EF_ARM_BE8 set in the flags field of the image header. R. > > Thanks, > > Mathieu > >> >> I'm using: >> >> gcc version 7.3.0 (Ubuntu/Linaro 7.3.0-27ubuntu1~18.04) >> GNU ld (GNU Binutils for Ubuntu) 2.30 >> >> Thanks, >> >> Mathieu >> >>> >>>> >>>> For ARMv6+ mixed-endianness, it seems to be a mode that temporarily swap >>>> endianness >>>> of load/store instructions for specific memory accesses communicating with DMA >>>> devices, >>>> so I don't see any scenario where we can generate a binary that has little >>>> endian code >>>> and big endian data. If that is true, then it should be fine to declare the >>>> signature >>>> with ".arm .inst" and expect the data endianness to be the same as code >>>> endianness. >>>> >>>> Am I missing something ? >>>> >>>> Thanks, >>>> >>>> Mathieu >> >> -- >> Mathieu Desnoyers >> EfficiOS Inc. >> http://www.efficios.com > ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-09 19:32 rseq/arm32: choosing rseq code signature Mathieu Desnoyers 2019-04-10 20:29 ` Mathieu Desnoyers @ 2019-04-11 12:24 ` Florian Weimer 2019-04-15 13:22 ` Mathieu Desnoyers 1 sibling, 1 reply; 15+ messages in thread From: Florian Weimer @ 2019-04-11 12:24 UTC (permalink / raw) To: Mathieu Desnoyers Cc: Will Deacon, libc-alpha, linux-kernel, Carlos O'Donell * Mathieu Desnoyers: > /* > * TODO: document trap instruction objdump output on each sub-architecture > * instruction sets, as well as instruction set extensions. > */ > #define RSEQ_SIG 0x######## Will RSEQ_SIG actually be needed at run time outside the rseq implementation library (whether it's glibc or something else)? Actually rseq users will emit the signature directly into the text section, right? They never have to load it into a register, I assume. My concern is that on some architectures, the very act of referencing RSEQ_SIG will put it into the text section, as a non-instruction, which is not what we want. Thanks, Florian ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: rseq/arm32: choosing rseq code signature 2019-04-11 12:24 ` Florian Weimer @ 2019-04-15 13:22 ` Mathieu Desnoyers 0 siblings, 0 replies; 15+ messages in thread From: Mathieu Desnoyers @ 2019-04-15 13:22 UTC (permalink / raw) To: Florian Weimer; +Cc: Will Deacon, libc-alpha, linux-kernel, carlos ----- On Apr 11, 2019, at 8:24 AM, Florian Weimer fweimer@redhat.com wrote: > * Mathieu Desnoyers: > >> /* >> * TODO: document trap instruction objdump output on each sub-architecture >> * instruction sets, as well as instruction set extensions. >> */ >> #define RSEQ_SIG 0x######## > > Will RSEQ_SIG actually be needed at run time outside the rseq > implementation library (whether it's glibc or something else)? Here is how I plan to use it: - rseq registration performed by glibc, - rseq critical section abort handlers: - inlined into applications, - inlined into libraries. I plan that it will be mostly used through librseq headers, but inlined into applications/libraries, which really makes this a fixed ABI once it's published through public headers. > > Actually rseq users will emit the signature directly into the text > section, right? They never have to load it into a register, I assume. The user-space libraries defining rseq critical sections only emit this signature into their text section. However, the kernel will load that signature and compare its value before moving the instruction pointer to the abort handler. So it gets eventually loaded into a register and compared by the kernel, not by user-space. > My concern is that on some architectures, the very act of referencing > RSEQ_SIG will put it into the text section, as a non-instruction, which > is not what we want. The kernel knows at which address the RSEQ_SIG sits based on the abort_ip of the current rseq_cs struct. Getting the address of the abort_ip is performed through an assembler label. Note that on arm32, I had to use ".arm\n\t.inst 0xNNNNNNNN" rather than ".long 0xNNNNNNNN" to ensure the assembler emits the signature as an actual instruction rather than non-instruction "data". This modifies the content of the symbol table .symtab elf section. Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2019-04-18 16:18 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-04-09 19:32 rseq/arm32: choosing rseq code signature Mathieu Desnoyers 2019-04-10 20:29 ` Mathieu Desnoyers 2019-04-11 16:42 ` Will Deacon 2019-04-11 17:51 ` Mathieu Desnoyers 2019-04-11 19:55 ` Peter Maydell 2019-04-15 13:11 ` Mathieu Desnoyers 2019-04-15 13:30 ` Peter Maydell 2019-04-15 13:37 ` Mathieu Desnoyers 2019-04-16 13:39 ` Mathieu Desnoyers 2019-04-17 10:37 ` Richard Earnshaw (lists) 2019-04-17 14:43 ` Mathieu Desnoyers 2019-04-17 15:30 ` Mathieu Desnoyers 2019-04-18 16:18 ` Richard Earnshaw (lists) 2019-04-11 12:24 ` Florian Weimer 2019-04-15 13:22 ` Mathieu Desnoyers
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.