Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • martin/relibc
  • ashton/relibc
  • vincent/relibc
  • boomshroom/relibc
  • gmacd/relibc
  • mati865/relibc
  • nicoan/relibc
  • lmiskiew/relibc
  • devnexen/relibc
  • jamesgraves/relibc
  • oddcoder/relibc
  • andar1an/relibc
  • bitstr0m/relibc
  • gugz0r/relibc
  • matijaskala/relibc
  • 4lDO2/relibc
  • arthurpaulino/relibc
  • Majoneza/relibc
  • enygmator/relibc
  • njskalski/relibc
  • JustAnotherDev/relibc
  • darley/relibc
  • doriancodes/relibc
  • adamantinum/relibc
  • wiredtv/relibc
  • stratact/relibc
  • Ramla-I/relibc
  • bpisch/relibc
  • henritel/relibc
  • smckay/relibc
  • xTibor/relibc
  • devajithvs/relibc
  • t-nil/relibc
  • zen3ger/relibc
  • DataTriny/relibc
  • dlrobertson/relibc
  • josh/relibc
  • TheDarkula/relibc
  • willnode/relibc
  • raffaeleragni/relibc
  • redoxeon/relibc
  • athei/relibc
  • ayf/relibc
  • heghe/relibc
  • Ivan/relibc
  • hasheddan/relibc
  • dahc/relibc
  • auwardoctor/relibc
  • kodicraft/relibc
  • jasonhansel/relibc
  • kel/relibc
  • microcolonel/relibc
  • sahitpj/relibc
  • plimkilde/relibc
  • BjornTheProgrammer/relibc
  • defra/relibc
  • SteveLauC/relibc
  • josh_williams/relibc
  • jD91mZM2/relibc
  • Schyrsivochter/relibc
  • ebalalic/relibc
  • adchacon/relibc
  • aaronjanse/relibc
  • andypython/relibc
  • 8tab/relibc
  • AgostonSzepessy/relibc
  • carrot93/relibc
  • bamontan/relibc
  • zhaozhao/relibc
  • JCake/relibc
  • KGrewal1/relibc
  • feliwir/relibc
  • emturner/relibc
  • LuigiPiucco/relibc
  • RA_GM1/relibc
  • bfrascher/relibc
  • redox-os/relibc
  • kcired/relibc
  • jamespcfrancis/relibc
  • omar-mohamed-khallaf/relibc
  • neallred/relibc
  • rw_van/relibc
  • Skallwar/relibc
  • matt-vdv/relibc
  • SoyaOhnishi/relibc
  • ArniDagur/relibc
  • tlam/relibc
  • glongo/relibc
  • kamirr/relibc
  • abdullah/relibc
  • saeedtabrizi/relibc
  • sajattack/relibc
  • seanpk/relibc
  • MaikuZ/relibc
  • jamadazi/relibc
  • coolreader18/relibc
  • wt/relibc
  • lebensterben/relibc
  • starsheriff/relibc
  • uuuvn/relibc
  • vadorovsky/relibc
  • ids1024/relibc
  • freewilll/relibc
  • LLeny/relibc
  • batonius/relibc
  • alfredoyang/relibc
  • TornaxO7/relibc
  • bjorn3/relibc
  • Arcterus/relibc
  • Tommoa/relibc
  • samuela/relibc
  • mindriot101/relibc
  • lygstate/relibc
