Skip to content

Commit 8b733dd

Browse files
authored
Add LLVM libc sample (#538)
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.
1 parent 41e8b9f commit 8b733dd

File tree

7 files changed

+436
-0
lines changed

7 files changed

+436
-0
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,12 @@ if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL llvmlibc)
378378
COMPONENT llvm-toolchain-llvmlibc-configs
379379
)
380380

381+
install(
382+
DIRECTORY
383+
${CMAKE_CURRENT_SOURCE_DIR}/llvmlibc-samples/src
384+
DESTINATION samples
385+
COMPONENT llvm-toolchain-llvmlibc-configs
386+
)
381387
# We aren't yet able to build C++ libraries to go with llvm-libc
382388
set(CXX_LIBS OFF)
383389

docs/llvmlibc.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,21 @@ following command line options, in addition to `--target`, `-march` or
5454
`__llvm_libc_heap_limit` in addition to whatever other memory layout
5555
you want.
5656

57+
* LLVM libc does not define errno. If you are using a function that
58+
sets errno then you must implement the function `int *__llvm_libc_errno()`
59+
that returns the address of your definition of errno.
60+
5761
For example:
5862

5963
```
6064
clang --config=llvmlibc.cfg --target=arm-none-eabi -march=armv7m -o hello hello.c -lsemihost -lcrt0 -Wl,--defsym=__stack=0x200000
6165
```
6266

67+
## Samples
68+
69+
The overlay package installs a llvmlibc directory in the samples/src
70+
directory containing sample programs that use LLVM libc.
71+
6372
## Limitations of LLVM libc in LLVM Embedded Toolchain for Arm
6473

6574
At present, this toolchain does not build any C++ libraries to go with
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#
2+
# Copyright (c) 2020-2024, Arm Limited and affiliates.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
include ../../../Makefile.conf
19+
20+
build: hello.elf
21+
22+
hello.elf: *.c
23+
../$(BIN_PATH)/clang --config=llvmlibc.cfg $(MICROBIT_TARGET) -nostartfiles -lsemihost -g -fno-exceptions -fno-rtti -T microbit-llvmlibc.ld -o hello.elf $^
24+
25+
%.hex: %.elf
26+
../$(BIN_PATH)/llvm-objcopy -O ihex $< $@
27+
28+
run: hello.hex
29+
qemu-system-arm -M microbit -semihosting -nographic -device loader,file=$<
30+
31+
debug: hello.hex
32+
qemu-system-arm -M microbit -semihosting -nographic -device loader,file=$< -s -S
33+
34+
clean:
35+
rm -f *.elf *.hex
36+
37+
.PHONY: clean run debug
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) 2024, Arm Limited and affiliates.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#include <stddef.h>
17+
#include <stdlib.h>
18+
#include <string.h>
19+
#include <stdint.h>
20+
21+
extern int main(int argc, char** argv);
22+
23+
extern void _platform_init();
24+
25+
extern char __data_source[];
26+
extern char __data_start[];
27+
extern char __data_end[];
28+
extern char __data_size[];
29+
extern char __bss_start[];
30+
extern char __bss_end[];
31+
extern char __bss_size[];
32+
extern char __tls_base[];
33+
extern char __tdata_end[];
34+
extern char __tls_end[];
35+
36+
void _start(void) {
37+
memcpy(__data_start, __data_source, (size_t) __data_size);
38+
memset(__bss_start, 0, (size_t) __bss_size);
39+
_platform_init();
40+
_Exit(main(0, NULL));
41+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) 2024, Arm Limited and affiliates.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#include <assert.h>
17+
#include <stdio.h>
18+
#include <stdlib.h>
19+
#include <string.h>
20+
#include <math.h>
21+
22+
// Implementation of errno
23+
int *__llvm_libc_errno() {
24+
static int internal_err;
25+
return &internal_err;
26+
}
27+
28+
// Example that uses heap, string and math library.
29+
30+
int main(void) {
31+
const char *hello_s = "hello ";
32+
const char *world_s = "world";
33+
const size_t hello_s_len = strlen(hello_s);
34+
const size_t world_s_len = strlen(world_s);
35+
const size_t out_s_len = hello_s_len + world_s_len + 1;
36+
char *out_s = (char*) malloc(out_s_len);
37+
assert(out_s_len >= hello_s_len + 1);
38+
strncpy(out_s, hello_s, hello_s_len + 1);
39+
assert(out_s_len >= strlen(out_s) + world_s_len + 1);
40+
strncat(out_s, world_s, world_s_len + 1);
41+
// 2024-10-17 Embedded printf implementation does not currently
42+
// support printing floating point numbers.
43+
printf("%s %li\n", out_s, lround(400000 * atanf(1.0f)));
44+
free(out_s);
45+
return 0;
46+
}

0 commit comments

Comments
 (0)