#!/usr/bin/env python3
-# Copyright (C) 1996-2021 Free Software Foundation, Inc.
+# Copyright (C) 1996-2023 Free Software Foundation, Inc.
#
# This file is part of the GNU simulators.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""Helper to generate nltvals.def.
+"""Helper to generate target-newlib-* files.
-nltvals.def is a file that describes various newlib/libgloss target values used
+target-newlib-* are files that describe various newlib/libgloss values used
by the host/target interface. This needs to be rerun whenever the newlib source
changes. Developers manually run it.
TARGET_DIRS = {
'cr16': 'libgloss/cr16/sys',
'd10v': 'newlib/libc/sys/d10v/sys',
- 'i960': 'libgloss/i960',
+ # Port removed from the tree years ago.
+ #'i960': 'libgloss/i960',
'mcore': 'libgloss/mcore',
'riscv': 'libgloss/riscv/machine',
'sh': 'newlib/libc/sys/sh/sys',
return ret
-def gentvals(output_dir: Path, output: TextIO,
+def gentvals(output_dir: Path,
cpp: str, srctype: str, srcdir: Path,
headers: Iterable[str],
pattern: str,
syms = extract_syms(cpp, srcdir, headers, pattern, filter)
- # If we have a map file, use it directly.
target_map = output_dir / f'target-newlib-{srctype}.c'
- if target_map.exists():
- old_lines = target_map.read_text().splitlines()
- start_i = end_i = None
- for i, line in enumerate(old_lines):
- if START_MARKER in line:
- start_i = i
- if END_MARKER in line:
- end_i = i
- assert start_i and end_i
- new_lines = old_lines[0:start_i + 1]
- new_lines.extend(
- f'#ifdef {sym}\n'
- f' {{ "{sym}", {sym}, {val} }},\n'
- f'#endif' for sym, val in sorted(syms.items()))
- new_lines.extend(old_lines[end_i:])
- target_map.write_text('\n'.join(new_lines) + '\n')
- return
-
- # Fallback to classic nltvals.def.
- if target is not None:
- print(f'#ifdef NL_TARGET_{target}', file=output)
- print(f'#ifdef {srctype}_defs', file=output)
-
- print('\n'.join(f'/* from {x} */' for x in headers), file=output)
-
- if target is None:
- print(f'/* begin {srctype} target macros */', file=output)
- else:
- print(f'/* begin {target} {srctype} target macros */', file=output)
-
- for sym, val in sorted(syms.items()):
- print(f' {{ "{sym}", {val} }},', file=output)
-
- print(f'#undef {srctype}_defs', file=output)
- if target is None:
- print(f'/* end {srctype} target macros */', file=output)
- else:
- print(f'/* end {target} {srctype} target macros */', file=output)
- print('#endif', file=output)
- print('#endif', file=output)
-
-
-def gen_common(output_dir: Path, output: TextIO, newlib: Path, cpp: str):
+ assert target_map.exists(), f'{target_map}: Missing skeleton'
+ old_lines = target_map.read_text().splitlines()
+ start_i = end_i = None
+ for i, line in enumerate(old_lines):
+ if START_MARKER in line:
+ start_i = i
+ if END_MARKER in line:
+ end_i = i
+ assert start_i and end_i
+ new_lines = old_lines[0:start_i + 1]
+ new_lines.extend(
+ f'#ifdef {sym}\n'
+ f' {{ "{sym}", {sym}, {val} }},\n'
+ f'#endif' for sym, val in sorted(syms.items()))
+ new_lines.extend(old_lines[end_i:])
+ target_map.write_text('\n'.join(new_lines) + '\n')
+
+
+def gen_common(output_dir: Path, newlib: Path, cpp: str):
"""Generate the common C library constants.
No arch should override these.
"""
- gentvals(output_dir, output, cpp, 'errno', newlib / 'newlib/libc/include',
+ gentvals(output_dir, cpp, 'errno', newlib / 'newlib/libc/include',
('errno.h', 'sys/errno.h'), 'E[A-Z0-9]*')
- gentvals(output_dir, output, cpp, 'signal', newlib / 'newlib/libc/include',
+ gentvals(output_dir, cpp, 'signal', newlib / 'newlib/libc/include',
('signal.h', 'sys/signal.h'), r'SIG[A-Z0-9]*', filter=r'SIGSTKSZ')
- gentvals(output_dir, output, cpp, 'open', newlib / 'newlib/libc/include',
+ gentvals(output_dir, cpp, 'open', newlib / 'newlib/libc/include',
('fcntl.h', 'sys/fcntl.h', 'sys/_default_fcntl.h'), r'O_[A-Z0-9]*')
-def gen_targets(output_dir: Path, output: TextIO, newlib: Path, cpp: str):
- """Generate the target-specific lists."""
+def gen_target_syscall(output_dir: Path, newlib: Path, cpp: str):
+ """Generate the target-specific syscall lists."""
+ target_map_c = output_dir / 'target-newlib-syscall.c'
+ old_lines_c = target_map_c.read_text().splitlines()
+ start_i = end_i = None
+ for i, line in enumerate(old_lines_c):
+ if START_MARKER in line:
+ start_i = i
+ if END_MARKER in line:
+ end_i = i
+ assert start_i and end_i, f'{target_map_c}: Unable to find markers'
+ new_lines_c = old_lines_c[0:start_i + 1]
+ new_lines_c_end = old_lines_c[end_i:]
+
+ target_map_h = output_dir / 'target-newlib-syscall.h'
+ old_lines_h = target_map_h.read_text().splitlines()
+ start_i = end_i = None
+ for i, line in enumerate(old_lines_h):
+ if START_MARKER in line:
+ start_i = i
+ if END_MARKER in line:
+ end_i = i
+ assert start_i and end_i, f'{target_map_h}: Unable to find markers'
+ new_lines_h = old_lines_h[0:start_i + 1]
+ new_lines_h_end = old_lines_h[end_i:]
+
+ headers = ('syscall.h',)
+ pattern = r'SYS_[_a-zA-Z0-9]*'
+
+ # Output the target-specific syscalls.
for target, subdir in sorted(TARGET_DIRS.items()):
- gentvals(output_dir, output, cpp, 'sys', newlib / subdir,
- ('syscall.h',), r'SYS_[_a-zA-Z0-9]*', target=target)
+ syms = extract_syms(cpp, newlib / subdir, headers, pattern)
+ new_lines_c.append(f'CB_TARGET_DEFS_MAP cb_{target}_syscall_map[] = {{')
+ new_lines_c.extend(
+ f'#ifdef CB_{sym}\n'
+ ' { '
+ f'"{sym[4:]}", CB_{sym}, TARGET_NEWLIB_{target.upper()}_{sym}'
+ ' },\n'
+ '#endif' for sym in sorted(syms))
+ new_lines_c.append(' {NULL, -1, -1},')
+ new_lines_c.append('};\n')
+
+ new_lines_h.append(
+ f'extern CB_TARGET_DEFS_MAP cb_{target}_syscall_map[];')
+ new_lines_h.extend(
+ f'#define TARGET_NEWLIB_{target.upper()}_{sym} {val}'
+ for sym, val in sorted(syms.items()))
+ new_lines_h.append('')
# Then output the common syscall targets.
- gentvals(output_dir, output, cpp, 'sys', newlib / 'libgloss',
- ('syscall.h',), r'SYS_[_a-zA-Z0-9]*')
+ syms = extract_syms(cpp, newlib / 'libgloss', headers, pattern)
+ new_lines_c.append(f'CB_TARGET_DEFS_MAP cb_init_syscall_map[] = {{')
+ new_lines_c.extend(
+ f'#ifdef CB_{sym}\n'
+ f' {{ "{sym[4:]}", CB_{sym}, TARGET_NEWLIB_{sym} }},\n'
+ f'#endif' for sym in sorted(syms))
+ new_lines_c.append(' {NULL, -1, -1},')
+ new_lines_c.append('};')
+ new_lines_h.append('extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];')
+ new_lines_h.extend(
+ f'#define TARGET_NEWLIB_{sym} {val}'
+ for sym, val in sorted(syms.items()))
-def gen(output_dir: Path, output: TextIO, newlib: Path, cpp: str):
+ new_lines_c.extend(new_lines_c_end)
+ target_map_c.write_text('\n'.join(new_lines_c) + '\n')
+
+ new_lines_h.extend(new_lines_h_end)
+ target_map_h.write_text('\n'.join(new_lines_h) + '\n')
+
+
+def gen_targets(output_dir: Path, newlib: Path, cpp: str):
+ """Generate the target-specific lists."""
+ gen_target_syscall(output_dir, newlib, cpp)
+
+
+def gen(output_dir: Path, newlib: Path, cpp: str):
"""Generate all the things!"""
- print(FILE_HEADER, file=output)
- gen_common(output_dir, output, newlib, cpp)
- gen_targets(output_dir, output, newlib, cpp)
+ gen_common(output_dir, newlib, cpp)
+ gen_targets(output_dir, newlib, cpp)
def get_parser() -> argparse.ArgumentParser:
"""The main entry point for scripts."""
opts = parse_args(argv)
- output = (opts.output / 'nltvals.def').open('w', encoding='utf-8')
-
- gen(opts.output, output, opts.newlib, opts.cpp)
+ gen(opts.output, opts.newlib, opts.cpp)
return 0