Przeglądaj źródła

VERY basic crti/crtn

jD91mZM2 6 lat temu
rodzic
commit
d659377b24
9 zmienionych plików z 161 dodań i 10 usunięć
  1. 8 0
      Cargo.lock
  2. 1 1
      Cargo.toml
  3. 12 2
      Makefile
  4. 10 0
      src/crti/Cargo.toml
  5. 58 0
      src/crti/src/lib.rs
  6. 10 0
      src/crtn/Cargo.toml
  7. 48 0
      src/crtn/src/lib.rs
  8. 4 0
      src/header/stdio/mod.rs
  9. 10 7
      tests/Makefile

+ 8 - 0
Cargo.lock

@@ -79,6 +79,14 @@ dependencies = [
  "relibc 0.1.0",
 ]
 
+[[package]]
+name = "crti"
+version = "0.1.0"
+
+[[package]]
+name = "crtn"
+version = "0.1.0"
+
 [[package]]
 name = "fuchsia-zircon"
 version = "0.3.3"

+ 1 - 1
Cargo.toml

@@ -8,7 +8,7 @@ name = "c"
 crate-type = ["staticlib"]
 
 [workspace]
-members = ["src/crt0", "cbindgen"]
+members = ["src/crt0", "src/crti", "src/crtn", "cbindgen"]
 
 [build-dependencies]
 cc = "1.0.17"

+ 12 - 2
Makefile

