-
Notifications
You must be signed in to change notification settings - Fork 97
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
Add LLVM libc sample #538
Add LLVM libc sample #538
Conversation
This will be built into the LLVM libc overlay package. Sample installs to samples/src/llvmlibc/baremetal-semihosting. * Add llvmlibc-samples directory to contain LLVM libc specific samples. * Add single baremetal-semihosting sample using LLVM libc. Sample contains a number of calls to LLVM libc functionality: * heap. * printf. * string library. * math library. A special linker script is used to set the bounds of the heap. This uses different linker defined symbols to picolibc. The crt0.S from the existing llvmlibc-support can't be used directly as the RW and ZI from the linker script need initializing.
@@ -0,0 +1,37 @@ | |||
# | |||
# Copyright (c) 2020-2023, Arm Limited and affiliates. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Copyright (c) 2020-2023, Arm Limited and affiliates. | |
# Copyright (c) 2020-2024, Arm Limited and affiliates. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll add this change in. Given I'm making other changes I'll update in a follow up commit.
/* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
* | ||
* Copyright © 2019 Keith Packard |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to add Arm copyright as well? Presumably this was tweaked to meet the needs of the sample.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was a trivial modification, but it is probably best to add the additional copyright anyway.
What's the motivation for using a separate directory structure instead of placing the new samples inside the existing |
A couple of reasons, neither particularly strong:
I'm open to opinions on what's best? |
* Update copyright date on Makefile. * Add additional copyright message on linker script. * Add missing ) in half-open interval comment in linker script.
extern char __tls_end[]; | ||
|
||
void _start(void) { | ||
memcpy(__data_start, __data_source, (uintptr_t) __data_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pedantry: formally, memcpy and memset take a size_t
, not a uintptr_t
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks will fix.
#include <string.h> | ||
#include <math.h> | ||
|
||
/* Example that uses heap, string and math library */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure you have used the math library, have you? I can only see a call to abs
, which is defined in stdlib.h
, not math.h
.
The problem with the actual math.h functions in embedded LLVM libc is that they won't make a good demo, because you can't printf the floating-point results, because FP printf is left out in the embedded build profile!
I suppose if you really wanted to demonstrate math.h functions, you could do something that has an integer final result, along the lines of lround(400000 * atan(1))
to get 314159. But it's probably also worth adding a comment explaining why you picked that example, so that when the user inevitably tries tweaking it to printf a floating-point value, they're warned why it won't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That will teach me for using the list of math functions in cppreference. Was trying to find one that returned an integer.
I've used atanf
as llvm-libc doesn't define atan
. This also showed up that I hadn't defined int *__llvm_libc_errno()
so I've added that to the docs aswell.
For consistency I'd suggest keeping everything under Could we maybe have separate sub-sirectories inside
|
* Use a function from the math library, rather than a math like function not defined in math.h. * Use size_t in memcpy/memset in startup code. * Define int *__llvm_libc_errno() as math library function requires it. * Add to documentation that you may need to define errno.
Are you OK with me doing that in a follow up change as this one currently only affects the overlay package? |
/* Example that uses heap, string and math library */ | ||
// Implementation of errno | ||
int *__llvm_libc_errno() { | ||
static int errno; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to do another pedantic one, but I recommend calling that internal variable something other than errno
. If a user starts from this code and adds #include <errno.h>
, then the name errno
will surely become a macro, making this function into nonsense. Any other name is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for spotting. I've used a name that doesn't contain errno.
Not relevant for the example but could occur if #include <errno.h> is added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the fixes. I'm happy with this now, but of course other reviewers have been commenting on entirely different aspects of the patch.
strncat(out_s, world_s, world_s_len + 1); | ||
// 2024-10-17 Embedded printf implementation does not currently | ||
// support printing floating point numbers. | ||
printf("%s %li\n", out_s, lround(400000 * atanf(1.0f))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you wrote lround
rather than lroundf
, the float returned from atanf
is being converted into a double, so this code is testing a mix of single and double precision operations.
I think that's actually a good thing – it makes it a better test! I point it out because you probably didn't do it on purpose, but I quite like it, and perhaps it's better not to "fix" it :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM too, thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you OK with me doing that in a follow up change as this one currently only affects the overlay package?
Yes, that's ok. LGTM.
This will be built into the LLVM libc overlay package. Sample installs to samples/src/llvmlibc/baremetal-semihosting.
Sample contains a number of calls to LLVM libc functionality:
A special linker script is used to set the bounds of the heap. This uses different linker defined symbols to picolibc.
The crt0.S from the existing llvmlibc-support can't be used directly as the RW and ZI from the linker script need initializing.