Skip to content

Commit

Permalink
newlib/libc/stdio: Make old newlib stdio bits work again
Browse files Browse the repository at this point in the history
This fixes some compile and link issues when using the old newlib
stdio bits.

 1) Include stdio64 when -Dstdio64=true is defined. This is
    needed on __linux__ systems; the configuration should
    probably be automated.

 2) Fix stdio64 to work in picolibc -- use lseek64/write64 instead
    of _lseek64_r and _write_r.

 3) Disable swprintf tests unless the library supports swprintf

 4) Extend semihosting API support to include fstat and isatty

 5) Make semihosting read/write to fd 0,1,2 use the console

 6) Add printf_float definition for non TINY_STDIO builds

Signed-off-by: Keith Packard <[email protected]>
  • Loading branch information
keith-packard committed May 4, 2020
1 parent b5039f8 commit 31e7713
Show file tree
Hide file tree
Showing 17 changed files with 283 additions and 11 deletions.
3 changes: 2 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ enable_picolib = get_option('picolib')
enable_tests = get_option('tests')
enable_native_tests = get_option('native-tests')
newlib_tinystdio = get_option('newlib-tinystdio')
stdio64 = get_option('stdio64')
have_alias_attribute_option = get_option('have-alias-attribute')
newlib_io_pos_args = get_option('newlib-io-pos-args')
newlib_io_c99_formats = get_option('newlib-io-c99-formats')
Expand Down Expand Up @@ -346,8 +347,8 @@ has_ieeefp_funcs = false
# semihost will adjust this if supported
has_semihost = false

subdir('semihost')
if newlib_tinystdio
subdir('semihost')
subdir('dummyhost')
endif