@@ -41,11 +41,13 @@ install: all
 	cp -rv "$(BUILD)/include"/* "$(DESTDIR)/include"
 	cp -v "$(BUILD)/release/libc.a" "$(DESTDIR)/lib"
 	cp -v "$(BUILD)/release/crt0.o" "$(DESTDIR)/lib"
+	cp -v "$(BUILD)/release/crti.o" "$(DESTDIR)/lib"
+	cp -v "$(BUILD)/release/crtn.o" "$(DESTDIR)/lib"
 	cp -rv "openlibm/include"/* "$(DESTDIR)/include"
 	cp -rv "openlibm/src"/*.h "$(DESTDIR)/include"
 	cp -v "$(BUILD)/openlibm/libopenlibm.a" "$(DESTDIR)/lib/libm.a"
 
-libc: $(BUILD)/release/libc.a $(BUILD)/release/crt0.o $(BUILD)/include
+libc: $(BUILD)/release/libc.a $(BUILD)/release/crt0.o $(BUILD)/release/crti.o $(BUILD)/release/crtn.o $(BUILD)/include
 
 libm: $(BUILD)/openlibm/libopenlibm.a
 
@@ -56,7 +58,7 @@ sysroot: all
 	mv $@.partial $@
 	touch $@
 
-test: all
+test: sysroot
 	make -C tests run
 
 $(BUILD)/debug/libc.a: $(SRC)
@@ -75,6 +77,14 @@ $(BUILD)/release/crt0.o: $(SRC)
 	CARGO_INCREMENTAL=0 cargo rustc --release --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
 	touch $@
 
+$(BUILD)/release/crti.o: $(SRC)
+	CARGO_INCREMENTAL=0 cargo rustc --release --manifest-path src/crti/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
+	touch $@
+
+$(BUILD)/release/crtn.o: $(SRC)
+	CARGO_INCREMENTAL=0 cargo rustc --release --manifest-path src/crtn/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
+	touch $@
+
 $(BUILD)/include: $(SRC)
 	rm -rf $@ $@.partial
 	mkdir -p $@.partial

+ 10 - 0
src/crti/Cargo.toml

@@ -0,0 +1,10 @@
+[package]
+name = "crti"
+version = "0.1.0"
+authors = ["jD91mZM2 <me@krake.one>"]
+
+[lib]
+name = "crti"
+crate-type = ["staticlib"]
+
+[dependencies]

+ 58 - 0
src/crti/src/lib.rs

@@ -0,0 +1,58 @@
+//! crti
+
+#![no_std]
+#![feature(global_asm)]
+#![feature(linkage)]
+#![feature(panic_implementation)]
+
+// https://wiki.osdev.org/Creating_a_C_Library#crtbegin.o.2C_crtend.o.2C_crti.o.2C_and_crtn.o
+#[cfg(target_arch = "x86_64")]
+global_asm!(r#"
+    .section .init
+    .global _init
+    _init:
+        push %rbp
+        movq %rsp, %rbp
+        // Created a new stack frame and updated the stack pointer
+        // Body will be filled in by gcc and ended by crtn.o
+
+    .section .fini
+    .global _fini
+    _fini:
+        push %rbp
+        movq %rsp, %rbp
+        // Created a new stack frame and updated the stack pointer
+        // Body will be filled in by gcc and ended by crtn.o
+"#);
+// https://git.musl-libc.org/cgit/musl/tree/crt/aarch64/crti.s
+#[cfg(target_arch = "aarch64")]
+global_asm!(r#"
+    .section .init
+    .global _init
+    .type _init,%function
+    _init:
+        stp x29,x30,[sp,-16]
+        mov x29,sp
+        // stp: "stores two doublewords from the first and second argument to memory addressed by addr"
+        // Body will be filled in by gcc and ended by crtn.o
+
+    .section .fini
+    .global _fini
+    .type _fini,%function
+    _fini:
+        stp x29,x30,[sp,-16]
+        mov x29,sp
+        // stp: "stores two doublewords from the first and second argument to memory addressed by addr"
+        // Body will be filled in by gcc and ended by crtn.o
+"#);
+
+#[panic_implementation]
+#[linkage = "weak"]
+#[no_mangle]
+pub extern "C" fn rust_begin_unwind(_pi: &::core::panic::PanicInfo) -> ! {
+    extern "C" {
+        fn exit(status: i32) -> !;
+    }
+
+    unsafe { exit(1) }
+}

+ 10 - 0
src/crtn/Cargo.toml

@@ -0,0 +1,10 @@
+[package]
+name = "crtn"
+version = "0.1.0"
+authors = ["jD91mZM2 <me@krake.one>"]
+
+[lib]
+name = "crtn"
+crate-type = ["staticlib"]
+
+[dependencies]

+ 48 - 0
src/crtn/src/lib.rs

@@ -0,0 +1,48 @@
+//! crti
+
+#![no_std]
+#![feature(global_asm)]
+#![feature(linkage)]
+#![feature(panic_implementation)]
+
+// https://wiki.osdev.org/Creating_a_C_Library#crtbegin.o.2C_crtend.o.2C_crti.o.2C_and_crtn.o
+#[cfg(target_arch = "x86_64")]
+global_asm!(r#"
+    .section .init
+        // This happens after crti.o and gcc has inserted code
+        // Pop the stack frame
+        pop %rbp
+        ret
+
+    .section .fini
+        // This happens after crti.o and gcc has inserted code
+        // Pop the stack frame
+        pop %rbp
+        ret
+"#);
+// https://git.musl-libc.org/cgit/musl/tree/crt/aarch64/crtn.s
+#[cfg(target_arch = "aarch64")]
+global_asm!(r#"
+    .section .init
+        // This happens after crti.o and gcc has inserted code
+        // ldp: "loads two doublewords from memory addressed by the third argument to the first and second"
+        ldp x29,x30,[sp],#16
+        ret
+
+    .section .fini
+        // This happens after crti.o and gcc has inserted code
+        // ldp: "loads two doublewords from memory addressed by the third argument to the first and second"
+        ldp x29,x30,[sp],#16
+        ret
+"#);
+
+#[panic_implementation]
+#[linkage = "weak"]
+#[no_mangle]
+pub extern "C" fn rust_begin_unwind(_pi: &::core::panic::PanicInfo) -> ! {
+    extern "C" {
+        fn exit(status: i32) -> !;
+    }
+
+    unsafe { exit(1) }
+}

+ 4 - 0
src/header/stdio/mod.rs

@@ -542,12 +542,14 @@ pub extern "C" fn freopen(
         }
         flags &= !(fcntl::O_CREAT | fcntl::O_EXCL | fcntl::O_CLOEXEC);
         if fcntl::sys_fcntl(stream.fd, fcntl::F_SETFL, flags) < 0 {
+            funlockfile(stream);
             fclose(stream);
             return ptr::null_mut();
         }
     } else {
         let new = fopen(filename, mode);
         if new.is_null() {
+            funlockfile(stream);
             fclose(stream);
             return ptr::null_mut();
         }
@@ -557,6 +559,7 @@ pub extern "C" fn freopen(
         } else if Sys::dup2(new.fd, stream.fd) < 0
             || fcntl::sys_fcntl(stream.fd, fcntl::F_SETFL, flags & fcntl::O_CLOEXEC) < 0
         {
+            funlockfile(stream);
             fclose(new);
             fclose(stream);
             return ptr::null_mut();
@@ -564,6 +567,7 @@ pub extern "C" fn freopen(
         stream.flags = (stream.flags & constants::F_PERM) | new.flags;
         fclose(new);
     }
+    funlockfile(stream);
     stream
 }
 

+ 10 - 7
tests/Makefile

@@ -93,33 +93,34 @@ BINS=\
 .PHONY: all $(BINS) clean run expected verify
 
 all: $(BINS)
+expect: $(EXPECT_BINS)
 
 $(BINS): %: bins/%
 
 clean:
 	rm -rf bins gen *.out
 
-run: $(BINS)
-	for bin in $^; \
+run: | ../sysroot all
+	for bin in $(BINS); \
 	do \
 		echo "# $${bin} #"; \
 		"bins/$${bin}" test args || exit $$?; \
 	done
 
-expected: $(EXPECT_BINS)
+expected: | ../sysroot expect
 	rm -rf expected
 	mkdir -p expected
-	for bin in $^; \
+	for bin in $(EXPECT_BINS); \
 	do \
 		echo "# $${bin} #"; \
 		mkdir -p expected/`dirname $${bin}`; \
 		"bins/$${bin}" test args > "expected/$${bin}.stdout" 2> "expected/$${bin}.stderr" || exit $$?; \
 	done
 
-verify: $(EXPECT_BINS)
+verify: | ../sysroot expect
 	rm -rf gen
 	mkdir -p gen
-	for bin in $^; \
+	for bin in $(EXPECT_BINS); \
 	do \
 		echo "# $${bin} #"; \
 		mkdir -p gen/`dirname $${bin}`; \
@@ -138,9 +139,11 @@ CFLAGS=\
 	-isystem ../sysroot/include
 
 HEADLIBS=\
-	../sysroot/lib/crt0.o
+	../sysroot/lib/crt0.o \
+	../sysroot/lib/crti.o
 
 TAILLIBS=\
+	../sysroot/lib/crtn.o \
 	../sysroot/lib/libc.a \
 	../sysroot/lib/libm.a