Ben Hutchings
2018-Jul-17 02:08 UTC
[klibc] [PATCH klibc 1/2] rename, renameat: Use renameat2() system call
New architectures only define the renameat2() system call, which was added in Linux 3.15. Define rename() and renameat() as wrappers for it if necessary. Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- --- a/usr/klibc/Kbuild +++ b/usr/klibc/Kbuild @@ -59,7 +59,8 @@ klib-y += vsnprintf.o snprintf.o vsprint inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ accept.o send.o recv.o \ - access.o chmod.o chown.o dup2.o mknod.o poll.o rename.o stat.o \ + access.o chmod.o chown.o dup2.o mknod.o poll.o rename.o renameat.o \ + stat.o \ lchown.o link.o rmdir.o unlink.o utimes.o lstat.o mkdir.o \ readlink.o select.o symlink.o pipe.o \ ctype/isalnum.o ctype/isalpha.o ctype/isascii.o \ --- a/usr/klibc/rename.c +++ b/usr/klibc/rename.c @@ -5,7 +5,7 @@ int rename(const char *oldpath, const char *newpath) { - return renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath); + return renameat2(AT_FDCWD, oldpath, AT_FDCWD, newpath, 0); } #endif /* __NR_rename */ --- /dev/null +++ b/usr/klibc/renameat.c @@ -0,0 +1,12 @@ +#include <fcntl.h> +#include <stdio.h> + +#ifndef __NR_renameat + +int renameat(int olddirfd, const char *oldpath, + int newdirfd, const char *newpath) +{ + return renameat2(olddirfd, oldpath, newdirfd, newpath, 0); +} + +#endif /* __NR_renameat */ --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -116,6 +116,7 @@ int chdir(const char *); int fchdir(int); <?> int rename(const char *, const char *); <?> int renameat(int, const char *, int, const char *); +<?> int renameat2(int, const char *, int, const char *, unsigned int); <?> int mknod(const char *, mode_t, dev_t); <?> int mknodat(int, const char *, mode_t, dev_t); <?> int chmod(const char *, mode_t); -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 811 bytes Desc: Digital signature URL: <http://www.zytor.com/pipermail/klibc/attachments/20180717/cef82a9b/attachment.sig>
RISC-V is pretty boring. I've cribbed most of this from the MIPS and AArch64 ports. I ran into difficulty with initialisation of the gp,register, which I think has to be process-global - the psABI says that signal handlers can rely on it, and they could come from any module. This means that klibc.so and the executable using it need to agree on a single value. Currently they don't, and this causes gp-relative addressing to go wrong. gp-relative addressing is introduced by "relaxation" in the linker, so I've disabled that for now. Signed-off-by: Ben Hutchings <ben at decadent.org.uk> --- --- /dev/null +++ b/usr/include/arch/riscv64/klibc/archconfig.h @@ -0,0 +1,15 @@ +/* + * include/arch/riscv64/klibc/archconfig.h + * + * See include/klibc/sysconfig.h for the options that can be set in + * this file. + * + */ + +#ifndef _KLIBC_ARCHCONFIG_H +#define _KLIBC_ARCHCONFIG_H + +/* We have an MMU but no fork() syscall */ +#define _KLIBC_NO_MMU 0 + +#endif /* _KLIBC_ARCHCONFIG_H */ --- /dev/null +++ b/usr/include/arch/riscv64/klibc/archsetjmp.h @@ -0,0 +1,27 @@ +/* + * arch/riscv64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __pc; + unsigned long __s0; + unsigned long __s1; + unsigned long __s2; + unsigned long __s3; + unsigned long __s4; + unsigned long __s5; + unsigned long __s6; + unsigned long __s7; + unsigned long __s8; + unsigned long __s9; + unsigned long __s10; + unsigned long __s11; + unsigned long __sp; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ --- /dev/null +++ b/usr/include/arch/riscv64/klibc/archsignal.h @@ -0,0 +1,14 @@ +/* + * arch/riscv/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#include <asm/signal.h> +/* No special stuff for this architecture */ + +#endif --- /dev/null +++ b/usr/include/arch/riscv64/klibc/archstat.h @@ -0,0 +1,28 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include <klibc/stathelp.h> + +#define _STATBUF_ST_NSEC + +struct stat { + __stdev64 (st_dev); /* Device */ + unsigned long st_ino; /* File serial number */ + unsigned int st_mode; /* File mode */ + unsigned int st_nlink; /* Link count */ + unsigned int st_uid; /* User ID of the file's owner */ + unsigned int st_gid; /* Group ID of the file's group */ + __stdev64 (st_rdev); /* Device number, if device */ + unsigned long __pad1; + long st_size; /* Size of file, in bytes */ + int st_blksize; /* Optimal block size for I/O */ + int __pad2; + long st_blocks; /* Number 512-byte blocks allocated */ + struct timespec st_atim; /* Time of last access */ + struct timespec st_mtim; /* Time of last modification */ + struct timespec st_ctim; /* Time of last status change */ + unsigned int __unused4; + unsigned int __unused5; +}; + +#endif --- /dev/null +++ b/usr/include/arch/riscv64/machine/asm.h @@ -0,0 +1,26 @@ +/* + * arch/riscv64/include/machine/asm.h + * + * Mostly cribbed from mips. + */ + +#ifndef _MACHINE_ASM_H +#define _MACHINE_ASM_H + +/* + * ENTRY - declare entry point + */ +#define ENTRY(symbol) \ + .globl symbol; \ + .align 2; \ + .type symbol, @function; \ +symbol: + +/* + * END - mark end of function + */ +#define END(function) \ + .size function, . - function + + +#endif /* _MACHINE_ASM_H */ --- /dev/null +++ b/usr/klibc/arch/riscv64/Kbuild @@ -0,0 +1,8 @@ +# -*- makefile -*- +# +# klibc files for riscv64 + +always := crt0.o +targets := crt0.o + +klib-y := setjmp.o syscall.o --- /dev/null +++ b/usr/klibc/arch/riscv64/MCONFIG @@ -0,0 +1,22 @@ +# -*- makefile -*- +# +# arch/riscv64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +# We should get klibc.so and the executables to agree on what gp +# should be. For now, disable gp-relative addressing. +KLIBCLDFLAGS = --no-relax +KLIBCOPTFLAGS += -Os -fomit-frame-pointer +ifeq ($(DEBUG),y) +KLIBCOPTFLAGS += -g +endif +KLIBCBITSIZE = 64 + +# Normal binaries start at 64 KB, so start the libary at 2 MB. +KLIBCSHAREDFLAGS =-Ttext 0x00200200 + +KLIBCARCHINCFLAGS = -I$(KLIBCKERNELOBJ)/arch/riscv/include --- /dev/null +++ b/usr/klibc/arch/riscv64/crt0.S @@ -0,0 +1,22 @@ +# +# arch/riscv64/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + +#include <machine/asm.h> + +ENTRY(_start) + .option push + .option norelax + lla gp, __global_pointer$ + .option pop + + mv a0, sp # Pointer to ELF entry structure + mv a1, zero # No onexit pointer + jal __libc_init +END(_start) --- /dev/null +++ b/usr/klibc/arch/riscv64/setjmp.S @@ -0,0 +1,50 @@ +/* + * arch/riscv64/setjmp.S + * + * setjmp/longjmp for the RISC-V (RV64) architecture + * + * The jmp_buf is assumed to contain the following, in order: + * pc (ra) + * s0..s11 + * sp + */ + +#include <machine/asm.h> + +ENTRY(setjmp) + sd ra, 0(a0) + sd s0, 8(a0) + sd s1, 16(a0) + sd s2, 24(a0) + sd s3, 32(a0) + sd s4, 40(a0) + sd s5, 48(a0) + sd s6, 56(a0) + sd s7, 64(a0) + sd s8, 72(a0) + sd s9, 80(a0) + sd s10, 88(a0) + sd s11, 96(a0) + sd sp, 104(a0) + mv a0, zero + jr ra +END(setjmp) + +ENTRY(longjmp) + ld ra, 0(a0) + ld s0, 8(a0) + ld s1, 16(a0) + ld s2, 24(a0) + ld s3, 32(a0) + ld s4, 40(a0) + ld s5, 48(a0) + ld s6, 56(a0) + ld s7, 64(a0) + ld s8, 72(a0) + ld s9, 80(a0) + ld s10, 88(a0) + ld s11, 96(a0) + ld sp, 104(a0) + mv a0, a1 + jr ra +END(longjmp) --- /dev/null +++ b/usr/klibc/arch/riscv64/syscall.S @@ -0,0 +1,13 @@ +#include <machine/asm.h> +#include <asm/unistd.h> + +ENTRY(__syscall_common) + scall + li t0, -4096 + bleu a0, t0, 1f + neg a0, a0 + lui t0, %hi(errno) + sw a0, %lo(errno)(t0) + li a0, -1 +1: jr ra +END(__syscall_common) --- /dev/null +++ b/usr/klibc/arch/riscv64/sysstub.ph @@ -0,0 +1,26 @@ +# -*- perl -*- +# +# arch/riscv/sysstub.ph +# +# Script to generate system call stubs +# + +# On RISC-V, most system calls follow the standard convention, with the +# system call number in x17 (a7) and the return value in x10 (a0). + +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; + + $stype = $stype || 'common'; + open(OUT, '>', "${outputdir}/${fname}.S"); + print OUT "#include <machine/asm.h>\n"; + print OUT "#include <asm/unistd.h>\n"; + print OUT "\n"; + print OUT "ENTRY(${fname})\n"; + print OUT "\tli\ta7, __NR_${sname}\n"; + print OUT "\tj\t__syscall_${stype}\n"; + print OUT "END(${fname})\n"; + close(OUT); +} + +1; --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -21,7 +21,7 @@ void _exit,exit::_exit(int); <?!ia64> pid_t clone::__clone(unsigned long, void *); <?ia64> pid_t clone::__clone2(unsigned long, void *, void *); # if ! _KLIBC_NO_MMU -<!sparc,sparc64,ia64,arm64> pid_t fork(); +<!sparc,sparc64,ia64,arm64,riscv64> pid_t fork(); <sparc,sparc64> pid_t fork at forkish(); #endif #if _KLIBC_REAL_VFORK -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 811 bytes Desc: Digital signature URL: <http://www.zytor.com/pipermail/klibc/attachments/20180717/30565c34/attachment.sig>