113 results
Show changes
Commits on Source (1970)
[**.c]
indent_size = 4
indent_style = space
[**.yml]
indent_size = 4
indent_style = space
**/target/
.idea/
prefix/
sysroot/
**/target/
.gdb_history
*.patch
*.swp
*.swo
/.vim
image: "rustlang/rust:nightly"
image: "redoxos/redoxer:latest"
variables:
GIT_SUBMODULE_STRATEGY: recursive
stages:
- build
- test
before_script:
- git submodule update --init --recursive
- rustup toolchain add "$(cat rust-toolchain)"
- rustup target add x86_64-unknown-redox --toolchain "$(cat rust-toolchain)"
- rustup show # Print version info for debugging
cargo install cbindgen
cache:
untracked: true
default:
cache:
paths:
- target/
build:linux:
stage: build
script:
- make all
- rustup show # Ensure correct toolchain is downloaded and installed
- make -j "$(nproc)" all
build:redox:
stage: build
variables:
TARGET: x86_64-unknown-redox
script:
# Install x86_64-unknown-redox-gcc
# This can't be in before_script because that overrides
# the global before_script.
- apt-get update -qq
- apt-get install -qq apt-transport-https build-essential curl git gnupg software-properties-common
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys AA12E97F0881517F
- add-apt-repository 'deb https://static.redox-os.org/toolchain/apt /'
- apt-get update -qq && apt-get install -qq x86-64-unknown-redox-gcc
# Main script
- make all
- ./redoxer.sh -j "$(nproc)" all
test:linux:
stage: test
needs:
- build:linux
dependencies:
- build:linux
script:
- make test
- cd tests && make verify
#TODO: fix redoxer exec hangs
# test:redox:
# stage: test
# needs:
# - build:redox
# dependencies:
# - build:redox
# variables:
# TARGET: x86_64-unknown-redox
# script:
# - ./redoxer.sh test
# # TODO: Out of memory
# allow_failure: true
fmt:
stage: test
needs: []
script:
- rustup component add rustfmt-preview
- ./fmt.sh -- --check
allow_failure: true
[submodule "openlibm"]
path = openlibm
url = https://gitlab.redox-os.org/redox-os/openlibm.git
[submodule "cbindgen"]
path = cbindgen
url = https://gitlab.redox-os.org/redox-os/cbindgen.git
[submodule "ralloc"]
path = ralloc
url = https://gitlab.redox-os.org/redox-os/ralloc.git
[submodule "va_list"]
path = va_list
url = https://gitlab.redox-os.org/redox-os/va_list-rs.git
url = https://github.com/JuliaMath/openlibm.git
branch = master
[submodule "posix-regex"]
path = posix-regex
url = https://gitlab.redox-os.org/redox-os/posix-regex.git
[submodule "compiler-builtins"]
path = compiler-builtins
url = https://gitlab.redox-os.org/redox-os/compiler-builtins.git
branch = relibc_fix_dup_symbols
[submodule "src/dlmalloc-rs"]
path = dlmalloc-rs
url = https://gitlab.redox-os.org/redox-os/dlmalloc-rs.git
language: rust
env:
-
- TARGET=aarch64-unknown-linux-gnu
- TARGET=x86_64-unknown-redox
rust:
- nightly
install:
- if [ $TARGET == "aarch64-unknown-linux-gnu" ]; then sudo apt-get install gcc-aarch64-linux-gnu; fi
before_script:
- rustup component add rustfmt-preview
- if [ -n "$TARGET" ]; then rustup target add $TARGET; fi
script:
- ./ci.sh
notifications:
email: false
{
"cmake.ignoreCMakeListsMissing": true
}
\ No newline at end of file
# Contributing
## Table of contents
1. [What to do](#what-to-do)
2. [Code style](#code-style)
3. [Sending merge requests](#sending-merge-requests)
4. [Writing tests](#writing-tests)
5. [Running tests](#running-tests)
Maintaining a libc is tough work, and we'd love some help!
## What to do
For now, we are still trying to get full libc compatibility before we move on to
any optimisation.
- We currently have a number of unimplemented functions. Search for
`unimplemented!()` and hop right in!
- If you notice any missing functionality, feel free to add it in
## Code style
We have a `rustfmt.toml` in the root directory of relibc. Please run `./fmt.sh`
before sending in any merge requests as it will automatically format your code.
With regards to general style:
### Where applicable, prefer using references to raw pointers
This is most obvious when looking at `stdio` functions. If raw pointers were
used instead of references, then the resulting code would be significantly
uglier. Instead try to check for pointer being valid with `pointer::as_ref()`
and `pointer::as_mut()` and then immediately use those references instead.
Internal functions should always take references.
### Use the c types exposed in our platform module instead of Rust's inbuilt integer types
This is so we can guarantee that everything works across platforms. While it is
generally accepted these days that an `int` has 32 bits (which matches against
an `i32`), some platforms have `int` as having 16 bits, and others have long as
being 32 bits instead of 64. If you use the types in platform, then we can
guarantee that your code will "just work" should we port relibc to a different
architecture.
### Use our internal functions
If you need to use a C string, don't reinvent the wheel. We have functions in
the platform module that convert C strings to Rust slices.
We also have structures that wrap files, wrap writable strings, and wrap various
other commonly used things that you should use instead of rolling your own.
## Sending merge requests
If you have sent us a merge request, first of all, thanks for taking your time
to help us!
The first thing to note is that we do most of our development on our
[GitLab server](https://gitlab.redox-os.org/redox-os/relibc), and as such it is
possible that none of the maintainers will see your merge request if it is
opened on GitHub.
In your merge request, please put in the description:
- What functions (if any) have been implemented or changed
- The rationale behind your merge request (e.g. why you thought this change was
required. If you are just implementing some functions, you can ignore this)
- Any issues that are related to the merge request
We have CI attached to our GitLab instance, so all merge requests are checked to
make sure that they are tested before they are merged. Please write tests for
the functions that you add/change and test locally on your own machine
***before*** submitting a merge request.
## Writing tests
Every function that gets written needs to have a test in C in order to make sure
it works as intended. Here are a few guidelines for writing good tests.
### Ensure that any literals you have are mapped to variables instead of being directly passed to a function.
Sometimes compilers take literals put into libc functions and run them
internally during compilation, which can cause some false positives. All tests
are compiled with `-fno-builtin`, which theoretically solves this issue, but
just in case, it'd be a good idea to map inputs to variables.
```c
#include "string.h"
#include "stdio.h"
int main(void) {
// Don't do this
printf("%d\n", strcspn("Hello", "Hi"));
// Do this
char *first = "Hello";
char *second = "Hi";
printf("%d\n", strcspn(first, second));
}
```
### Ensure your tests cover every section of code.
What happens if a string in `strcmp()` is shorter than the other string? What
happens if the first argument to `strcspn()` is longer than the second string?
In order to make sure that all functions work as expected, we ask that any tests
cover as much of the code that you have written as possible.
## Running tests
Running tests is an important part in trying to find bugs. Before opening a
merge request, we ask that you test on your own machine to make sure there are
no regressions.
You can run tests with `make test` in the root directory of relibc to compile
relibc, compile the tests and run them. This *will* print a lot of output to
stdout, so be warned!
You can test against verified correct output with `make verify` in the tests
directory. You will need to manually create the correct output and put it in the
tests/expected directory. Running any `make` commands in the tests directory
will ***not*** rebuild relibc, so you'll need to go back to the root directory
if you need to rebuild relibc.
This diff is collapsed.
[package]
name = "relibc"
version = "0.1.0"
version = "0.2.5"
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
edition = "2021"
[lib]
name = "c"
name = "relibc"
crate-type = ["staticlib"]
[workspace]
members = ["src/crt0", "cbindgen"]
members = [
"src/crt0",
"src/crti",
"src/crtn",
"redox-rt",
"ld_so",
"generic-rt",
]
exclude = ["tests", "dlmalloc-rs"]
[build-dependencies]
cc = "1.0.17"
cc = "1"
[dependencies]
lazy_static = { version = "*", features = ["nightly", "spin_no_std"] }
rand = { version = "0.5.2", default-features = false }
va_list = { path = "va_list", features = ["no_std"] }
bitflags = "2"
cbitset = "0.2"
posix-regex = { path = "posix-regex", features = ["no_std"] }
[dependencies.compiler_builtins]
git = "https://github.com/rust-lang-nursery/compiler-builtins.git"
default-features = false
features = ["no-lang-items", "mangled-names"]
# TODO: For some reason, rand_jitter hasn't been updated to use the latest rand_core
rand = { version = "0.8", default-features = false, features = ["small_rng"] }
rand_xorshift = "0.3"
rand_jitter = "0.4"
memchr = { version = "2.2.0", default-features = false }
plain = "0.2"
unicode-width = "0.1"
__libc_only_for_layout_checks = { package = "libc", version = "0.2.149", optional = true }
md5-crypto = { package = "md-5", version = "0.10.6", default-features = false }
sha-crypt = { version = "0.5", default-features = false }
base64ct = { version = "1.6", default-features = false, features = ["alloc"] }
bcrypt-pbkdf = { version = "0.10", default-features = false, features = [
"alloc",
] }
scrypt = { version = "0.11", default-features = false, features = ["simple"] }
pbkdf2 = { version = "0.12", features = ["sha2"] }
sha2 = { version = "0.10", default-features = false }
generic-rt = { path = "generic-rt" }
chrono-tz = {version = "0.10", default-features = false}
chrono = {version = "0.4", default-features = false, features = ["alloc"]}
libm = "0.2"
object = { version = "0.36.7", git = "https://gitlab.redox-os.org/andypython/object", default-features = false, features = ["elf", "read_core"] }
spin = "0.9.8"
[dependencies.ralloc]
path = "ralloc"
[dependencies.dlmalloc]
path = "dlmalloc-rs"
default-features = false
optional = true
features = ["c_api"]
[target.'cfg(target_os = "linux")'.dependencies]
sc = "0.2"
sc = "0.2.3"
[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = { git = "https://gitlab.redox-os.org/redox-os/syscall.git", branch = "relibc" }
spin = "0.4"
redox_syscall = "0.5.8"
redox-rt = { path = "redox-rt" }
redox-path = "0.2"
redox_event = { git = "https://gitlab.redox-os.org/redox-os/event.git", default-features = false, features = [
"redox_syscall",
] }
[features]
default = ["check_against_libc_crate"]
trace = []
check_against_libc_crate = ["__libc_only_for_layout_checks"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
[patch.crates-io]
cc-11 = { git = "https://github.com/tea/cc-rs", branch = "riscv-abi-arch-fix", package = "cc" }
TARGET?=
BUILD=target
ifneq ($(TARGET),)
BUILD="target/$(TARGET)"
CARGOFLAGS+="--target=$(TARGET)"
ifndef TARGET
export TARGET:=$(shell rustc -Z unstable-options --print target-spec-json | grep llvm-target | cut -d '"' -f4)
endif
CARGO?=cargo
CARGO_TEST?=$(CARGO)
CARGO_COMMON_FLAGS=-Z build-std=core,alloc,compiler_builtins
CARGOFLAGS?=$(CARGO_COMMON_FLAGS)
RUSTCFLAGS?=
export OBJCOPY?=objcopy
BUILD?=$(shell pwd)/target/$(TARGET)
CARGOFLAGS+=--target=$(TARGET)
TARGET_HEADERS?=$(BUILD)/include
export CFLAGS=-I$(TARGET_HEADERS)
PROFILE?=release
HEADERS_UNPARSED=$(shell find src/header -mindepth 1 -maxdepth 1 -type d -not -name "_*" -printf "%f\n")
HEADERS_DEPS=$(shell find src/header -type f \( -name "cbindgen.toml" -o -name "*.rs" \))
#HEADERS=$(patsubst %,%.h,$(subst _,/,$(HEADERS_UNPARSED)))
ifeq ($(TARGET),aarch64-unknown-linux-gnu)
CC=aarch64-linux-gnu-gcc
export CC=aarch64-linux-gnu-gcc
export LD=aarch64-linux-gnu-ld
export AR=aarch64-linux-gnu-ar
export NM=aarch64-linux-gnu-nm
export OBJCOPY=aarch64-linux-gnu-objcopy
export CPPFLAGS=
endif
ifeq ($(TARGET),aarch64-unknown-redox)
export CC=aarch64-unknown-redox-gcc
export LD=aarch64-unknown-redox-ld
export AR=aarch64-unknown-redox-ar
export NM=aarch64-unknown-redox-nm
export OBJCOPY=aarch64-unknown-redox-objcopy
export CPPFLAGS=
endif
ifeq ($(TARGET),x86_64-unknown-linux-gnu)
export CC=x86_64-linux-gnu-gcc
export LD=x86_64-linux-gnu-ld
export AR=x86_64-linux-gnu-ar
export NM=x86_64-linux-gnu-nm
export OBJCOPY=objcopy
export CPPFLAGS=
endif
ifeq ($(TARGET),i686-unknown-redox)
export CC=i686-unknown-redox-gcc
export LD=i686-unknown-redox-ld
export AR=i686-unknown-redox-ar
export NM=i686-unknown-redox-nm
export OBJCOPY=i686-unknown-redox-objcopy
export CPPFLAGS=
endif
ifeq ($(TARGET),x86_64-unknown-redox)
CC=x86_64-unknown-redox-gcc
export CC=x86_64-unknown-redox-gcc
export LD=x86_64-unknown-redox-ld
export AR=x86_64-unknown-redox-ar
export NM=x86_64-unknown-redox-nm
export OBJCOPY=x86_64-unknown-redox-objcopy
export CPPFLAGS=
endif
ifeq ($(TARGET),riscv64gc-unknown-redox)
export CC=riscv64-unknown-redox-gcc
export LD=riscv64-unknown-redox-ld
export AR=riscv64-unknown-redox-ar
export NM=riscv64-unknown-redox-nm
export OBJCOPY=riscv64-unknown-redox-objcopy
export CPPFLAGS=-march=rv64gc -mabi=lp64d
endif
SRC=\
src/* \
src/*/* \
src/*/*/* \
src/*/*/*/*
Cargo.* \
$(shell find src -type f)
.PHONY: all clean fmt install libc libm test
BUILTINS_VERSION=0.1.70
all: | libc libm
.PHONY: all clean fmt install install-libs install-headers install-tests libs headers submodules test
all: | headers libs
headers: $(HEADERS_DEPS)
rm -rf $(TARGET_HEADERS)
mkdir -pv $(TARGET_HEADERS)
cp -rv include/* $(TARGET_HEADERS)
cp -v "openlibm/include"/*.h $(TARGET_HEADERS)
cp -v "openlibm/src"/*.h $(TARGET_HEADERS)
set -e ; \
for header in $(HEADERS_UNPARSED); do \
echo "Header $$header"; \
if test -f "src/header/$$header/cbindgen.toml"; then \
out=`echo "$$header" | sed 's/_/\//g'`; \
out="$(TARGET_HEADERS)/$$out.h"; \
cat "src/header/$$header/cbindgen.toml" cbindgen.globdefs.toml \
| cbindgen "src/header/$$header/mod.rs" --config=/dev/stdin --output "$$out"; \
fi \
done
clean:
cargo clean
make -C tests clean
$(CARGO) clean
$(MAKE) -C tests clean
rm -rf sysroot
check:
cargo check
$(CARGO) check
fmt:
./fmt.sh
install: all
mkdir -pv "$(DESTDIR)/lib"
install-headers: headers libs
mkdir -pv "$(DESTDIR)/include"
cp -rv "include"/* "$(DESTDIR)/include"
cp -rv "target/include"/* "$(DESTDIR)/include"
cp -v "$(BUILD)/release/libc.a" "$(DESTDIR)/lib"
cp -v "$(BUILD)/release/crt0.o" "$(DESTDIR)/lib"
cp -rv "openlibm/include"/* "$(DESTDIR)/include"
cp -rv "openlibm/src"/*.h "$(DESTDIR)/include"
cp -rv "$(TARGET_HEADERS)"/* "$(DESTDIR)/include"
libs: \
$(BUILD)/$(PROFILE)/libc.a \
$(BUILD)/$(PROFILE)/libc.so \
$(BUILD)/$(PROFILE)/crt0.o \
$(BUILD)/$(PROFILE)/crti.o \
$(BUILD)/$(PROFILE)/crtn.o \
$(BUILD)/$(PROFILE)/ld_so
install-libs: headers libs
mkdir -pv "$(DESTDIR)/lib"
cp -v "$(BUILD)/$(PROFILE)/libc.a" "$(DESTDIR)/lib"
cp -v "$(BUILD)/$(PROFILE)/libc.so" "$(DESTDIR)/lib"
ln -vnfs libc.so "$(DESTDIR)/lib/libc.so.6"
cp -v "$(BUILD)/$(PROFILE)/crt0.o" "$(DESTDIR)/lib"
ln -vnfs crt0.o "$(DESTDIR)/lib/crt1.o"
cp -v "$(BUILD)/$(PROFILE)/crti.o" "$(DESTDIR)/lib"
cp -v "$(BUILD)/$(PROFILE)/crtn.o" "$(DESTDIR)/lib"
cp -v "$(BUILD)/$(PROFILE)/ld_so" "$(DESTDIR)/lib/ld64.so.1"
cp -v "$(BUILD)/openlibm/libopenlibm.a" "$(DESTDIR)/lib/libm.a"
# Empty libraries for dl, pthread, and rt
$(AR) -rcs "$(DESTDIR)/lib/libdl.a"
$(AR) -rcs "$(DESTDIR)/lib/libpthread.a"
$(AR) -rcs "$(DESTDIR)/lib/librt.a"
install-tests: tests
$(MAKE) -C tests
mkdir -p "$(DESTDIR)/bin/relibc-tests"
cp -vr tests/bins_static/* "$(DESTDIR)/bin/relibc-tests/"
install: install-headers install-libs
header:
mkdir -p header
./header.sh
touch header
submodules:
git submodule sync
git submodule update --init --recursive
libc: $(BUILD)/release/libc.a $(BUILD)/release/crt0.o
sysroot:
rm -rf $@
rm -rf $@.partial
mkdir -p $@.partial
$(MAKE) install DESTDIR=$@.partial
mv $@.partial $@
touch $@
test: sysroot
# TODO: Fix SIGILL when running cargo test
# $(CARGO_TEST) test
$(MAKE) -C tests run
$(MAKE) -C tests verify
libm: $(BUILD)/openlibm/libopenlibm.a
test: all
make -C tests run
$(BUILD)/$(PROFILE)/libc.so: $(BUILD)/$(PROFILE)/librelibc.a $(BUILD)/openlibm/libopenlibm.a
$(CC) -nostdlib \
-shared \
-Wl,--gc-sections \
-Wl,-z,pack-relative-relocs \
-Wl,--sort-common \
-Wl,--allow-multiple-definition \
-Wl,--whole-archive $^ -Wl,--no-whole-archive \
-Wl,-soname,libc.so.6 \
-lgcc \
-o $@
$(BUILD)/debug/libc.a: $(SRC)
cargo build $(CARGOFLAGS)
# Debug targets
$(BUILD)/debug/libc.a: $(BUILD)/debug/librelibc.a $(BUILD)/openlibm/libopenlibm.a
echo "create $@" > "$@.mri"
for lib in $^; do\
echo "addlib $$lib" >> "$@.mri"; \
done
echo "save" >> "$@.mri"
echo "end" >> "$@.mri"
$(AR) -M < "$@.mri"
$(BUILD)/debug/librelibc.a: $(SRC)
$(CARGO) rustc $(CARGOFLAGS) -- --emit link=$@ -g -C debug-assertions=no $(RUSTCFLAGS)
./renamesyms.sh "$@" "$(BUILD)/debug/deps/"
touch $@
$(BUILD)/debug/crt0.o: $(SRC)
CARGO_INCREMENTAL=0 cargo rustc --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
$(CARGO) rustc --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/debug/crti.o: $(SRC)
$(CARGO) rustc --manifest-path src/crti/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/debug/crtn.o: $(SRC)
$(CARGO) rustc --manifest-path src/crtn/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/debug/ld_so.o: $(SRC)
$(CARGO) rustc --manifest-path ld_so/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort -g -C debug-assertions=no $(RUSTCFLAGS)
touch $@
$(BUILD)/release/libc.a: $(SRC)
cargo build --release $(CARGOFLAGS)
$(BUILD)/debug/ld_so: $(BUILD)/debug/ld_so.o $(BUILD)/debug/crti.o $(BUILD)/debug/libc.a $(BUILD)/debug/crtn.o
$(LD) --no-relax -T ld_so/ld_script/$(TARGET).ld --allow-multiple-definition --gc-sections $^ -o $@
# Release targets
$(BUILD)/release/libc.a: $(BUILD)/release/librelibc.a $(BUILD)/openlibm/libopenlibm.a
echo "create $@" > "$@.mri"
for lib in $^; do\
echo "addlib $$lib" >> "$@.mri"; \
done
echo "save" >> "$@.mri"
echo "end" >> "$@.mri"
$(AR) -M < "$@.mri"
$(BUILD)/release/librelibc.a: $(SRC)
$(CARGO) rustc --release $(CARGOFLAGS) -- --emit link=$@ $(RUSTCFLAGS)
# TODO: Better to only allow a certain whitelisted set of symbols? Perhaps
# use some cbindgen hook, specify them manually, or grep for #[no_mangle].
./renamesyms.sh "$@" "$(BUILD)/release/deps/"
touch $@
$(BUILD)/release/crt0.o: $(SRC)
CARGO_INCREMENTAL=0 cargo rustc --release --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
$(CARGO) rustc --release --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/release/crti.o: $(SRC)
$(CARGO) rustc --release --manifest-path src/crti/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/release/crtn.o: $(SRC)
$(CARGO) rustc --release --manifest-path src/crtn/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/release/ld_so.o: $(SRC)
$(CARGO) rustc --release --manifest-path ld_so/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@ -C panic=abort $(RUSTCFLAGS)
touch $@
$(BUILD)/release/ld_so: $(BUILD)/release/ld_so.o $(BUILD)/release/crti.o $(BUILD)/release/libc.a $(BUILD)/release/crtn.o
$(LD) --no-relax -T ld_so/ld_script/$(TARGET).ld --allow-multiple-definition --gc-sections $^ -o $@
# Other targets
$(BUILD)/openlibm: openlibm
rm -rf $@ $@.partial
mkdir -p $(BUILD)
......@@ -80,5 +260,6 @@ $(BUILD)/openlibm: openlibm
mv $@.partial $@
touch $@
$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm
make CC=$(CC) CPPFLAGS="-fno-stack-protector -I$(shell pwd)/include -I $(shell pwd)/target/include" -C $< libopenlibm.a
$(BUILD)/openlibm/libopenlibm.a: $(BUILD)/openlibm $(BUILD)/release/librelibc.a
$(MAKE) AR=$(AR) CC=$(CC) LD=$(LD) CPPFLAGS="$(CPPFLAGS) -fno-stack-protector -I$(shell pwd)/include -I$(TARGET_HEADERS)" -C $< libopenlibm.a
./renamesyms.sh "$@" "$(BUILD)/release/deps/"
# relibc ![build](https://travis-ci.org/redox-os/relibc.svg?branch=master)
relibc is a portable POSIX C standard library written in Rust. It is under heavy development, and currently supports Redox and Linux.
# Redox C Library (relibc)
The motivation for this project is twofold: Reduce issues the redox crew was having with newlib, and create a safer alternative to a C standard library written in C. It is mainly designed to be used under redox, as an alternative to newlib, but it also supports linux syscalls via the [sc](https://crates.io/crates/sc) crate.
relibc is a portable POSIX C standard library written in Rust and is under heavy development.
The motivation for this project is twofold: Reduce issues that the Redox developers were having with [newlib](https://sourceware.org/newlib/), and create a safer alternative to a C standard library written in C. It is mainly designed to be used under Redox, as an alternative to newlib, but it also supports Linux system calls via the [sc](https://crates.io/crates/sc) crate.
Currently Redox and Linux are supported.
## redox-rt
redox-rt is our equivalent for [vDSO](https://en.wikipedia.org/wiki/VDSO) from Linux.
## Repository Layout
- `include` - Header files (mostly macros and variadic functions `cbindgen` can't generate)
- `src` - Source files
- `src/c` - C code
- `src/crt0` - Runtime code
- `src/crti` - Runtime code
- `src/crtn` - Runtime code
- `src/header` - Header files implementation
- `src/header/*` - Each folder has a `cbindgen.toml` file, it generates a C-to-Rust interface and header files
- `src/ld_so` - Dynamic loader code
- `src/platform` - Platform-specific and common code
- `src/platform/redox` - Redox-specific code
- `src/platform/linux` - Linux-specific code
- `src/pthread` - pthread implementation
- `src/sync` - Synchronization primitives
- `tests` - C tests (each MR needs to give success in all of them)
## Download the sources
To download the relibc sources run the following command:
```sh
git clone --recursive https://gitlab.redox-os.org/redox-os/relibc
```
## Build Instructions
To build relibc out of the Redox build system, do the following steps:
### Dependencies
- Install `cbindgen`
```sh
cargo install cbindgen
```
#### Install the `expect` tool
- Debian, Ubuntu and PopOS:
```sh
sudo apt install expect
```
- Fedora:
```sh
sudo dnf install expect
```
- Arch Linux:
```sh
sudo pacman -S expect
```
### Build Relibc
To build the relibc library objects, run the following command:
```sh
make all
```
- Clean old library objects and tests
```sh
make clean
```
## Build relibc inside the Redox build system
Inside of your Redox build system, run:
```sh
make prefix
```
If you need to rebuild `relibc` for testing a Cookbook recipe, run:
```sh
touch relibc
make prefix r.recipe-name
```
Touching (changing the "last modified time" of) the `relibc` folder is needed to trigger recompilation for `make prefix`. Replace `recipe-name` with your desired recipe name.
Note: Do not edit `relibc` inside `prefix` folder! Do your work on `relibc` folder directly inside your Redox build system instead.
## Tests
This section explain how to build and run the tests.
### Build
To build the tests run `make all` on the `tests` folder, it will store the executables at `tests/bins_static`
If you did changes to your tests, run `make clean all` to rebuild the executables.
### Redox OS Testing
To test on Redox do the following steps:
- Add the `relibc-tests` recipe on your filesystem configuration at `config/your-cpu/your-config.toml` (generally `desktop.toml`)
- Run the following commands to rebuild relibc with your changes, update the `relibc-tests` recipe and update your QEMU image:
```sh
touch relibc
```
```sh
make prefix cr.relibc-tests image
```
- Run the tests
```sh
/usr/share/relibc-tests/bins_static/test-name
```
### Linux Testing
Run `make test` on the relibc directory.
If you want to run one test, run the following command:
```sh
tests/bins_static/test-name
```
## Issues
#### I'm building for my own platform which I run, and am getting `x86_64-linux-gnu-ar: command not found` (or similar)
The Makefile expects GNU compiler tools prefixed with the platform specifier, as would be present when you installed a cross compiler. Since you are building for your own platform, some Linux distributions (like Manjaro) don't install/symlink the prefixed executables.
An easy fix would be to replace the corresponding lines in the Makefile, e.g.
```diff
ifeq ($(TARGET),x86_64-unknown-linux-gnu)
export CC=x86_64-linux-gnu-gcc
- export LD=x86_64-linux-gnu-ld
- export AR=x86_64-linux-gnu-ar
+ export LD=ld
+ export AR=ar
export OBJCOPY=x86_64-linux-gnu-objcopy
endif
```
## Contributing
Just search for any invocation of the `unimplemented` macro, and hop in! The ci server checks builds for linux and redox, checks formatting (via rustfmt), and runs the test suite. Run `ci.sh` locally to check that your changes will pass travis. Use `fmt.sh` to format your code and `make test` to run the C test suite.
Before starting to contribute, read [this](CONTRIBUTING.md) document.
## Supported OSes
- Redox OS
- Linux
- Redox OS
- Linux
## Supported architectures
- x86\_64
- Aarch64
- i686 (Intel/AMD)
- x86_64 (Intel/AMD)
- Aarch64 (ARM64)
extern crate cc;
// use std::env;
use std::{env, fs};
fn get_target() -> String {
env::var("TARGET").unwrap_or(
option_env!("TARGET").map_or("x86_64-unknown-redox".to_string(), |x| x.to_string()),
)
}
fn main() {
// let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
//
// cc::Build::new()
// .flag("-nostdinc")
// .flag("-nostdlib")
// .flag("-I")
// .flag(&format!("{}/include", crate_dir))
// .flag("-fno-stack-protector")
// .file("src/c/dlmalloc.c")
// .file("src/c/fcntl.c")
// .file("src/c/stack_chk.c")
// .file("src/c/stdio.c")
// .file("src/c/unistd.c")
// .compile("relibc_c");
let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
let target = get_target();
println!("cargo:rerun-if-changed=src/c");
let mut cc_builder = &mut cc::Build::new();
cc_builder = cc_builder.flag("-nostdinc").flag("-nostdlib");
if target.starts_with("aarch64") {
cc_builder = cc_builder.flag("-mno-outline-atomics")
}
cc_builder
.flag("-fno-stack-protector")
.flag("-Wno-expansion-to-defined")
.files(
fs::read_dir("src/c")
.expect("src/c directory missing")
.map(|res| res.expect("read_dir error").path()),
)
.compile("relibc_c");
println!("cargo:rustc-link-lib=static=relibc_c");
}
Subproject commit 95821b3bbe857354e3fb1efa96ed5252ecc3ec3e
# needs a leading newline
[defines]
"target_os=redox" = "__redox__"
"target_os=linux" = "__linux__"
"target_pointer_width=64" = "__LP64__"
"target_pointer_width=32" = "__LP32__"
"target_arch=x86" = "__i386__"
"target_arch=x86_64" = "__x86_64__"
"target_arch=aarch64" = "__aarch64__"
# This is not exact. It should be `defined(__riscv) && defined(__LP64__)`, or `defined(__riscv) && __riscv_xlen==64`
# This will do however, as long as we only support riscv64 and not riscv32
"target_arch=riscv64" = "__riscv"
# XXX: silences a warning
"feature = no_std" = "__relibc__"
# Ensure attributes are passed down from Rust
# <features.h> must be included where attributes are used in relibc
[fn]
must_use = "__nodiscard"
deprecated = "__deprecated"
deprecated_with_note = "__deprecatedNote({})"
no_return = "__noreturn"
#!/bin/bash
set -ex
./fmt.sh -- --write-mode=diff
./fmt.sh -- --check
if [ -z "$TARGET" ]
then
make all
make test
else
make libc
make libs
fi
Subproject commit 2242e05dc862f221fa1c0cc8ef23f0e9595b1dfa
#!/usr/bin/env bash
ARGS=()
for crate in relibc $(find src -name Cargo.toml | cut -d '/' -f2 | grep -v template)
do
ARGS+=("--package" "$crate")
done
cargo fmt "${ARGS[@]}" "$@"
cargo fmt --package relibc --package crt0 --package redox-rt "$@"
[package]
name = "netinet"
name = "generic-rt"
version = "0.1.0"
authors = ["Dan Robertson <danlrobertson89@gmail.com>"]
edition = "2021"
[dependencies]
in_h = { path = "in" }
#![no_std]
#![feature(core_intrinsics)]
use core::{
arch::asm,
mem::{self, offset_of},
};
#[derive(Debug)]
#[repr(C)]
pub struct GenericTcb<Os> {
/// Pointer to the end of static TLS. Must be the first member
pub tls_end: *mut u8,
/// Size of the memory allocated for the static TLS in bytes (multiple of page size)
pub tls_len: usize,
/// Pointer to this structure
pub tcb_ptr: *mut Self,
/// Size of the memory allocated for this structure in bytes (should be same as page size)
pub tcb_len: usize,
pub os_specific: Os,
}
impl<Os> GenericTcb<Os> {
/// Architecture specific code to read a usize from the TCB - aarch64
#[inline(always)]
#[cfg(target_arch = "aarch64")]
pub unsafe fn arch_read(offset: usize) -> usize {
let abi_ptr: usize;
asm!(
"mrs {}, tpidr_el0",
out(reg) abi_ptr,
);
let tcb_ptr = *(abi_ptr as *const usize);
*((tcb_ptr + offset) as *const usize)
}
/// Architecture specific code to read a usize from the TCB - x86
#[inline(always)]
#[cfg(target_arch = "x86")]
pub unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"
mov {}, gs:[{}]
",
out(reg) value,
in(reg) offset,
);
value
}
/// Architecture specific code to read a usize from the TCB - x86_64
#[inline(always)]
#[cfg(target_arch = "x86_64")]
pub unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"
mov {}, fs:[{}]
",
out(reg) value,
in(reg) offset,
);
value
}
/// Architecture specific code to read a usize from the TCB - riscv64
#[inline(always)]
#[cfg(target_arch = "riscv64")]
unsafe fn arch_read(offset: usize) -> usize {
let value;
asm!(
"ld {value}, -8(tp)", // TCB
"add {value}, {value}, {offset}",
"ld {value}, 0({value})",
value = out(reg) value,
offset = in(reg) offset,
);
value
}
pub unsafe fn current_ptr() -> Option<*mut Self> {
let tcb_ptr = Self::arch_read(offset_of!(Self, tcb_ptr)) as *mut Self;
let tcb_len = Self::arch_read(offset_of!(Self, tcb_len));
if tcb_ptr.is_null() || tcb_len < mem::size_of::<Self>() {
None
} else {
Some(tcb_ptr)
}
}
pub unsafe fn current() -> Option<&'static mut Self> {
Some(&mut *Self::current_ptr()?)
}
}
pub fn panic_notls(msg: impl core::fmt::Display) -> ! {
//eprintln!("panicked in ld.so: {}", msg);
core::intrinsics::abort();
}
pub trait ExpectTlsFree {
type Unwrapped;
fn expect_notls(self, msg: &str) -> Self::Unwrapped;
}
impl<T, E: core::fmt::Debug> ExpectTlsFree for Result<T, E> {
type Unwrapped = T;
fn expect_notls(self, msg: &str) -> T {
match self {
Ok(t) => t,
Err(err) => panic_notls(format_args!(
"{}: expect failed for Result with err: {:?}",
msg, err
)),
}
}
}
impl<T> ExpectTlsFree for Option<T> {
type Unwrapped = T;
fn expect_notls(self, msg: &str) -> T {
match self {
Some(t) => t,
None => panic_notls(format_args!("{}: expect failed for Option", msg)),
}
}
}
#!/usr/bin/env bash
set -ex
header="$(realpath header)"
cbindgen="$(realpath cbindgen)"
for config in src/header/*/cbindgen.toml
do
dir="$(dirname "$config")"
name="$(basename "$dir")"
pushd "$dir"
cargo run --release --manifest-path "$cbindgen/Cargo.toml" -- \
-c cbindgen.toml -o "$header/$name.h" mod.rs
popd
done