Expand Down
4 changes: 3 additions & 1 deletion meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ option('native-tests', type: 'boolean', value: false,

option('newlib-tinystdio', type: 'boolean', value: true,
description: 'Use tiny stdio from avr libc')
option('stdio64', type: 'boolean', value: true,
description: 'Include stdio64 with newlib stdio')

option('specsdir', type: 'string',
description: 'Installation directory for .specs file')
Expand Down Expand Up @@ -93,7 +95,7 @@ option('newlib-global-stdio-streams', type: 'boolean', value: false,
option('newlib-fvwrite-in-streamio', type: 'boolean', value: false,
description: 'disable iov in streamio')
option('newlib-fseek-optimization', type: 'boolean', value: false,
description: 'disable fseek optimization')
description: 'enable fseek optimization')
option('newlib-wide-orient', type: 'boolean', value: false,
description: 'Turn off wide orientation in streamio')
option('newlib-nano-malloc', type: 'boolean', value: true,
Expand Down
3 changes: 3 additions & 0 deletions newlib/libc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ if newlib_tinystdio
libdirs += 'tinystdio'
else
libdirs += ['stdio', 'reent']
if stdio64
libdirs += 'stdio64'
endif
endif

if newlib_supplied_syscalls
Expand Down
2 changes: 1 addition & 1 deletion newlib/libc/stdio64/fseeko64.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ _fseeko64_r (struct _reent *ptr,
_fpos64_t target, curoff;
size_t n;

struct stat64 st;
int havepos;

/* Only do 64-bit seek on large file. */
Expand Down Expand Up @@ -201,6 +200,7 @@ _fseeko64_r (struct _reent *ptr,
goto dumb;
if ((fp->_flags & __SOPT) == 0)
{
struct stat64 st;
if (seekfn != __sseek64
|| fp->_file < 0
|| _fstat64_r (ptr, fp->_file, &st)
Expand Down
56 changes: 56 additions & 0 deletions newlib/libc/stdio64/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# SPDX-License-Identifier: BSD-3-Clause
#
# Copyright © 2020 Keith Packard
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
#

srcs_stdio64 = [
'fdopen64.c',
'fgetpos64.c',
'fopen64.c',
'freopen64.c',
'fseeko64.c',
'fsetpos64.c',
'ftello64.c',
'stdio64.c',
'tmpfile64.c',
]
foreach target : targets
value = get_variable('target_' + target)
set_variable('lib_stdio64' + target,
static_library('stdio64' + target,
srcs_stdio64,
pic: false,
include_directories: inc,
c_args: value[1]))
endforeach

11 changes: 7 additions & 4 deletions newlib/libc/stdio64/stdio64.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@
#include "local.h"

#ifdef __LARGE64_FILES
_fpos64_t

_off64_t lseek64(int fd, _off64_t offset, int whence);

fpos64_t
__sseek64 (struct _reent *ptr,
void *cookie,
_fpos64_t offset,
Expand All @@ -34,7 +37,7 @@ __sseek64 (struct _reent *ptr,
register FILE *fp = (FILE *) cookie;
register _off64_t ret;

ret = _lseek64_r (ptr, fp->_file, (_off64_t) offset, whence);
ret = lseek64 (fp->_file, (_off64_t) offset, whence);
if (ret == (_fpos64_t)-1L)
fp->_flags &= ~__SOFF;
else
Expand All @@ -58,15 +61,15 @@ __swrite64 (struct _reent *ptr,
#endif

if (fp->_flags & __SAPP)
(void) _lseek64_r (ptr, fp->_file, (_off64_t)0, SEEK_END);
(void) lseek64 (fp->_file, (_off64_t)0, SEEK_END);
fp->_flags &= ~__SOFF; /* in case O_APPEND mode is set */

#ifdef __SCLE
if (fp->_flags & __SCLE)
oldmode = setmode(fp->_file, O_BINARY);
#endif

w = _write_r (ptr, fp->_file, buf, n);
w = write (fp->_file, buf, n);

#ifdef __SCLE
if (oldmode)
Expand Down
2 changes: 1 addition & 1 deletion newlib/testsuite/newlib.stdio/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

tests = ['nulprintf']

if not newlib_tinystdio
if not newlib_tinystdio and not newlib_nano_formatted_io and newlib_elix_level >= 4
tests += ['swprintf']
endif

Expand Down
59 changes: 59 additions & 0 deletions semihost/fstat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright © 2020 Keith Packard
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "semihost-private.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int
fstat (int fd, struct stat *sbuf )
{
int size = sys_semihost_flen(fd);

if (size > 0) {
sbuf->st_size = size;
sbuf->st_blksize = 4096;
sbuf->st_mode = S_IFREG;
} else {
sbuf->st_size = 0;
sbuf->st_blksize = 0;
sbuf->st_mode = S_IFCHR;
}
return 0;
}
50 changes: 50 additions & 0 deletions semihost/isatty.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright © 2020 Keith Packard
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "semihost-private.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

int
isatty (int fd)
{
int size = sys_semihost_flen(fd);

return size <= 0;
}
64 changes: 64 additions & 0 deletions semihost/mapstdio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright © 2020 Keith Packard
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "semihost-private.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

static int _check_done, fd_stdin, fd_stdout, fd_stderr;

int
_map_stdio(int fd)
{
if (!_check_done) {
fd_stdin = sys_semihost_open(":tt", 0);
fd_stdout = sys_semihost_open(":tt", 4);
fd_stderr = sys_semihost_open(":tt", 8);
}
switch (fd) {
case 0:
return fd_stdin;
case 1:
return fd_stdout;
case 2:
return fd_stderr;
default:
return fd;
}
}
9 changes: 8 additions & 1 deletion semihost/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ if src_semihost_machine.has_key(host_cpu_family)
srcs_semihost = [
'close.c',
'exit.c',
'iob.c',
'fstat.c',
'isatty.c',
'kill.c',
'lseek.c',
'open.c',
Expand All @@ -64,6 +65,12 @@ if src_semihost_machine.has_key(host_cpu_family)
join_paths('machine', src_semihost_machine[host_cpu_family])
]

if newlib_tinystdio
srcs_semihost += 'iob.c'
else
srcs_semihost += 'mapstdio.c'
endif

install_headers(
'semihost.h'
)
Expand Down
11 changes: 9 additions & 2 deletions semihost/open.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,16 @@ open(const char *pathname, int flags, ...)
break;
}

int ret = sys_semihost_open(pathname, semiflags);
int ret;
do {
ret = sys_semihost_open(pathname, semiflags);
}
#ifdef TINY_STDIO
while(0);
#else
while (ret <= 2);
#endif
if (ret == -1)
errno = sys_semihost_errno();
return ret;
}

3 changes: 3 additions & 0 deletions semihost/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
ssize_t
read(int fd, void *buf, size_t count)
{
#ifndef TINY_STDIO
fd = _map_stdio(fd);
#endif
uintptr_t ret = sys_semihost_read(fd, buf, count);

ssize_t got = count - (ssize_t) ret;
Expand Down
Loading

0 comments on commit 31e7713

Please sign in to comment.