SYS funcs and GCC12 fixes (#1186)
* SYS functions and GCC 12 fixes * Add implementation of _gettimeofday and settimeofday, _times * Remove some GCC warnings about unimplemented SYS functions (e.g. _open) by making weak implementations that return errors. * Removed _exit from crt0.S since we have a weak version in runtime.c and we don't want two weak impls since the linker can't pick. If the user omits runtime.c then they'll need to provide _exit or get the error * Add sys/time.h to arch/cc.h for lwIP as it seems under GCC12 this is not getting included
This commit is contained in:
		@ -159,7 +159,7 @@ static inline int64_t absolute_time_diff_us(absolute_time_t from, absolute_time_
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/*! \brief The timestamp representing the end of time; this is actually not the maximum possible
 | 
					/*! \brief The timestamp representing the end of time; this is actually not the maximum possible
 | 
				
			||||||
 * timestamp, but is set to 0x7fffffff_ffffffff microseconds to avoid sign overflows with time
 | 
					 * timestamp, but is set to 0x7fffffff_ffffffff microseconds to avoid sign overflows with time
 | 
				
			||||||
 * arithmetic. This is still over 7 million years, so should be sufficient.
 | 
					 * arithmetic. This is almost 300,000 years, so should be sufficient.
 | 
				
			||||||
 * \ingroup timestamp
 | 
					 * \ingroup timestamp
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern const absolute_time_t at_the_end_of_time;
 | 
					extern const absolute_time_t at_the_end_of_time;
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,8 @@
 | 
				
			|||||||
#ifndef __CC_H__
 | 
					#ifndef __CC_H__
 | 
				
			||||||
#define __CC_H__
 | 
					#define __CC_H__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if NO_SYS
 | 
					#if NO_SYS
 | 
				
			||||||
// todo really we should just not allow SYS_LIGHTWEIGHT_PROT for nosys mode (it doesn't do anything anyway)
 | 
					// todo really we should just not allow SYS_LIGHTWEIGHT_PROT for nosys mode (it doesn't do anything anyway)
 | 
				
			||||||
typedef int sys_prot_t;
 | 
					typedef int sys_prot_t;
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <sys/time.h>
 | 
				
			||||||
 | 
					#include <sys/times.h>
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
#include "pico.h"
 | 
					#include "pico.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "hardware/regs/m0plus.h"
 | 
					#include "hardware/regs/m0plus.h"
 | 
				
			||||||
@ -175,7 +178,7 @@ void runtime_init(void) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __attribute__((noreturn)) _exit(__unused int status) {
 | 
					void __attribute__((noreturn)) __attribute__((weak)) _exit(__unused int status) {
 | 
				
			||||||
#if PICO_ENTER_USB_BOOT_ON_EXIT
 | 
					#if PICO_ENTER_USB_BOOT_ON_EXIT
 | 
				
			||||||
    reset_usb_boot(0,0);
 | 
					    reset_usb_boot(0,0);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@ -185,7 +188,7 @@ void __attribute__((noreturn)) _exit(__unused int status) {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void *_sbrk(int incr) {
 | 
					__attribute__((weak)) void *_sbrk(int incr) {
 | 
				
			||||||
    extern char end; /* Set by linker.  */
 | 
					    extern char end; /* Set by linker.  */
 | 
				
			||||||
    static char *heap_end;
 | 
					    static char *heap_end;
 | 
				
			||||||
    char *prev_heap_end;
 | 
					    char *prev_heap_end;
 | 
				
			||||||
@ -212,6 +215,45 @@ void *_sbrk(int incr) {
 | 
				
			|||||||
    return (void *) prev_heap_end;
 | 
					    return (void *) prev_heap_end;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int64_t epoch_time_us_since_boot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute__((weak)) int _gettimeofday (struct timeval *__restrict tv, __unused void *__restrict tz) {
 | 
				
			||||||
 | 
					    if (tv) {
 | 
				
			||||||
 | 
					        int64_t us_since_epoch = ((int64_t)to_us_since_boot(get_absolute_time())) - epoch_time_us_since_boot;
 | 
				
			||||||
 | 
					        tv->tv_sec = (time_t)(us_since_epoch / 1000000);
 | 
				
			||||||
 | 
					        tv->tv_usec = (suseconds_t)(us_since_epoch % 1000000);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute((weak)) int settimeofday(__unused const struct timeval *tv, __unused const struct timezone *tz) {
 | 
				
			||||||
 | 
					    if (tv) {
 | 
				
			||||||
 | 
					        int64_t us_since_epoch = tv->tv_sec * 1000000 + tv->tv_usec;
 | 
				
			||||||
 | 
					        epoch_time_us_since_boot = (int64_t)to_us_since_boot(get_absolute_time()) - us_since_epoch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute((weak)) int _times(struct tms *tms) {
 | 
				
			||||||
 | 
					#if CLOCKS_PER_SEC >= 1000000
 | 
				
			||||||
 | 
					    tms->tms_utime = to_us_since_boot(get_absolute_time()) * (CLOCKS_PER_SEC / 1000000);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    tms->tms_utime = to_us_since_boot(get_absolute_time()) / (1000000 / CLOCKS_PER_SEC);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    tms->tms_stime = 0;
 | 
				
			||||||
 | 
					    tms->tms_cutime = 0;
 | 
				
			||||||
 | 
					    tms->tms_cstime = 0;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute((weak)) pid_t _getpid(void) {
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__attribute((weak)) int _kill(__unused pid_t pid, __unused int sig) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// exit is not useful... no desire to pull in __call_exitprocs
 | 
					// exit is not useful... no desire to pull in __call_exitprocs
 | 
				
			||||||
void exit(int status) {
 | 
					void exit(int status) {
 | 
				
			||||||
    _exit(status);
 | 
					    _exit(status);
 | 
				
			||||||
 | 
				
			|||||||
@ -263,10 +263,6 @@ platform_entry: // symbol for stack traces
 | 
				
			|||||||
    blx r1
 | 
					    blx r1
 | 
				
			||||||
    // exit should not return.  If it does, hang the core.
 | 
					    // exit should not return.  If it does, hang the core.
 | 
				
			||||||
    // (fall thru into our hang _exit impl
 | 
					    // (fall thru into our hang _exit impl
 | 
				
			||||||
.weak _exit
 | 
					 | 
				
			||||||
.type _exit,%function
 | 
					 | 
				
			||||||
.thumb_func
 | 
					 | 
				
			||||||
_exit:
 | 
					 | 
				
			||||||
1: // separate label because _exit can be moved out of branch range
 | 
					1: // separate label because _exit can be moved out of branch range
 | 
				
			||||||
    bkpt #0
 | 
					    bkpt #0
 | 
				
			||||||
    b 1b
 | 
					    b 1b
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdarg.h>
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "pico.h"
 | 
					#include "pico.h"
 | 
				
			||||||
#if LIB_PICO_PRINTF_PICO
 | 
					#if LIB_PICO_PRINTF_PICO
 | 
				
			||||||
@ -172,14 +173,14 @@ int puts_raw(const char *s) {
 | 
				
			|||||||
    return len;
 | 
					    return len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int _read(int handle, char *buffer, int length) {
 | 
					int __attribute__((weak)) _read(int handle, char *buffer, int length) {
 | 
				
			||||||
    if (handle == STDIO_HANDLE_STDIN) {
 | 
					    if (handle == STDIO_HANDLE_STDIN) {
 | 
				
			||||||
        return stdio_get_until(buffer, length, at_the_end_of_time);
 | 
					        return stdio_get_until(buffer, length, at_the_end_of_time);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int _write(int handle, char *buffer, int length) {
 | 
					int __attribute__((weak)) _write(int handle, char *buffer, int length) {
 | 
				
			||||||
    if (handle == STDIO_HANDLE_STDOUT || handle == STDIO_HANDLE_STDERR) {
 | 
					    if (handle == STDIO_HANDLE_STDOUT || handle == STDIO_HANDLE_STDERR) {
 | 
				
			||||||
        stdio_put_string(buffer, length, false, false);
 | 
					        stdio_put_string(buffer, length, false, false);
 | 
				
			||||||
        return length;
 | 
					        return length;
 | 
				
			||||||
@ -187,6 +188,26 @@ int _write(int handle, char *buffer, int length) {
 | 
				
			|||||||
    return -1;
 | 
					    return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __attribute__((weak)) _open(__unused const char *fn, __unused int oflag, ...) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __attribute__((weak)) _close(__unused int fd) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					off_t __attribute__((weak)) _lseek(__unused int fd, __unused off_t pos, __unused int whence) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __attribute__((weak)) _fstat(__unused int fd, __unused struct stat *buf) {
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int __attribute__((weak)) _isatty(int fd) {
 | 
				
			||||||
 | 
					    return fd == STDIO_HANDLE_STDIN || fd == STDIO_HANDLE_STDOUT || fd == STDIO_HANDLE_STDERR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stdio_set_driver_enabled(stdio_driver_t *driver, bool enable) {
 | 
					void stdio_set_driver_enabled(stdio_driver_t *driver, bool enable) {
 | 
				
			||||||
    stdio_driver_t **prev = &drivers;
 | 
					    stdio_driver_t **prev = &drivers;
 | 
				
			||||||
    while (*prev) {
 | 
					    while (*prev) {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user