From e280469cee39b4d4a4529ee63f4560f6fb1d6bc9 Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Tue, 28 Feb 2023 18:19:20 +0100 Subject: [PATCH] [machdep] add ssize_t and weof to schema + auto regenerate default machdeps Now, only msvc_x86_64 and gcc_x86_16 need to be edited by hand when schema changes --- share/machdeps/Makefile | 20 ++++++++++ share/machdeps/machdep-schema.yaml | 12 ++++++ share/machdeps/machdep_avr_16.yaml | 3 +- share/machdeps/machdep_gcc_x86_16.yaml | 2 + share/machdeps/machdep_gcc_x86_32.yaml | 2 + share/machdeps/machdep_gcc_x86_64.yaml | 3 +- share/machdeps/machdep_msvc_x86_64.yaml | 2 + share/machdeps/machdep_ppc_32.yaml | 3 +- share/machdeps/machdep_x86_16.yaml | 2 + share/machdeps/machdep_x86_32.yaml | 4 +- share/machdeps/machdep_x86_64.yaml | 4 +- share/machdeps/make_machdep/make_machdep.py | 38 +++++++++++++++++-- share/machdeps/make_machdep/ssize_t.c | 30 +++++++++++++++ share/machdeps/make_machdep/weof.c | 3 ++ src/kernel_internals/runtime/machdep.ml | 6 +-- src/kernel_services/ast_data/cil_types.ml | 2 + .../ast_queries/cil_datatype.ml | 2 + tests/misc/custom_machdep.ml | 2 + tests/misc/custom_machdep.yaml | 2 + tests/syntax/machdep_char_unsigned.ml | 3 +- 20 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 share/machdeps/Makefile create mode 100644 share/machdeps/make_machdep/ssize_t.c create mode 100644 share/machdeps/make_machdep/weof.c diff --git a/share/machdeps/Makefile b/share/machdeps/Makefile new file mode 100644 index 00000000000..348bb70e140 --- /dev/null +++ b/share/machdeps/Makefile @@ -0,0 +1,20 @@ +update-all: machdep_*.yaml + +machdep_avr_16.yaml \ +machdep_gcc_x86_32.yaml \ +machdep_gcc_x86_64.yaml \ +machdep_ppc_32.yaml : \ +%.yaml: machdep-schema.yaml make_machdep/make_machdep.py + @./make_machdep/make_machdep.py -i --from-file $@ --check + +machdep_x86_16.yaml machdep_x86_32.yaml machdep_x86_64.yaml: \ +machdep_%.yaml: machdep_gcc_%.yaml Makefile + @sed -e 's/sizeof_fun: .*/sizeof_fun: -1/' \ + -e 's/sizeof_void: .*/sizeof_void: -1/' \ + -e 's/alignof_fun: .*/alignof_fun: -1/' \ + -e 's/compiler: .*/compiler: generic/' \ + $< > $@ + +machdep_gcc_x86_16.yaml machdep_msvc_x86_64.yaml: %.yaml: machdep-schema.yaml + @echo "$@ is newer than $< and must be updated manually" + @exit 1 diff --git a/share/machdeps/machdep-schema.yaml b/share/machdeps/machdep-schema.yaml index cbc7163ae36..a48241896c2 100644 --- a/share/machdeps/machdep-schema.yaml +++ b/share/machdeps/machdep-schema.yaml @@ -179,6 +179,12 @@ sizeof_void: type: integer +ssize_t: + + description: definition of 'ssize_t' (POSIX standard type) + + type: string + uintptr_t: description: definition of 'uintptr_t' @@ -197,6 +203,12 @@ wchar_t: type: string +weof: + + description: value of 'WEOF' macro + + type: string + wint_t: description: definition of 'wint_t' diff --git a/share/machdeps/machdep_avr_16.yaml b/share/machdeps/machdep_avr_16.yaml index ec24d4f54c5..be755d979fb 100644 --- a/share/machdeps/machdep_avr_16.yaml +++ b/share/machdeps/machdep_avr_16.yaml @@ -30,8 +30,9 @@ sizeof_longlong: 8 sizeof_ptr: 2 sizeof_short: 2 sizeof_void: 1 +ssize_t: int uintptr_t: unsigned int version: clang version 15.0.7 wchar_t: int +weof: (0xffffffffu) wint_t: int - diff --git a/share/machdeps/machdep_gcc_x86_16.yaml b/share/machdeps/machdep_gcc_x86_16.yaml index 7e4f537bb2c..f15c429e025 100644 --- a/share/machdeps/machdep_gcc_x86_16.yaml +++ b/share/machdeps/machdep_gcc_x86_16.yaml @@ -28,7 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 4 sizeof_short: 2 sizeof_void: 1 +ssize_t: int uintptr_t: unsigned long version: none wchar_t: int +weof: (0xffffffffUL) wint_t: unsigned long diff --git a/share/machdeps/machdep_gcc_x86_32.yaml b/share/machdeps/machdep_gcc_x86_32.yaml index 66e15e9ca00..c2b6c927b7b 100644 --- a/share/machdeps/machdep_gcc_x86_32.yaml +++ b/share/machdeps/machdep_gcc_x86_32.yaml @@ -28,7 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 4 sizeof_short: 2 sizeof_void: 1 +ssize_t: int uintptr_t: unsigned int version: gcc (GCC) 12.2.1 20230201 wchar_t: long +weof: (0xffffffffu) wint_t: unsigned int diff --git a/share/machdeps/machdep_gcc_x86_64.yaml b/share/machdeps/machdep_gcc_x86_64.yaml index cd58ca56090..be370464cd6 100644 --- a/share/machdeps/machdep_gcc_x86_64.yaml +++ b/share/machdeps/machdep_gcc_x86_64.yaml @@ -28,8 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 8 sizeof_short: 2 sizeof_void: 1 +ssize_t: long uintptr_t: unsigned long version: gcc (GCC) 12.2.1 20230201 wchar_t: int +weof: (0xffffffffu) wint_t: unsigned int - diff --git a/share/machdeps/machdep_msvc_x86_64.yaml b/share/machdeps/machdep_msvc_x86_64.yaml index b39d6e20ca8..b530584b990 100644 --- a/share/machdeps/machdep_msvc_x86_64.yaml +++ b/share/machdeps/machdep_msvc_x86_64.yaml @@ -28,7 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 8 sizeof_short: 2 sizeof_void: 0 +ssize_t: long long uintptr_t: unsigned long long version: MSVC - X86-64bits mode wchar_t: unsigned short +weof: (0xffffU) wint_t: unsigned short diff --git a/share/machdeps/machdep_ppc_32.yaml b/share/machdeps/machdep_ppc_32.yaml index 304e2140688..7f0e1a922d1 100644 --- a/share/machdeps/machdep_ppc_32.yaml +++ b/share/machdeps/machdep_ppc_32.yaml @@ -30,8 +30,9 @@ sizeof_longlong: 8 sizeof_ptr: 4 sizeof_short: 2 sizeof_void: 1 +ssize_t: int uintptr_t: unsigned int version: clang version 15.0.7 wchar_t: int +weof: (0xffffffffu) wint_t: unsigned int - diff --git a/share/machdeps/machdep_x86_16.yaml b/share/machdeps/machdep_x86_16.yaml index cf3183d3458..0ef5ad977a0 100644 --- a/share/machdeps/machdep_x86_16.yaml +++ b/share/machdeps/machdep_x86_16.yaml @@ -28,7 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 4 sizeof_short: 2 sizeof_void: -1 +ssize_t: int uintptr_t: unsigned long version: none wchar_t: int +weof: (0xffffffffUL) wint_t: unsigned long diff --git a/share/machdeps/machdep_x86_32.yaml b/share/machdeps/machdep_x86_32.yaml index 344ef9ad036..cf02c8f3bfc 100644 --- a/share/machdeps/machdep_x86_32.yaml +++ b/share/machdeps/machdep_x86_32.yaml @@ -28,7 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 4 sizeof_short: 2 sizeof_void: -1 -uintptr_t: unsigned +ssize_t: int +uintptr_t: unsigned int version: gcc (GCC) 12.2.1 20230201 wchar_t: long +weof: (0xffffffffu) wint_t: unsigned int diff --git a/share/machdeps/machdep_x86_64.yaml b/share/machdeps/machdep_x86_64.yaml index ff21378b903..8d9a2386e8f 100644 --- a/share/machdeps/machdep_x86_64.yaml +++ b/share/machdeps/machdep_x86_64.yaml @@ -28,7 +28,9 @@ sizeof_longlong: 8 sizeof_ptr: 8 sizeof_short: 2 sizeof_void: -1 +ssize_t: long uintptr_t: unsigned long -version: clang version 15.0.7 +version: gcc (GCC) 12.2.1 20230201 wchar_t: int +weof: (0xffffffffu) wint_t: unsigned int diff --git a/share/machdeps/make_machdep/make_machdep.py b/share/machdeps/make_machdep/make_machdep.py index 0a61c5e6693..e8766ab6cee 100755 --- a/share/machdeps/make_machdep/make_machdep.py +++ b/share/machdeps/make_machdep/make_machdep.py @@ -108,8 +108,6 @@ def print_machdep(machdep): if args.in_place: args.dest_file = open(args.from_file, "w") yaml.dump(machdep, args.dest_file, indent=4, sort_keys=True) - # Python does not end the dump with a newline by itself - args.dest_file.write("\n") def make_schema(): schema_filename = my_path.parent / "machdep-schema.yaml" @@ -162,6 +160,7 @@ source_files = [ ("alignof_str.c", "number"), ("alignof_aligned.c", "number"), ("size_t.c", "type"), + ("ssize_t.c", "type"), ("wchar_t.c", "type"), ("ptrdiff_t.c", "type"), ("intptr_t.c", "type"), @@ -170,6 +169,7 @@ source_files = [ ("char_is_unsigned.c", "bool"), ("little_endian.c", "bool"), ("has__builtin_va_list.c", "has__builtin_va_list"), + ("weof.c", "macro"), ] @@ -191,7 +191,6 @@ def find_value(name, typ, output): def conversion(x): return x - else: warnings.warn(f"unexpected type '{typ}' for field '{name}', skipping") return @@ -210,14 +209,47 @@ def find_value(name, typ, output): if args.verbose: print(f"compiler output is:{output}") +def cleanup_cpp(output): + lines = output.splitlines() + macro = filter(lambda s: s != '' and s[0] != '#', lines) + macro = map(lambda s: s.strip(),macro) + return ' '.join(macro) + +def find_macro_value(name,output): + msg = re.compile(name + "_is = ([^;]+);") + res = re.search(msg,output) + if res: + if name in machdep: + value = res.group(1).strip() + if args.verbose: + print(f"[INFO] setting {name} to {value}") + machdep[name] = value + else: + warnings.warn(f"unexpected symbol '{name}', ignoring") + else: + warnings.warn(f"cannot find value of field '{name}', skipping") + if args.verbose: + print(f"compiler output is:{output}") for (f, typ) in source_files: p = my_path / f cmd = compilation_command + [str(p)] + if typ == "macro": + # We're just interested in expanding a macro, + # treatment is a bit different than the rest. + cmd = cmd + ["-E"] if args.verbose: print(f"[INFO] running command: {' '.join(cmd)}") proc = subprocess.run(cmd, capture_output=True) Path(f).with_suffix(".o").unlink(missing_ok=True) + if typ == "macro": + if proc.returncode != 0: + warnings.warn(f"error in determining value of '{p,stem}', skipping") + if args.verbose: + print(f"compiler output is:{proc.stderr.decode()}") + continue + find_macro_value(p.stem,cleanup_cpp(proc.stdout.decode())) + continue if typ == "has__builtin_va_list": # Special case: compilation success determines presence or absence machdep["has__builtin_va_list"] = proc.returncode == 0 diff --git a/share/machdeps/make_machdep/ssize_t.c b/share/machdeps/make_machdep/ssize_t.c new file mode 100644 index 00000000000..95260cbfc10 --- /dev/null +++ b/share/machdeps/make_machdep/ssize_t.c @@ -0,0 +1,30 @@ +/**************************************************************************/ +/* */ +/* This file is part of Frama-C. */ +/* */ +/* Copyright (C) 2007-2023 */ +/* CEA (Commissariat à l'énergie atomique et aux énergies */ +/* alternatives) */ +/* */ +/* you can redistribute it and/or modify it under the terms of the GNU */ +/* Lesser General Public License as published by the Free Software */ +/* Foundation, version 2.1. */ +/* */ +/* It is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* See the GNU Lesser General Public License version 2.1 */ +/* for more details (enclosed in the file licenses/LGPLv2.1). */ +/* */ +/**************************************************************************/ + +#include "make_machdep_common.h" +#include <sys/types.h> + +#define TEST_TYPE ssize_t + +TEST_TYPE_IS(int) +TEST_TYPE_IS(long) +TEST_TYPE_IS(long long) diff --git a/share/machdeps/make_machdep/weof.c b/share/machdeps/make_machdep/weof.c new file mode 100644 index 00000000000..67d58eb031c --- /dev/null +++ b/share/machdeps/make_machdep/weof.c @@ -0,0 +1,3 @@ +#include <wchar.h> + +const wint_t weof_is = WEOF; diff --git a/src/kernel_internals/runtime/machdep.ml b/src/kernel_internals/runtime/machdep.ml index e2daa153cec..1caae68014c 100644 --- a/src/kernel_internals/runtime/machdep.ml +++ b/src/kernel_internals/runtime/machdep.ml @@ -189,19 +189,19 @@ let gen_all_defines fmt mach = gen_define_string fmt "__UINTPTR_T" mach.uintptr_t; gen_define_string fmt "__PTRDIFF_T" mach.ptrdiff_t; gen_define_string fmt "__WINT_T" mach.wint_t; - (* gen_define_string fmt "__SSIZE_T" mach.ssize_t; *) + gen_define_string fmt "__SSIZE_T" mach.ssize_t; gen_intlike_max fmt "__FC_SIZE" mach.size_t mach; gen_intlike_min fmt "__FC_INTPTR" mach.intptr_t mach; gen_intlike_max fmt "__FC_INTPTR" mach.intptr_t mach; gen_intlike_max fmt "__FC_UINTPTR" mach.uintptr_t mach; gen_intlike_min fmt "__FC_WCHAR" mach.wchar_t mach; gen_intlike_max fmt "__FC_WCHAR" mach.wchar_t mach; - (* TODO: __SSIZE_MAX *) + gen_intlike_max fmt "__SSIZE_MAX" mach.ssize_t mach; gen_intlike_min fmt "__FC_PTRDIFF" mach.ptrdiff_t mach; gen_intlike_max fmt "__FC_PTRDIFF" mach.ptrdiff_t mach; gen_intlike_min fmt "__FC_WINT" mach.wint_t mach; gen_intlike_max fmt "__FC_WINT" mach.wint_t mach; - (* TODO: __FC_WEOF *) + gen_define_string fmt "__FC_WEOF" mach.weof; (* NB: Frama-C's inttypes.h is assuming that intptr_t and uintptr_t have the same rank when it comes to define PRI.?PTR macros. *) gen_define_literal_string fmt "__PRIPTR_PREFIX" diff --git a/src/kernel_services/ast_data/cil_types.ml b/src/kernel_services/ast_data/cil_types.ml index b80ed81244c..1b77b2e5856 100644 --- a/src/kernel_services/ast_data/cil_types.ml +++ b/src/kernel_services/ast_data/cil_types.ml @@ -1876,6 +1876,7 @@ type mach = { sizeof_void: int; (* Size of "void" *) sizeof_fun: int; (* Size of function. Negative if unsupported. *) size_t: string; (* Type of "sizeof(T)" *) + ssize_t: string; (* representation of ssize_t *) wchar_t: string; (* Type of "wchar_t" *) ptrdiff_t: string; (* Type of "ptrdiff_t" *) intptr_t: string; (* Type of "intptr_t" *) @@ -1900,6 +1901,7 @@ type mach = { cpp_arch_flags: string list; (* Architecture-specific flags to be given to the preprocessor (if supported) *) version: string; (* Information on this machdep *) + weof: string; (* expansion of WEOF macro *) } (* diff --git a/src/kernel_services/ast_queries/cil_datatype.ml b/src/kernel_services/ast_queries/cil_datatype.ml index 72e9e135a1e..8819cba4a61 100644 --- a/src/kernel_services/ast_queries/cil_datatype.ml +++ b/src/kernel_services/ast_queries/cil_datatype.ml @@ -2640,6 +2640,7 @@ let dummy_machdep = sizeof_void = -1; sizeof_fun = -1; size_t = "unsigned long"; + ssize_t = "long"; wchar_t = "int"; ptrdiff_t = "long"; intptr_t = "long"; (* Type of "intptr_t" *) @@ -2662,6 +2663,7 @@ let dummy_machdep = compiler = "none"; cpp_arch_flags = []; version = "N/A"; + weof = "(-1)" } module Machdep = Datatype.Make_with_collections(struct diff --git a/tests/misc/custom_machdep.ml b/tests/misc/custom_machdep.ml index 7d929b77693..fc497312b09 100644 --- a/tests/misc/custom_machdep.ml +++ b/tests/misc/custom_machdep.ml @@ -16,6 +16,7 @@ let mach = sizeof_void = 1; sizeof_fun = 1; size_t = "unsigned long"; + ssize_t = "long"; intptr_t = "long"; uintptr_t = "unsigned long"; wint_t = "int"; @@ -35,6 +36,7 @@ let mach = char_is_unsigned = false; little_endian = true; has__builtin_va_list = true; + weof = "(-1)"; } let mach2 = { mach with compiler = "baz" } diff --git a/tests/misc/custom_machdep.yaml b/tests/misc/custom_machdep.yaml index 67b759afe50..11e6ed0cab1 100644 --- a/tests/misc/custom_machdep.yaml +++ b/tests/misc/custom_machdep.yaml @@ -29,5 +29,7 @@ sizeof_longlong: 8 sizeof_ptr: 4 sizeof_short: 2 sizeof_void: 1 +ssize_t: long version: foo wchar_t: int +weof: (-1) diff --git a/tests/syntax/machdep_char_unsigned.ml b/tests/syntax/machdep_char_unsigned.ml index 9ccf6d9691e..51b9b7655e2 100644 --- a/tests/syntax/machdep_char_unsigned.ml +++ b/tests/syntax/machdep_char_unsigned.ml @@ -1,4 +1,3 @@ - open Cil_types let md = { @@ -29,12 +28,14 @@ let md = { char_is_unsigned = true; little_endian = true; size_t = "unsigned int"; + ssize_t = "int"; wchar_t = "int"; intptr_t = "int"; uintptr_t = "unsigned int"; ptrdiff_t = "int"; wint_t = "long"; has__builtin_va_list = true; + weof = "(-1L)" } let () = -- GitLab