Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/llvmlibc.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ following command line options, in addition to `--target`, `-march` or
`__llvm_libc_heap_limit` in addition to whatever other memory layout
you want.

* LLVM libc does not define errno. If you are using a function that
sets errno then you must implement the function `int *__llvm_libc_errno()`
that returns the address of your definition of errno.

For example:

```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ extern char __tdata_end[];
extern char __tls_end[];

void _start(void) {
memcpy(__data_start, __data_source, (uintptr_t) __data_size);
memset(__bss_start, '\0', (uintptr_t) __bss_size);
memcpy(__data_start, __data_source, (size_t) __data_size);
memset(__bss_start, 0, (size_t) __bss_size);
_platform_init();
_Exit(main(0, NULL));
}
12 changes: 10 additions & 2 deletions llvmlibc-samples/src/llvmlibc/baremetal-semihosting/hello.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@
#include <string.h>
#include <math.h>

/* Example that uses heap, string and math library */
// Implementation of errno
int *__llvm_libc_errno() {
static int errno;
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

return &errno;
}

// Example that uses heap, string and math library.

int main(void) {
const char *hello_s = "hello ";
Expand All @@ -32,7 +38,9 @@ int main(void) {
strncpy(out_s, hello_s, hello_s_len + 1);
assert(out_s_len >= strlen(out_s) + world_s_len + 1);
strncat(out_s, world_s, world_s_len + 1);
printf("%s %d\n", out_s, abs(-3));
// 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)));
Copy link
Collaborator

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 :-)

free(out_s);
return 0;
}
Loading