Skip to content
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

cortexm_common/cpu_check_address: fixup for asm statement. #1

Merged

Conversation

jcarrano
Copy link

To prevent GCC/Clang from optimizing away what it should not, the best way is to use Inputs, Outputs and Clobbers to tell it exacly what we are doing.

With this change the code works again in cortex-m0.

For more information see:

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm

Objdump show the following asm being generated (gcc):

00000000 <cpu_check_address>:

bool cpu_check_address(volatile const char *address)
{
   0:	b520      	push	{r5, lr}
    /* Cortex-M0 doesn't have BusFault so we need to catch HardFault */
    (void)address;

    bool result;

    __asm__ volatile (
   2:	2501      	movs	r5, #1
   4:	4902      	ldr	r1, [pc, #8]	; (10 <cpu_check_address+0x10>)
   6:	4a03      	ldr	r2, [pc, #12]	; (14 <cpu_check_address+0x14>)
   8:	7803      	ldrb	r3, [r0, #0]
   a:	1c28      	adds	r0, r5, #0
   c:	b2c0      	uxtb	r0, r0
        : "r1", "r2", "r3", "r5"
     );

    return result;
}
   e:	bd20      	pop	{r5, pc}
  10:	deadf00d 	.word	0xdeadf00d
  14:	cafebabe 	.word	0xcafebabe

In this particular case clang seems to be a bit less smart and also uses r4 and r7.

Testing

I checked address 0 and 0x08080000 in a samr21. The first one is valid and the second one is not.

To prevent GCC from optimizing away what it should not, the best way is
to use Inputs, Outputs and Clobbers to tell it exacly what we are doing.

With this change the code works again in cortex-m0.

For more information see:

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm

Objdump show the following asm being generated (gcc):

-------------------------------
00000000 <cpu_check_address>:

bool cpu_check_address(volatile const char *address)
{
   0:	b520      	push	{r5, lr}
    /* Cortex-M0 doesn't have BusFault so we need to catch HardFault */
    (void)address;

    bool result;

    __asm__ volatile (
   2:	2501      	movs	r5, #1
   4:	4902      	ldr	r1, [pc, RIOT-OS#8]	; (10 <cpu_check_address+0x10>)
   6:	4a03      	ldr	r2, [pc, RIOT-OS#12]	; (14 <cpu_check_address+0x14>)
   8:	7803      	ldrb	r3, [r0, #0]
   a:	1c28      	adds	r0, r5, #0
   c:	b2c0      	uxtb	r0, r0
        : "r1", "r2", "r3", "r5"
     );

    return result;
}
   e:	bd20      	pop	{r5, pc}
  10:	deadf00d 	.word	0xdeadf00d
  14:	cafebabe 	.word	0xcafebabe
-----------------------------

In this particular case clang seems to be a bit less smart and also uses
r4 and r7.
@fjmolinas fjmolinas merged commit bce426d into fjmolinas:riot-cortexm-address-check Apr 15, 2019
fjmolinas pushed a commit that referenced this pull request Jul 22, 2019
The evtimer_msg test is expanded to also delete entries.

Furthermore the messages that are printed should now show
numbers that are very close (if not equal). Something like
this:
At    740 ms received msg 0: "#2 supposed to be 740"
At   1081 ms received msg 1: "#0 supposed to be 1081"
At   1581 ms received msg 2: "#1 supposed to be 1581"
At   4035 ms received msg 3: "#3 supposed to be 4035"

The function evtimer_print is also called to show the
intermediate status of evtimer entries.
fjmolinas pushed a commit that referenced this pull request Aug 4, 2019
The evtimer_msg test is expanded to also delete entries.

Furthermore the messages that are printed should now show
numbers that are very close (if not equal). Something like
this:
At    740 ms received msg 0: "#2 supposed to be 740"
At   1081 ms received msg 1: "#0 supposed to be 1081"
At   1581 ms received msg 2: "#1 supposed to be 1581"
At   4035 ms received msg 3: "#3 supposed to be 4035"

The function evtimer_print is also called to show the
intermediate status of evtimer entries.
fjmolinas pushed a commit that referenced this pull request Sep 3, 2019
The test randomly fails on `native` due to timers being not accurate but
it cannot be otherwise. So better disable it than raising fake errors.

    main(): This is RIOT! (Version: buildtest)
    Testing generic evtimer
    This should list 2 items
    ev #1 offset=1000
    ev #2 offset=500
    This should list 4 items
    ev #1 offset=659
    ev #2 offset=341
    ev #3 offset=500
    ev #4 offset=2454
    Are the reception times of all 4 msgs close to the supposed values?
    At    662 ms received msg 0: "#2 supposed to be 659"
    At   1009 ms received msg 1: "#0 supposed to be 1000"
    At   1511 ms received msg 2: "#1 supposed to be 1500"

    Traceback (most recent call last):
      File "/tmp/dwq.0.3125418833043728/ef3af88c4b3615788b164464a437df5c/tests/evtimer_msg/tests/01-run.py", line 33, in <module>
        sys.exit(run(testfunc))
      File "/tmp/dwq.0.3125418833043728/ef3af88c4b3615788b164464a437df5c/dist/pythonlibs/testrunner/__init__.py", line 29, in run
        testfunc(child)
      File "/tmp/dwq.0.3125418833043728/ef3af88c4b3615788b164464a437df5c/tests/evtimer_msg/tests/01-run.py", line 26, in testfunc
        assert(actual in range(expected - ACCEPTED_ERROR, expected + ACCEPTED_ERROR))
    AssertionError
fjmolinas pushed a commit that referenced this pull request Apr 1, 2020
The ROM size is encoded in the part number of the Atmel SAM chips.
RAM size is not encoded directly, so get it by parsing the chip's vendor file.

The file remains in the page cache for the compiler to use, so the overhead
should be minimal:

on master:

  Benchmark #1: make BOARD=samr21-xpro -j
    Time (mean ± σ):     527.9 ms ±   4.9 ms    [User: 503.1 ms, System: 69.6 ms]
    Range (min … max):   519.7 ms … 537.2 ms    10 runs

with this patch:

  Benchmark #1: make BOARD=samr21-xpro -j
    Time (mean ± σ):     535.6 ms ±   4.0 ms    [User: 507.6 ms, System: 75.1 ms]
    Range (min … max):   530.6 ms … 542.0 ms    10 runs
fjmolinas pushed a commit that referenced this pull request Aug 11, 2020
Coverty scan found this:

> CID 298279 (#1 of 1): Out-of-bounds read (OVERRUN)
> 21. overrun-local: Overrunning array of 16 bytes at byte offset 64 by dereferencing pointer

The original intention was probably to advance the destination pointer by 4 bytes, not
4 * the destination type size.
fjmolinas pushed a commit that referenced this pull request Aug 11, 2020
Coverty scan found this:

> CID 298295 (#1 of 1): Operands don't affect result (CONSTANT_EXPRESSION_RESULT) result_independent_of_operands:
> (ipv6_hdr_get_fl(ipv6_hdr) & 255) >> 8 is 0 regardless of the values of its operands.

Looking at the code, this appears to be a copy & paste error from the previous line.
fjmolinas pushed a commit that referenced this pull request Feb 1, 2022
The ENTROPY test always fails on this board

main(): This is RIOT! (Version: buildtest)
mbedtls test

  SHA-224 test #1: passed
  SHA-224 test #2: passed
  SHA-224 test #3: passed
  SHA-256 test #1: passed
  SHA-256 test #2: passed
  SHA-256 test #3: passed

  ENTROPY test: failed
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