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:
Graham Sanderson 2023-01-24 09:00:26 -06:00 committed by GitHub
parent a66ba7a942
commit 177b0303dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 9 deletions

View File

@ -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
* 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
*/
extern const absolute_time_t at_the_end_of_time;

View File

@ -32,6 +32,8 @@
#ifndef __CC_H__
#define __CC_H__
#include <sys/time.h>
#if NO_SYS
// todo really we should just not allow SYS_LIGHTWEIGHT_PROT for nosys mode (it doesn't do anything anyway)
typedef int sys_prot_t;

View File

@ -6,6 +6,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/times.h>
#include <unistd.h>
#include "pico.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
reset_usb_boot(0,0);
#else
@ -185,7 +188,7 @@ void __attribute__((noreturn)) _exit(__unused int status) {
#endif
}
void *_sbrk(int incr) {
__attribute__((weak)) void *_sbrk(int incr) {
extern char end; /* Set by linker. */
static char *heap_end;
char *prev_heap_end;
@ -212,6 +215,45 @@ void *_sbrk(int incr) {
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
void exit(int status) {
_exit(status);

View File

@ -263,10 +263,6 @@ platform_entry: // symbol for stack traces
blx r1
// exit should not return. If it does, hang the core.
// (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
bkpt #0
b 1b

View File

@ -7,6 +7,7 @@
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/stat.h>
#include "pico.h"
#if LIB_PICO_PRINTF_PICO
@ -172,14 +173,14 @@ int puts_raw(const char *s) {
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) {
return stdio_get_until(buffer, length, at_the_end_of_time);
}
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) {
stdio_put_string(buffer, length, false, false);
return length;
@ -187,6 +188,26 @@ int _write(int handle, char *buffer, int length) {
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) {
stdio_driver_t **prev = &drivers;
while (*prev) {