diff options
31 files changed, 909 insertions, 672 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bb2f1a..e7b4682 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ function(_suppress_tinyusb_warnings) COMPILE_OPTIONS "-Wno-switch-enum") endfunction() -function(target_embed_sources arg_target arg_hdrname) +function(target_embed_sources arg_compile_target arg_link_target arg_hdrname) set(embed_objs) foreach(embed_src IN LISTS ARGN) add_custom_command( @@ -53,7 +53,8 @@ function(target_embed_sources arg_target arg_hdrname) DEPENDS "${embed_objs}" "${CMAKE_SOURCE_DIR}/build-aux/embed-sources.h.gen" ) - target_sources("${arg_target}" PRIVATE "${embed_objs}" "${arg_hdrname}") + target_sources("${arg_compile_target}" PRIVATE "${arg_hdrname}") + target_sources("${arg_link_target}" PRIVATE "${embed_objs}") endfunction() function(add_stack_analysis arg_outfile arg_objlib_target) @@ -63,7 +64,7 @@ function(add_stack_analysis arg_outfile arg_objlib_target) ) add_custom_command( OUTPUT "${arg_outfile}" - COMMAND "${CMAKE_SOURCE_DIR}/build-aux/stack.c.gen" "${CMAKE_SOURCE_DIR}" "$<TARGET_OBJECTS:${arg_objlib_target}>" "$<PATH:ABSOLUTE_PATH,$<TARGET_PROPERTY:${arg_objlib_target},SOURCES>,${CMAKE_CURRENT_SOURCE_DIR}>" >"${arg_outfile}" + COMMAND "${CMAKE_SOURCE_DIR}/build-aux/stack.c.gen" "${PICO_PLATFORM}" "${CMAKE_SOURCE_DIR}" "$<TARGET_OBJECTS:${arg_objlib_target}>" "$<PATH:ABSOLUTE_PATH,$<TARGET_PROPERTY:${arg_objlib_target},SOURCES>,${CMAKE_CURRENT_SOURCE_DIR}>" >"${arg_outfile}" COMMAND_EXPAND_LISTS DEPENDS "$<TARGET_OBJECTS:${arg_objlib_target}>" "${CMAKE_SOURCE_DIR}/build-aux/stack.c.gen" COMMENT "Calculating ${arg_objlib_target} required stack sizes" @@ -127,6 +128,7 @@ add_subdirectory(libhw) add_subdirectory(libdhcp) add_subdirectory(libusb) add_subdirectory(lib9p) +add_subdirectory(lib9p_util) add_subdirectory(cmd/sbc_harness) add_subdirectory(cmd/srv9p) diff --git a/build-aux/stack.c.gen b/build-aux/stack.c.gen index 22b18d5..92bd8c2 100755 --- a/build-aux/stack.c.gen +++ b/build-aux/stack.c.gen @@ -95,6 +95,8 @@ def parse_vcg(reader: typing.TextIO) -> typing.Iterator[VCGElem]: ################################################################################ # Main analysis +UsageKind: typing.TypeAlias = typing.Literal["static", "dynamic", "dynamic,bounded"] + class Node: # from .title (`static` and `__weak` functions are prefixed with @@ -103,6 +105,7 @@ class Node: funcname: str # .label is "{funcname}\n{location}\n{nstatic} bytes (static}\n{ndynamic} dynamic objects" location: str + usage_kind: UsageKind nstatic: int ndynamic: int @@ -116,6 +119,7 @@ def synthetic_node(name: str, nstatic: int, calls: set[str] = set()) -> Node: n.funcname = name n.location = "<synthetic>" + n.usage_kind = "static" n.nstatic = nstatic n.ndynamic = 0 @@ -137,8 +141,9 @@ def analyze( re_node_label = re.compile( r"(?P<funcname>[^\n]+)\n" + r"(?P<location>[^\n]+:[0-9]+:[0-9]+)\n" - + r"(?P<nstatic>[0-9]+) bytes \(static\)\n" - + r"(?P<ndynamic>[0-9]+) dynamic objects", + + r"(?P<nstatic>[0-9]+) bytes \((?P<usage_kind>static|dynamic|dynamic,bounded)\)\n" + + r"(?P<ndynamic>[0-9]+) dynamic objects" + + r"(?:\n.*)?", flags=re.MULTILINE, ) @@ -163,6 +168,9 @@ def analyze( f"unexpected label value {repr(v)}" ) node.location = m.group("location") + node.usage_kind = typing.cast( + UsageKind, m.group("usage_kind") + ) node.nstatic = int(m.group("nstatic")) node.ndynamic = int(m.group("ndynamic")) case "shape": @@ -216,8 +224,7 @@ def analyze( graph[node.funcname] = node missing: set[str] = set() - - print("/*") + dynamic: set[str] = set() dbg = False @@ -255,41 +262,46 @@ def analyze( node = graph[funcname] if dbg: print(f"//dbg: {funcname}\t{node.nstatic}") + if node.usage_kind == "dynamic" or node.ndynamic > 0: + dynamic.add(app_location_xform(funcname)) return node.nstatic + max( [0, *[nstatic(call, chain + [funcname]) for call in node.calls]] ) - for grp_name, grp_filter in app_func_filters.items(): - namelen = max( - [len(app_location_xform(name)) for name in graph if grp_filter(name)] - + [len(grp_name) + 4] - ) - numlen = max(len(str(nstatic(name))) for name in graph if name.endswith("_cr")) - sep1 = ("=" * namelen) + " " + "=" * numlen - sep2 = ("-" * namelen) + " " + "-" * numlen - - print("= " + grp_name + " " + sep1[len(grp_name) + 3 :]) + print("/*") + for grp_name, grp_filter in app_func_filters.items(): + # Gather the data. nmax = 0 nsum = 0 + rows: dict[str, int] = {} for funcname in graph: if grp_filter(funcname): n = nstatic(funcname) - print( - f"{app_location_xform(funcname).ljust(namelen)} {str(n).rjust(numlen)}" - ) + rows[app_location_xform(funcname)] = n if n > nmax: nmax = n nsum += n + # Figure sizes. + namelen = max([len(k) for k in rows.keys()] + [len(grp_name) + 4]) + numlen = len(str(nsum)) + sep1 = ("=" * namelen) + " " + "=" * numlen + sep2 = ("-" * namelen) + " " + "-" * numlen + + # Print. + print("= " + grp_name + " " + sep1[len(grp_name) + 3 :]) + for name, num in rows.items(): + print(f"{name.ljust(namelen)} {str(num).rjust(numlen)}") print(sep2) print(f"{'Total'.ljust(namelen)} {str(nsum).rjust(numlen)}") print(f"{'Maximum'.ljust(namelen)} {str(nmax).rjust(numlen)}") - print(sep1) for funcname in sorted(missing): print(f"warning: missing: {funcname}") + for funcname in sorted(dynamic): + print(f"warning: dynamic: {funcname}") print("*/") @@ -312,11 +324,20 @@ def read_source(location: str) -> str: def main( - *, arg_base_dir: str, arg_ci_fnames: list[str], arg_c_fnames: list[str] + *, + arg_pico_platform: str, + arg_base_dir: str, + arg_ci_fnames: list[str], + arg_c_fnames: list[str], ) -> None: re_call_other = re.compile(r"(?P<func>[^(]+)\(.*") + all_nodes: list[Node] = [] + hooks_is_intrhandler: list[typing.Callable[[str], bool]] = [] + hooks_indirect_callees: list[typing.Callable[[str, str], list[str] | None]] = [] + hooks_skip_call: list[typing.Callable[[list[str], str], bool]] = [] + # The sbc-harness codebase ####################################### vcalls: dict[str, set[str]] = {} @@ -341,6 +362,39 @@ def main( elif re_vtable_start.search(line): in_vtable = True + tmessage_handlers: set[str] | None = None + if any(fname.endswith("lib9p/srv.c") for fname in c_fnames): + srv_c = next(fname for fname in c_fnames if fname.endswith("lib9p/srv.c")) + re_tmessage_handler = re.compile( + r"^\s*\[LIB9P_TYP_T[^]]+\]\s*=\s*\(tmessage_handler\)\s*(?P<handler>\S+),\s*$" + ) + tmessage_handlers = set() + with open(srv_c, "r") as fh: + for line in fh: + line = line.rstrip() + if m := re_tmessage_handler.fullmatch(line): + tmessage_handlers.add(m.group("handler")) + + lib9p_versions: dict[str, set[str]] | None = None + if any(fname.endswith("lib9p/9p.c") for fname in c_fnames): + generated_c = next( + fname for fname in c_fnames if fname.endswith("lib9p/9p.generated.c") + ) + re_lib9p_msg_entry = re.compile(r"^\s*_MSG\((?P<typ>\S+)\),$") + lib9p_versions = { + "validate": set(), + "marshal": set(), + "unmarshal": set(), + } + with open(generated_c, "r") as fh: + for line in fh: + line = line.rstrip() + if m := re_lib9p_msg_entry.fullmatch(line): + typ = m.group("typ") + lib9p_versions["validate"].add(f"validate_{typ}") + lib9p_versions["unmarshal"].add(f"unmarshal_{typ}") + lib9p_versions["marshal"].add(f"marshal_{typ}") + re_call_vcall = re.compile(r"VCALL\((?P<obj>[^,]+), (?P<meth>[^,)]+)[,)].*") def sbc_indirect_callees(loc: str, line: str) -> list[str] | None: @@ -361,10 +415,22 @@ def main( "_cr_chan_dequeue", "_cr_select_dequeue", ] + if tmessage_handlers and "/srv.c:" in loc and "tmessage_handlers[typ](" in line: + return sorted(tmessage_handlers) + if lib9p_versions and "/9p.c:" in loc: + for meth in lib9p_versions.keys(): + if line.startswith(f"table.{meth}("): + return sorted(lib9p_versions[meth]) return None + hooks_indirect_callees += [sbc_indirect_callees] + def sbc_is_thread(name: str) -> bool: - return name.endswith("_cr") or name == "main" + if name.endswith("_cr") and name != "lib9p_srv_read_cr": + return True + if name == "main": + return True + return False def sbc_is_intrhandler(name: str) -> bool: return name in [ @@ -374,10 +440,19 @@ def main( "hostnet_handle_sig_io", ] + hooks_is_intrhandler += [sbc_is_intrhandler] + sbc_gpio_handlers = [ "w5500_intrhandler", ] + # 1=just root directory + # 2=just files in root directory + # 3=just 1 level of subdirectories + # 4=just 2 levels of subdirectories + # ... + sbc_9p_max_depth = 3 + def sbc_skip_call(chain: list[str], call: str) -> bool: if ( len(chain) > 1 @@ -386,268 +461,299 @@ def main( and any(c.endswith(":__assert_msg_fail") for c in chain[:-1]) ): return True - if call == "_cr_select_dequeue": + if ( + len(chain) >= sbc_9p_max_depth + and call.endswith("/srv.c:util_release") + and all( + c.endswith("/srv.c:util_release") for c in chain[-sbc_9p_max_depth:] + ) + ): return True return False + hooks_skip_call += [sbc_skip_call] + # pico-sdk ####################################################### - def pico_is_intrhandler(name: str) -> bool: - return name in [ - "gpio_default_irq_handler", - ] + if arg_pico_platform == "rp2040": + + def pico_is_intrhandler(name: str) -> bool: + return name in [ + "gpio_default_irq_handler", + ] - def pico_indirect_callees(loc: str, line: str) -> list[str] | None: - if "/3rd-party/pico-sdk/" not in loc or "/3rd-party/pico-sdk/lib/" in loc: + hooks_is_intrhandler += [pico_is_intrhandler] + + def pico_indirect_callees(loc: str, line: str) -> list[str] | None: + if "/3rd-party/pico-sdk/" not in loc or "/3rd-party/pico-sdk/lib/" in loc: + return None + m = re_call_other.fullmatch(line) + call: str | None = m.group("func") if m else None + + match call: + case "connect_internal_flash_func": + return ["rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)"] + case "flash_exit_xip_func": + return ["rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)"] + case "flash_range_erase_func": + return ["rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE)"] + case "flash_flush_cache_func": + return ["rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)"] + case "rom_table_lookup": + return ["rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)"] + if "/flash.c:" in loc and "boot2_copyout" in line: + return ["_stage2_boot"] + if "/gpio.c:" in loc and call == "callback": + return sbc_gpio_handlers + if "/printf.c:" in loc: + if call == "out": + return [ + "_out_buffer", + "_out_null", + "_out_fct", + ] + if "->fct(" in line: + return ["stdio_buffered_printer"] + if "/stdio.c:" in loc: + if call == "out_func": + return [ + "stdio_out_chars_crlf", + "stdio_out_chars_no_crlf", + ] + if call and (call.startswith("d->") or call.startswith("driver->")): + _, meth = call.split("->", 1) + match meth: + case "out_chars": + return ["stdio_uart_out_chars"] + case "out_flush": + return ["stdio_uart_out_flush"] + case "in_chars": + return ["stdio_uart_in_chars"] return None - m = re_call_other.fullmatch(line) - call: str | None = m.group("func") if m else None - - match call: - case "connect_internal_flash_func": - return ["rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)"] - case "flash_exit_xip_func": - return ["rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)"] - case "flash_range_erase_func": - return ["rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE)"] - case "flash_flush_cache_func": - return ["rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)"] - case "rom_table_lookup": - return ["rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)"] - if "/flash.c:" in loc and "boot2_copyout" in line: - return ["_stage2_boot"] - if "/gpio.c:" in loc and call == "callback": - return sbc_gpio_handlers - if "/printf.c:" in loc: - if call == "out": - return [ - "_out_buffer", - "_out_null", - "_out_fct", - ] - if "->fct(" in line: - return ["stdio_buffered_printer"] - if "/stdio.c:" in loc: - if call == "out_func": - return [ - "stdio_out_chars_crlf", - "stdio_out_chars_no_crlf", - ] - if call and (call.startswith("d->") or call.startswith("driver->")): - _, meth = call.split("->", 1) - match meth: - case "out_chars": - return ["stdio_uart_out_chars"] - case "out_flush": - return ["stdio_uart_out_flush"] - case "in_chars": - return ["stdio_uart_in_chars"] - return None - def pico_skip_call(chain: list[str], call: str) -> bool: - if call == "_out_buffer" or call == "_out_fct": - last = "" - for pcall in chain: - if pcall in [ - "__wrap_sprintf", - "__wrap_snprintf", - "__wrap_vsnprintf", - "vfctprintf", - ]: - last = pcall - if last == "vfctprintf": - return call != "_out_fct" - else: - return call == "_out_buffer" - return False + hooks_indirect_callees += [pico_indirect_callees] + + def pico_skip_call(chain: list[str], call: str) -> bool: + if call == "_out_buffer" or call == "_out_fct": + last = "" + for pcall in chain: + if pcall in [ + "__wrap_sprintf", + "__wrap_snprintf", + "__wrap_vsnprintf", + "vfctprintf", + ]: + last = pcall + if last == "vfctprintf": + return call != "_out_fct" + else: + return call == "_out_buffer" + return False + + hooks_skip_call += [pico_skip_call] - # src/rp2_common/hardware_divider/include/hardware/divider_helper.S - save_div_state_and_lr = 5 * 4 - # src/rp2_common/pico_divider/divider_hardware.S - save_div_state_and_lr_64 = 5 * 4 - pico_nodes: list[Node] = [ - # src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S - synthetic_node("__aeabi_lmul", 4), + # src/rp2_common/hardware_divider/include/hardware/divider_helper.S + save_div_state_and_lr = 5 * 4 # src/rp2_common/pico_divider/divider_hardware.S - # s32 aliases - synthetic_node("div_s32s32", 0, {"divmod_s32s32"}), - synthetic_node("__aeabi_idiv", 0, {"divmod_s32s32"}), - synthetic_node("__aeabi_idivmod", 0, {"divmod_s32s32"}), - # s32 impl - synthetic_node("divmod_s32s32", 0, {"divmod_s32s32_savestate"}), - synthetic_node( - "divmod_s32s32_savestate", save_div_state_and_lr, {"divmod_s32s32_unsafe"} - ), - synthetic_node("divmod_s32s32_unsafe", 2 * 4, {"__aeabi_idiv0"}), - # u32 aliases - synthetic_node("div_u32u32", 0, {"divmod_u32u32"}), - synthetic_node("__aeabi_uidiv", 0, {"divmod_u32u32"}), - synthetic_node("__aeabi_uidivmod", 0, {"divmod_u32u32"}), - # u32 impl - synthetic_node("divmod_u32u32", 0, {"divmod_u32u32_savestate"}), - synthetic_node( - "divmod_u32u32_savestate", save_div_state_and_lr, {"divmod_u32u32_unsafe"} - ), - synthetic_node("divmod_u32u32_unsafe", 2 * 4, {"__aeabi_idiv0"}), - # s64 aliases - synthetic_node("div_s64s64", 0, {"divmod_s64s64"}), - synthetic_node("__aeabi_ldiv", 0, {"divmod_s64s64"}), - synthetic_node("__aeabi_ldivmod", 0, {"divmod_s64s64"}), - # s64 impl - synthetic_node("divmod_s64s64", 0, {"divmod_s64s64_savestate"}), - synthetic_node( - "divmod_s64s64_savestate", - save_div_state_and_lr_64 + (2 * 4), - {"divmod_s64s64_unsafe"}, - ), - synthetic_node( - "divmod_s64s64_unsafe", 4, {"divmod_u64u64_unsafe", "__aeabi_ldiv0"} - ), - # u64 aliases - synthetic_node("div_u64u64", 0, {"divmod_u64u64"}), - synthetic_node("__aeabi_uldiv", 0, {"divmod_u64u64"}), - synthetic_node("__aeabi_uldivmod", 0, {"divmod_u64u64"}), - # u64 impl - synthetic_node("divmod_u64u64", 0, {"divmod_u64u64_savestate"}), - synthetic_node( - "divmod_u64u64_savestate", - save_div_state_and_lr_64 + (2 * 4), - {"divmod_u64u64_unsafe"}, - ), - synthetic_node( - "divmod_u64u64_unsafe", (1 + 1 + 2 + 5 + 5 + 2) * 4, {"__aeabi_ldiv0"} - ), - # *_rem - synthetic_node("divod_s64s64_rem", 2 * 4, {"divmod_s64s64"}), - synthetic_node("divod_u64u64_rem", 2 * 4, {"divmod_u64u64"}), - # src/rp2040/boot_stage2/boot2_${name,,}.S for name=W25Q080, - # controlled by `#define PICO_BOOT_STAGE2_{name} 1` in - # src/boards/include/boards/pico.h - synthetic_node("_stage2_boot", 0), # TODO - # https://github.com/raspberrypi/pico-bootrom-rp2040 - synthetic_node("rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)", 0), # TODO - synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)", 0), # TODO - synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)", 0), # TODO - synthetic_node("rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)", 0), # TODO - ] + save_div_state_and_lr_64 = 5 * 4 + all_nodes += [ + # src/rp2_common/pico_int64_ops/pico_int64_ops_aeabi.S + synthetic_node("__aeabi_lmul", 4), + # src/rp2_common/pico_divider/divider_hardware.S + # s32 aliases + synthetic_node("div_s32s32", 0, {"divmod_s32s32"}), + synthetic_node("__aeabi_idiv", 0, {"divmod_s32s32"}), + synthetic_node("__aeabi_idivmod", 0, {"divmod_s32s32"}), + # s32 impl + synthetic_node("divmod_s32s32", 0, {"divmod_s32s32_savestate"}), + synthetic_node( + "divmod_s32s32_savestate", + save_div_state_and_lr, + {"divmod_s32s32_unsafe"}, + ), + synthetic_node("divmod_s32s32_unsafe", 2 * 4, {"__aeabi_idiv0"}), + # u32 aliases + synthetic_node("div_u32u32", 0, {"divmod_u32u32"}), + synthetic_node("__aeabi_uidiv", 0, {"divmod_u32u32"}), + synthetic_node("__aeabi_uidivmod", 0, {"divmod_u32u32"}), + # u32 impl + synthetic_node("divmod_u32u32", 0, {"divmod_u32u32_savestate"}), + synthetic_node( + "divmod_u32u32_savestate", + save_div_state_and_lr, + {"divmod_u32u32_unsafe"}, + ), + synthetic_node("divmod_u32u32_unsafe", 2 * 4, {"__aeabi_idiv0"}), + # s64 aliases + synthetic_node("div_s64s64", 0, {"divmod_s64s64"}), + synthetic_node("__aeabi_ldiv", 0, {"divmod_s64s64"}), + synthetic_node("__aeabi_ldivmod", 0, {"divmod_s64s64"}), + # s64 impl + synthetic_node("divmod_s64s64", 0, {"divmod_s64s64_savestate"}), + synthetic_node( + "divmod_s64s64_savestate", + save_div_state_and_lr_64 + (2 * 4), + {"divmod_s64s64_unsafe"}, + ), + synthetic_node( + "divmod_s64s64_unsafe", 4, {"divmod_u64u64_unsafe", "__aeabi_ldiv0"} + ), + # u64 aliases + synthetic_node("div_u64u64", 0, {"divmod_u64u64"}), + synthetic_node("__aeabi_uldiv", 0, {"divmod_u64u64"}), + synthetic_node("__aeabi_uldivmod", 0, {"divmod_u64u64"}), + # u64 impl + synthetic_node("divmod_u64u64", 0, {"divmod_u64u64_savestate"}), + synthetic_node( + "divmod_u64u64_savestate", + save_div_state_and_lr_64 + (2 * 4), + {"divmod_u64u64_unsafe"}, + ), + synthetic_node( + "divmod_u64u64_unsafe", (1 + 1 + 2 + 5 + 5 + 2) * 4, {"__aeabi_ldiv0"} + ), + # *_rem + synthetic_node("divod_s64s64_rem", 2 * 4, {"divmod_s64s64"}), + synthetic_node("divod_u64u64_rem", 2 * 4, {"divmod_u64u64"}), + # src/rp2040/boot_stage2/boot2_${name,,}.S for name=W25Q080, + # controlled by `#define PICO_BOOT_STAGE2_{name} 1` in + # src/boards/include/boards/pico.h + synthetic_node("_stage2_boot", 0), # TODO + # https://github.com/raspberrypi/pico-bootrom-rp2040 + synthetic_node( + "rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH)", 0 + ), # TODO + synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP)", 0), # TODO + synthetic_node("rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE)", 0), # TODO + synthetic_node("rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET)", 0), # TODO + ] - # TinyUSB ######################################################## + # TinyUSB device ################################################# - tusb_config_fname = ( - arg_base_dir + "/cmd/sbc_harness/config/tusb_config.h" - ) # TODO: FIXME - re_tud_class = re.compile( - r"^\s*#\s*define\s+(?P<k>CFG_TUD_(?:\S{3}|AUDIO|VIDEO|MIDI|VENDOR|USBTMC|DFU_RUNTIME|ECM_RNDIS))\s+(?P<v>\S+).*" - ) - tusb_config: dict[str, bool] = {} - with open(tusb_config_fname, "r") as fh: - in_table = False - for line in fh: - line = line.rstrip() - if m := re_tud_class.fullmatch(line): - k = m.group("k") - v = m.group("v") - tusb_config[k] = bool(int(v)) - - usbd_fname = next( - fname for fname in c_fnames if fname.endswith("/tinyusb/src/device/usbd.c") - ) - tud_drivers: dict[str, set[str]] = {} - re_tud_entry = re.compile( - r"^\s+\.(?P<meth>\S+)\s*=\s*(?P<impl>[a-zA-Z0-9_]+)(?:,.*)?" - ) - re_tud_if1 = re.compile(r"^\s*#\s*if (\S+)\s*") - re_tud_if2 = re.compile(r"^\s*#\s*if (\S+)\s*\|\|\s*(\S+)\s*") - re_tud_endif = re.compile(r"^\s*#\s*endif\s*") - with open(usbd_fname, "r") as fh: - in_table = False - enabled = True - for line in fh: - line = line.rstrip() - if in_table: - if m := re_tud_if1.fullmatch(line): - enabled = tusb_config[m.group(1)] - elif m := re_tud_if2.fullmatch(line): - enabled = tusb_config[m.group(1)] or tusb_config[m.group(2)] - elif re_tud_endif.fullmatch(line): - enabled = True - if m := re_tud_entry.fullmatch(line): - meth = m.group("meth") - impl = m.group("impl") - if meth == "name" or not enabled: - continue - if meth not in tud_drivers: - tud_drivers[meth] = set() - if impl != "NULL": - tud_drivers[meth].add(impl) - if line.startswith("}"): - in_table = False - elif " _usbd_driver[] = {" in line: - in_table = True - - def tud_indirect_callees(loc: str, line: str) -> list[str] | None: - if "/tinyusb/" not in loc or "/tinyusb/src/host/" in loc or "_host.c:" in loc: - return None - m = re_call_other.fullmatch(line) - assert m - call = m.group("func") - if call == "_ctrl_xfer.complete_cb": - return [ - # "process_test_mode_cb", - "tud_vendor_control_xfer_cb", - *sorted(tud_drivers["control_xfer_cb"]), - ] - elif call.startswith("driver->"): - return sorted(tud_drivers[call[len("driver->") :]]) - elif call == "event.func_call.func": - # callback from usb_defer_func() - return [] + if any(fname.endswith("/tinyusb/src/device/usbd.c") for fname in c_fnames): + tusb_config_fname = ( + arg_base_dir + "/cmd/sbc_harness/config/tusb_config.h" + ) # TODO: FIXME + re_tud_class = re.compile( + r"^\s*#\s*define\s+(?P<k>CFG_TUD_(?:\S{3}|AUDIO|VIDEO|MIDI|VENDOR|USBTMC|DFU_RUNTIME|ECM_RNDIS))\s+(?P<v>\S+).*" + ) + tusb_config: dict[str, bool] = {} + with open(tusb_config_fname, "r") as fh: + in_table = False + for line in fh: + line = line.rstrip() + if m := re_tud_class.fullmatch(line): + k = m.group("k") + v = m.group("v") + tusb_config[k] = bool(int(v)) - return None + usbd_fname = next( + fname for fname in c_fnames if fname.endswith("/tinyusb/src/device/usbd.c") + ) + tud_drivers: dict[str, set[str]] = {} + re_tud_entry = re.compile( + r"^\s+\.(?P<meth>\S+)\s*=\s*(?P<impl>[a-zA-Z0-9_]+)(?:,.*)?" + ) + re_tud_if1 = re.compile(r"^\s*#\s*if (\S+)\s*") + re_tud_if2 = re.compile(r"^\s*#\s*if (\S+)\s*\|\|\s*(\S+)\s*") + re_tud_endif = re.compile(r"^\s*#\s*endif\s*") + with open(usbd_fname, "r") as fh: + in_table = False + enabled = True + for line in fh: + line = line.rstrip() + if in_table: + if m := re_tud_if1.fullmatch(line): + enabled = tusb_config[m.group(1)] + elif m := re_tud_if2.fullmatch(line): + enabled = tusb_config[m.group(1)] or tusb_config[m.group(2)] + elif re_tud_endif.fullmatch(line): + enabled = True + if m := re_tud_entry.fullmatch(line): + meth = m.group("meth") + impl = m.group("impl") + if meth == "name" or not enabled: + continue + if meth not in tud_drivers: + tud_drivers[meth] = set() + if impl != "NULL": + tud_drivers[meth].add(impl) + if line.startswith("}"): + in_table = False + elif " _usbd_driver[] = {" in line: + in_table = True + + def tud_indirect_callees(loc: str, line: str) -> list[str] | None: + if ( + "/tinyusb/" not in loc + or "/tinyusb/src/host/" in loc + or "_host.c:" in loc + ): + return None + m = re_call_other.fullmatch(line) + assert m + call = m.group("func") + if call == "_ctrl_xfer.complete_cb": + return [ + # "process_test_mode_cb", + "tud_vendor_control_xfer_cb", + *sorted(tud_drivers["control_xfer_cb"]), + ] + elif call.startswith("driver->"): + return sorted(tud_drivers[call[len("driver->") :]]) + elif call == "event.func_call.func": + # callback from usb_defer_func() + return [] - def tud_skip_call(chain: list[str], call: str) -> bool: - if call == "usbd_app_driver_get_cb": - return True - return False + return None + + hooks_indirect_callees += [tud_indirect_callees] # newlib ######################################################### - newlib_nodes: list[Node] = [ - # malloc - synthetic_node("free", 0), # TODO - synthetic_node("malloc", 0), # TODO - synthetic_node("realloc", 0), # TODO - synthetic_node("aligned_alloc", 0), # TODO - synthetic_node("reallocarray", 0), # TODO - # execution - synthetic_node("abort", 0), # TODO - synthetic_node("longjmp", 0), # TODO - synthetic_node("setjmp", 0), # TODO - # <strings.h> - synthetic_node("memcmp", 0), # TODO - synthetic_node("memcpy", 0), # TODO - synthetic_node("memset", 0), # TODO - synthetic_node("strlen", 0), # TODO - synthetic_node("strncpy", 0), # TODO - # other - synthetic_node("random", 0), # TODO - ] + if arg_pico_platform == "rp2040": + all_nodes += [ + # malloc + synthetic_node("free", 0), # TODO + synthetic_node("malloc", 0), # TODO + synthetic_node("realloc", 0), # TODO + synthetic_node("aligned_alloc", 0), # TODO + synthetic_node("reallocarray", 0), # TODO + # execution + synthetic_node("abort", 0), # TODO + synthetic_node("longjmp", 0), # TODO + synthetic_node("setjmp", 0), # TODO + # <strings.h> + synthetic_node("memcmp", 0), # TODO + synthetic_node("memcpy", 0), # TODO + synthetic_node("memset", 0), # TODO + synthetic_node("strcmp", 0), # TODO + synthetic_node("strlen", 0), # TODO + synthetic_node("strncpy", 0), # TODO + synthetic_node("strnlen", 0), # TODO + # other + synthetic_node("random", 0), # TODO + ] # libgcc ######################################################### - gcc_nodes: list[Node] = [ - synthetic_node("__aeabi_idiv0", 0), # TODO - synthetic_node("__aeabi_ldiv0", 0), # TODO - ] + if arg_pico_platform == "rp2040": + all_nodes += [ + synthetic_node("__aeabi_idiv0", 0), # TODO + synthetic_node("__aeabi_ldiv0", 0), # TODO + ] - # main ########################################################### + # Tie it all together ############################################ def thread_filter(name: str) -> bool: return sbc_is_thread(name) def intrhandler_filter(name: str) -> bool: name = name.rsplit(":", 1)[-1] - return sbc_is_intrhandler(name) or pico_is_intrhandler(name) + for hook in hooks_is_intrhandler: + if hook(name): + return True + return False def location_xform(loc: str) -> str: if not loc.startswith("/"): @@ -660,30 +766,26 @@ def main( loc = elem.attrs.get("label", "") line = read_source(loc) - ret = sbc_indirect_callees(loc, line) - if ret is not None: - return ret + for hook in hooks_indirect_callees: + ret = hook(loc, line) + if ret is not None: + return ret - ret = pico_indirect_callees(loc, line) - if ret is not None: - return ret - - ret = tud_indirect_callees(loc, line) - if ret is not None: - return ret - - return [f"__indirect_call:" + location_xform(elem.attrs.get("label", ""))] + placeholder = "__indirect_call" + if m := re_call_other.fullmatch(line): + placeholder += ":" + m.group("func") + placeholder += " at " + location_xform(elem.attrs.get("label", "")) + return [placeholder] def skip_call(chain: list[str], call: str) -> bool: - return ( - sbc_skip_call(chain, call) - or pico_skip_call(chain, call) - or tud_skip_call(chain, call) - ) + for hook in hooks_skip_call: + if hook(chain, call): + return True + return False analyze( ci_fnames=arg_ci_fnames, - extra_nodes=pico_nodes + newlib_nodes + gcc_nodes, + extra_nodes=all_nodes, app_func_filters={ "Threads": thread_filter, "Interrupt handlers": intrhandler_filter, @@ -696,19 +798,19 @@ def main( if __name__ == "__main__": - base_dir = sys.argv[1] + pico_platform = sys.argv[1] + base_dir = sys.argv[2] + fnames = sys.argv[3:] re_suffix = re.compile(r"\.c\.o(bj)?$") - ci_fnames = [ - re_suffix.sub(".c.ci", fname) - for fname in sys.argv[2:] - if re_suffix.search(fname) + re_suffix.sub(".c.ci", fname) for fname in fnames if re_suffix.search(fname) ] - c_fnames = [fname for fname in sys.argv[2:] if fname.endswith(".c")] + c_fnames = [fname for fname in fnames if fname.endswith(".c")] main( + arg_pico_platform=pico_platform, arg_base_dir=base_dir, arg_ci_fnames=ci_fnames, arg_c_fnames=c_fnames, diff --git a/cmd/sbc_harness/CMakeLists.txt b/cmd/sbc_harness/CMakeLists.txt index 96c2a2c..f1b1be2 100644 --- a/cmd/sbc_harness/CMakeLists.txt +++ b/cmd/sbc_harness/CMakeLists.txt @@ -24,6 +24,7 @@ target_link_libraries(sbc_harness_objs libusb libdhcp libhw + lib9p ) pico_minimize_runtime(sbc_harness_objs INCLUDE PRINTF PRINTF_MINIMAL PRINTF_LONG_LONG PRINTF_PTRDIFF_T @@ -38,10 +39,6 @@ add_stack_analysis(sbc_harness_stack.c sbc_harness_objs) # Link ######################################################################### add_executable(sbc_harness) -set_source_files_properties("$<TARGET_OBJECTS:sbc_harness_objs>" PROPERTIES - EXTERNAL_OBJECT true - GENERATED true -) target_sources(sbc_harness PRIVATE sbc_harness_stack.c "$<TARGET_OBJECTS:sbc_harness_objs>" diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c index fb4b696..00f1c4a 100644 --- a/cmd/sbc_harness/main.c +++ b/cmd/sbc_harness/main.c @@ -13,17 +13,19 @@ #include <libhw/rp2040_hwspi.h> #include <libhw/w5500.h> #include <libmisc/hash.h> +#include <libmisc/vcall.h> #include <libusb/usb_common.h> #include <libdhcp/client.h> +#include <lib9p/srv.h> #define LOG_NAME MAIN #include <libmisc/log.h> #include "usb_keyboard.h" -#define ARRAY_LEN(arr) (sizeof(arr)/sizeof((arr)[0])) +#include "config.h" -COROUTINE hello_world_cr(void *_chan) { +static COROUTINE hello_world_cr(void *_chan) { const char *msg = "Hello world!\n"; usb_keyboard_rpc_t *chan = _chan; cr_begin(); @@ -39,7 +41,7 @@ COROUTINE hello_world_cr(void *_chan) { cr_end(); } -COROUTINE dhcp_cr(void *_chip) { +static COROUTINE dhcp_cr(void *_chip) { struct w5500 *chip = _chip; cr_begin(); @@ -53,9 +55,20 @@ struct { struct w5500 dev_w5500; usb_keyboard_rpc_t keyboard_chan; uint16_t usb_serial[sizeof(uint64_t)*2]; /* UTF-16 */ + struct lib9p_srv srv; } globals; +static COROUTINE read9p_cr(void *) { + cr_begin(); + + lib9p_srv_read_cr(&globals.srv, + VCALL(&globals.dev_w5500, tcp_listen, CONFIG_9P_PORT)); + + cr_end(); +} + const char *hexdig = "0123456789ABCDEF"; +static_assert(CONFIG_9P_MAX_REQS*_CONFIG_9P_NUM_SOCKS <= 16); COROUTINE init_cr(void *) { cr_begin(); @@ -91,8 +104,8 @@ COROUTINE init_cr(void *) { flash_id24[0], flash_id24[1], flash_id24[2], }})); - static_assert(sizeof(flash_id64)*2 == ARRAY_LEN(globals.usb_serial)); - for (size_t i = 0; i < ARRAY_LEN(globals.usb_serial); i++) + static_assert(sizeof(flash_id64)*2 == LM_ARRAY_LEN(globals.usb_serial)); + for (size_t i = 0; i < LM_ARRAY_LEN(globals.usb_serial); i++) globals.usb_serial[i] = hexdig[(flash_id64 >> ((sizeof(flash_id64)*8)-((i+1)*4))) & 0xF]; usb_common_earlyinit(globals.usb_serial, sizeof(globals.usb_serial)); usb_keyboard_init(); @@ -103,8 +116,16 @@ COROUTINE init_cr(void *) { /* set up coroutines **************************************************/ coroutine_add("usb_common", usb_common_cr, NULL); coroutine_add("usb_keyboard", usb_keyboard_cr, &globals.keyboard_chan); - //coroutine_add("hello_world", hello_world_cr, &keyboard_chan); + coroutine_add("hello_world", hello_world_cr, &globals.keyboard_chan); coroutine_add_with_stack_size(4*1024, "dhcp", dhcp_cr, &globals.dev_w5500); + for (int i = 0; i < _CONFIG_9P_NUM_SOCKS; i++) { + char name[] = {'r', 'e', 'a', 'd', '-', hexdig[i], '\0'}; + coroutine_add(name, read9p_cr, NULL); + } + for (int i = 0; i < CONFIG_9P_MAX_REQS*_CONFIG_9P_NUM_SOCKS; i++) { + char name[] = {'w', 'r', 'i', 't', 'e', '-', hexdig[i], '\0'}; + coroutine_add(name, lib9p_srv_write_cr, &globals.srv); + } cr_exit(); } diff --git a/cmd/sbc_harness/usb_keyboard.c b/cmd/sbc_harness/usb_keyboard.c index f4816c1..b781d4d 100644 --- a/cmd/sbc_harness/usb_keyboard.c +++ b/cmd/sbc_harness/usb_keyboard.c @@ -8,11 +8,10 @@ #include <libusb/tusb_helpers.h> /* for TUD_ENDPOINT_IN */ #include <libusb/usb_common.h> +#include <libmisc/macro.h> #include "usb_keyboard.h" -#define UNUSED(name) - /** * A USB-HID "Report Descriptor" (see USB-HID 1.11 §6.2.2 "Report * Descriptor") describing a keyboard. @@ -108,7 +107,11 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t // Invoked when received SET_REPORT control request or // received data on OUT endpoint ( Report ID = 0, Type = 0 ) -void tud_hid_set_report_cb(uint8_t UNUSED(instance), uint8_t UNUSED(report_id), hid_report_type_t UNUSED(report_type), uint8_t const *UNUSED(buffer), uint16_t UNUSED(bufsize)) +void tud_hid_set_report_cb(uint8_t LM_UNUSED(instance), + uint8_t LM_UNUSED(report_id), + hid_report_type_t LM_UNUSED(report_type), + uint8_t const *LM_UNUSED(buffer), + uint16_t LM_UNUSED(bufsize)) { // TODO not implemented } diff --git a/cmd/srv9p/CMakeLists.txt b/cmd/srv9p/CMakeLists.txt index b747882..0d8e320 100644 --- a/cmd/srv9p/CMakeLists.txt +++ b/cmd/srv9p/CMakeLists.txt @@ -5,21 +5,38 @@ if (PICO_PLATFORM STREQUAL "host") -add_executable(srv9p +# Compile ###################################################################### + +add_library(srv9p_objs OBJECT main.c - static9p.c -) -target_embed_sources(srv9p static.h - static/README.md - static/Documentation/x ) -target_include_directories(srv9p PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_include_directories(srv9p PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) -target_link_libraries(srv9p +target_include_directories(srv9p_objs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/config) +target_include_directories(srv9p_objs PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(srv9p_objs libcr libcr_ipc libmisc lib9p + lib9p_util +) + +# Analyze the stack ############################################################ + +add_stack_analysis(srv9p_stack.c srv9p_objs) + +# Link ######################################################################### + +add_executable(srv9p) +target_sources(srv9p PRIVATE + srv9p_stack.c + "$<TARGET_OBJECTS:srv9p_objs>" +) + +# Embed ######################################################################## + +target_embed_sources(srv9p_objs srv9p static.h + static/README.md + static/Documentation/x ) endif() diff --git a/cmd/srv9p/main.c b/cmd/srv9p/main.c index 05368e5..b5cb122 100644 --- a/cmd/srv9p/main.c +++ b/cmd/srv9p/main.c @@ -11,8 +11,9 @@ #include <libhw/generic/net.h> #include <libhw/generic/alarmclock.h> #include <libhw/host_net.h> +#include <libmisc/macro.h> +#include <util9p/static.h> -#include "static9p.h" #include "static.h" /* configuration **************************************************************/ @@ -25,12 +26,10 @@ /* implementation *************************************************************/ -#define UNUSED(name) - /* file tree ******************************************************************/ -#define FILE_COMMON(NAME) { \ - .vtable = &static_file_vtable, \ +#define FILE_COMMON(NAME) { \ + .vtable = &util9p_static_file_vtable, \ \ .u_name = "root", .u_num = 0, /* owner user */ \ .g_name = "root", .g_num = 0, /* owner group */ \ @@ -43,8 +42,8 @@ .mtime = 1728337904, \ } -#define DIR_COMMON(NAME) { \ - .vtable = &static_dir_vtable, \ +#define DIR_COMMON(NAME) { \ + .vtable = &util9p_static_dir_vtable, \ \ .u_name = "root", .u_num = 0, /* owner user */ \ .g_name = "root", .g_num = 0, /* owner group */ \ @@ -57,18 +56,18 @@ .mtime = 1728337904, \ } -#define STATIC_FILE(STRNAME, SYMNAME) \ - &((static struct static_file){ \ - ._static_common = FILE_COMMON(STRNAME), \ - .data_start = _binary_static_##SYMNAME##_start, \ - .data_end = _binary_static_##SYMNAME##_end, \ +#define STATIC_FILE(STRNAME, SYMNAME) \ + &((static struct util9p_static_file){ \ + ._util9p_static_common = FILE_COMMON(STRNAME), \ + .data_start = _binary_static_##SYMNAME##_start, \ + .data_end = _binary_static_##SYMNAME##_end, \ }) -static struct static_dir root = { - ._static_common = DIR_COMMON(""), +static struct util9p_static_dir root = { + ._util9p_static_common = DIR_COMMON(""), .members = { - &((static struct static_dir){ - ._static_common = DIR_COMMON("Documentation"), + &((static struct util9p_static_dir){ + ._util9p_static_common = DIR_COMMON("Documentation"), .members = { STATIC_FILE("x", Documentation_x), NULL @@ -79,7 +78,7 @@ static struct static_dir root = { }, }; -static implements_lib9p_srv_file *get_root(struct lib9p_srv_ctx *UNUSED(ctx), char *UNUSED(treename)) { +static implements_lib9p_srv_file *get_root(struct lib9p_srv_ctx *LM_UNUSED(ctx), char *LM_UNUSED(treename)) { return &root; } @@ -65,8 +65,11 @@ int lib9p_errorf(struct lib9p_ctx *ctx, uint32_t linux_errno, char const *fmt, . } const char *lib9p_msg_type_str(struct lib9p_ctx *ctx, enum lib9p_msg_type typ) { - assert(0 <= typ && typ <= 0xFF); - return _lib9p_versions[ctx->version].msgs[typ].name; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" + assert(0 <= typ && typ <= 0xFF); +#pragma GCC diagnostic pop + return _lib9p_versions[ctx->version].msgs[typ].name; } /* main message functions *****************************************************/ diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c index f3a907b..d3dc36a 100644 --- a/lib9p/9p.generated.c +++ b/lib9p/9p.generated.c @@ -27,13 +27,16 @@ static const char *version_strs[LIB9P_VER_NUM] = { }; const char *lib9p_version_str(enum lib9p_version ver) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" assert(0 <= ver && ver < LIB9P_VER_NUM); +#pragma GCC diagnostic pop return version_strs[ver]; } /* validate_* *****************************************************************/ -ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { +LM_ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { if (__builtin_add_overflow(ctx->net_offset, n, &ctx->net_offset)) /* If needed-net-size overflowed uint32_t, then * there's no way that actual-net-size will live up to @@ -44,7 +47,7 @@ ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t return false; } -ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { +LM_ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { if (__builtin_add_overflow(ctx->host_extra, n, &ctx->host_extra)) /* If needed-host-size overflowed size_t, then there's * no way that actual-net-size will live up to @@ -53,7 +56,7 @@ ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t return false; } -ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, +LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, size_t cnt, _validate_fn_t item_fn, size_t item_host_size) { for (size_t i = 0; i < cnt; i++) @@ -68,15 +71,15 @@ ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, #define validate_8(ctx) _validate_size_net(ctx, 8) #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_u -ALWAYS_INLINE static bool validate_tag(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_tag(struct _validate_ctx *ctx) { return validate_2(ctx); } -ALWAYS_INLINE static bool validate_fid(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_fid(struct _validate_ctx *ctx) { return validate_4(ctx); } -ALWAYS_INLINE static bool validate_d(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_d(struct _validate_ctx *ctx) { uint32_t base_offset = ctx->net_offset; if (validate_4(ctx)) return true; @@ -84,7 +87,7 @@ ALWAYS_INLINE static bool validate_d(struct _validate_ctx *ctx) { return _validate_size_net(ctx, len) || _validate_size_host(ctx, len); } -ALWAYS_INLINE static bool validate_s(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_s(struct _validate_ctx *ctx) { uint32_t base_offset = ctx->net_offset; if (validate_2(ctx)) return true; @@ -107,7 +110,7 @@ static const lib9p_dm_t dm_masks[LIB9P_VER_NUM] = { [LIB9P_VER_9P2000_u] = 0b11101100101111000000000111111111, #endif /* CONFIG_9P_ENABLE_9P2000_u */ }; -ALWAYS_INLINE static bool validate_dm(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_dm(struct _validate_ctx *ctx) { if (validate_4(ctx)) return true; lib9p_dm_t mask = dm_masks[ctx->ctx->version]; @@ -128,7 +131,7 @@ static const lib9p_qt_t qt_masks[LIB9P_VER_NUM] = { [LIB9P_VER_9P2000_u] = 0b11101110, #endif /* CONFIG_9P_ENABLE_9P2000_u */ }; -ALWAYS_INLINE static bool validate_qt(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_qt(struct _validate_ctx *ctx) { if (validate_1(ctx)) return true; lib9p_qt_t mask = qt_masks[ctx->ctx->version]; @@ -138,7 +141,7 @@ ALWAYS_INLINE static bool validate_qt(struct _validate_ctx *ctx) { return false; } -ALWAYS_INLINE static bool validate_qid(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_qid(struct _validate_ctx *ctx) { return false || validate_qt(ctx) || validate_4(ctx) @@ -146,7 +149,7 @@ ALWAYS_INLINE static bool validate_qid(struct _validate_ctx *ctx) { ; } -ALWAYS_INLINE static bool validate_stat(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_stat(struct _validate_ctx *ctx) { uint16_t stat_size; uint32_t _kern_type_offset; return false @@ -184,7 +187,7 @@ static const lib9p_o_t o_masks[LIB9P_VER_NUM] = { [LIB9P_VER_9P2000_u] = 0b01010011, #endif /* CONFIG_9P_ENABLE_9P2000_u */ }; -ALWAYS_INLINE static bool validate_o(struct _validate_ctx *ctx) { +LM_ALWAYS_INLINE static bool validate_o(struct _validate_ctx *ctx) { if (validate_1(ctx)) return true; lib9p_o_t mask = o_masks[ctx->ctx->version]; @@ -194,7 +197,7 @@ ALWAYS_INLINE static bool validate_o(struct _validate_ctx *ctx) { return false; } -FLATTEN static bool validate_Tversion(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tversion(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -211,7 +214,7 @@ FLATTEN static bool validate_Tversion(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rversion(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rversion(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -228,7 +231,7 @@ FLATTEN static bool validate_Rversion(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tauth(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tauth(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -249,7 +252,7 @@ FLATTEN static bool validate_Tauth(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rauth(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rauth(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -265,7 +268,7 @@ FLATTEN static bool validate_Rauth(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tattach(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tattach(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -287,7 +290,7 @@ FLATTEN static bool validate_Tattach(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rattach(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rattach(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -303,7 +306,7 @@ FLATTEN static bool validate_Rattach(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rerror(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rerror(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -322,7 +325,7 @@ FLATTEN static bool validate_Rerror(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tflush(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tflush(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -338,7 +341,7 @@ FLATTEN static bool validate_Tflush(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rflush(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rflush(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -353,7 +356,7 @@ FLATTEN static bool validate_Rflush(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Twalk(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Twalk(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint16_t nwname; @@ -375,7 +378,7 @@ FLATTEN static bool validate_Twalk(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rwalk(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rwalk(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint16_t nwqid; @@ -395,7 +398,7 @@ FLATTEN static bool validate_Rwalk(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Topen(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Topen(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -412,7 +415,7 @@ FLATTEN static bool validate_Topen(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Ropen(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Ropen(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -429,7 +432,7 @@ FLATTEN static bool validate_Ropen(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tcreate(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tcreate(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -448,7 +451,7 @@ FLATTEN static bool validate_Tcreate(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rcreate(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rcreate(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -465,7 +468,7 @@ FLATTEN static bool validate_Rcreate(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tread(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tread(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -483,7 +486,7 @@ FLATTEN static bool validate_Tread(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rread(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rread(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -499,7 +502,7 @@ FLATTEN static bool validate_Rread(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Twrite(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Twrite(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -517,7 +520,7 @@ FLATTEN static bool validate_Twrite(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rwrite(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rwrite(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -533,7 +536,7 @@ FLATTEN static bool validate_Rwrite(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tclunk(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tclunk(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -549,7 +552,7 @@ FLATTEN static bool validate_Tclunk(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rclunk(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rclunk(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -564,7 +567,7 @@ FLATTEN static bool validate_Rclunk(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tremove(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tremove(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -580,7 +583,7 @@ FLATTEN static bool validate_Tremove(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rremove(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rremove(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -595,7 +598,7 @@ FLATTEN static bool validate_Rremove(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tstat(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tstat(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -611,7 +614,7 @@ FLATTEN static bool validate_Tstat(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rstat(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rstat(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint16_t nstat; @@ -632,7 +635,7 @@ FLATTEN static bool validate_Rstat(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Twstat(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Twstat(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint16_t nstat; @@ -654,7 +657,7 @@ FLATTEN static bool validate_Twstat(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rwstat(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rwstat(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -671,7 +674,7 @@ FLATTEN static bool validate_Rwstat(struct _validate_ctx *ctx) { #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000_e -FLATTEN static bool validate_Tsession(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tsession(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -687,7 +690,7 @@ FLATTEN static bool validate_Tsession(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rsession(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rsession(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -702,7 +705,7 @@ FLATTEN static bool validate_Rsession(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tsread(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tsread(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -720,7 +723,7 @@ FLATTEN static bool validate_Tsread(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rsread(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rsread(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -736,7 +739,7 @@ FLATTEN static bool validate_Rsread(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Tswrite(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Tswrite(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -755,7 +758,7 @@ FLATTEN static bool validate_Tswrite(struct _validate_ctx *ctx) { ; } -FLATTEN static bool validate_Rswrite(struct _validate_ctx *ctx) { +LM_FLATTEN static bool validate_Rswrite(struct _validate_ctx *ctx) { uint32_t size; uint8_t typ; uint32_t _size_offset; @@ -774,36 +777,36 @@ FLATTEN static bool validate_Rswrite(struct _validate_ctx *ctx) { /* unmarshal_* ****************************************************************/ -ALWAYS_INLINE static void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) { +LM_ALWAYS_INLINE static void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) { *out = decode_u8le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 1; } -ALWAYS_INLINE static void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) { +LM_ALWAYS_INLINE static void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) { *out = decode_u16le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 2; } -ALWAYS_INLINE static void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) { +LM_ALWAYS_INLINE static void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) { *out = decode_u32le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 4; } -ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) { +LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) { *out = decode_u64le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 8; } #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_u -ALWAYS_INLINE static void unmarshal_tag(struct _unmarshal_ctx *ctx, lib9p_tag_t *out) { +LM_ALWAYS_INLINE static void unmarshal_tag(struct _unmarshal_ctx *ctx, lib9p_tag_t *out) { unmarshal_2(ctx, (uint16_t *)out); } -ALWAYS_INLINE static void unmarshal_fid(struct _unmarshal_ctx *ctx, lib9p_fid_t *out) { +LM_ALWAYS_INLINE static void unmarshal_fid(struct _unmarshal_ctx *ctx, lib9p_fid_t *out) { unmarshal_4(ctx, (uint32_t *)out); } -ALWAYS_INLINE static void unmarshal_d(struct _unmarshal_ctx *ctx, struct lib9p_d *out) { +LM_ALWAYS_INLINE static void unmarshal_d(struct _unmarshal_ctx *ctx, struct lib9p_d *out) { memset(out, 0, sizeof(*out)); unmarshal_4(ctx, &out->len); out->dat = ctx->extra; @@ -812,7 +815,7 @@ ALWAYS_INLINE static void unmarshal_d(struct _unmarshal_ctx *ctx, struct lib9p_d unmarshal_1(ctx, (uint8_t *)&out->dat[i]); } -ALWAYS_INLINE static void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s *out) { +LM_ALWAYS_INLINE static void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s *out) { memset(out, 0, sizeof(*out)); unmarshal_2(ctx, &out->len); out->utf8 = ctx->extra; @@ -823,22 +826,22 @@ ALWAYS_INLINE static void unmarshal_s(struct _unmarshal_ctx *ctx, struct lib9p_s out->utf8[out->len] = '\0'; } -ALWAYS_INLINE static void unmarshal_dm(struct _unmarshal_ctx *ctx, lib9p_dm_t *out) { +LM_ALWAYS_INLINE static void unmarshal_dm(struct _unmarshal_ctx *ctx, lib9p_dm_t *out) { unmarshal_4(ctx, (uint32_t *)out); } -ALWAYS_INLINE static void unmarshal_qt(struct _unmarshal_ctx *ctx, lib9p_qt_t *out) { +LM_ALWAYS_INLINE static void unmarshal_qt(struct _unmarshal_ctx *ctx, lib9p_qt_t *out) { unmarshal_1(ctx, (uint8_t *)out); } -ALWAYS_INLINE static void unmarshal_qid(struct _unmarshal_ctx *ctx, struct lib9p_qid *out) { +LM_ALWAYS_INLINE static void unmarshal_qid(struct _unmarshal_ctx *ctx, struct lib9p_qid *out) { memset(out, 0, sizeof(*out)); unmarshal_qt(ctx, &out->type); unmarshal_4(ctx, &out->vers); unmarshal_8(ctx, &out->path); } -ALWAYS_INLINE static void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) { +LM_ALWAYS_INLINE static void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 2; unmarshal_2(ctx, &out->kern_type); @@ -860,11 +863,11 @@ ALWAYS_INLINE static void unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9 #endif /* CONFIG_9P_ENABLE_9P2000_u */ } -ALWAYS_INLINE static void unmarshal_o(struct _unmarshal_ctx *ctx, lib9p_o_t *out) { +LM_ALWAYS_INLINE static void unmarshal_o(struct _unmarshal_ctx *ctx, lib9p_o_t *out) { unmarshal_1(ctx, (uint8_t *)out); } -FLATTEN static void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tversion *out) { +LM_FLATTEN static void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tversion *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -873,7 +876,7 @@ FLATTEN static void unmarshal_Tversion(struct _unmarshal_ctx *ctx, struct lib9p_ unmarshal_s(ctx, &out->version); } -FLATTEN static void unmarshal_Rversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rversion *out) { +LM_FLATTEN static void unmarshal_Rversion(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rversion *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -882,7 +885,7 @@ FLATTEN static void unmarshal_Rversion(struct _unmarshal_ctx *ctx, struct lib9p_ unmarshal_s(ctx, &out->version); } -FLATTEN static void unmarshal_Tauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tauth *out) { +LM_FLATTEN static void unmarshal_Tauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tauth *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -895,7 +898,7 @@ FLATTEN static void unmarshal_Tauth(struct _unmarshal_ctx *ctx, struct lib9p_msg #endif /* CONFIG_9P_ENABLE_9P2000_u */ } -FLATTEN static void unmarshal_Rauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rauth *out) { +LM_FLATTEN static void unmarshal_Rauth(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rauth *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -903,7 +906,7 @@ FLATTEN static void unmarshal_Rauth(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_qid(ctx, &out->aqid); } -FLATTEN static void unmarshal_Tattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tattach *out) { +LM_FLATTEN static void unmarshal_Tattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tattach *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -917,7 +920,7 @@ FLATTEN static void unmarshal_Tattach(struct _unmarshal_ctx *ctx, struct lib9p_m #endif /* CONFIG_9P_ENABLE_9P2000_u */ } -FLATTEN static void unmarshal_Rattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rattach *out) { +LM_FLATTEN static void unmarshal_Rattach(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rattach *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -925,7 +928,7 @@ FLATTEN static void unmarshal_Rattach(struct _unmarshal_ctx *ctx, struct lib9p_m unmarshal_qid(ctx, &out->qid); } -FLATTEN static void unmarshal_Rerror(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rerror *out) { +LM_FLATTEN static void unmarshal_Rerror(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rerror *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -936,7 +939,7 @@ FLATTEN static void unmarshal_Rerror(struct _unmarshal_ctx *ctx, struct lib9p_ms #endif /* CONFIG_9P_ENABLE_9P2000_u */ } -FLATTEN static void unmarshal_Tflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tflush *out) { +LM_FLATTEN static void unmarshal_Tflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tflush *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -944,14 +947,14 @@ FLATTEN static void unmarshal_Tflush(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_2(ctx, &out->oldtag); } -FLATTEN static void unmarshal_Rflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rflush *out) { +LM_FLATTEN static void unmarshal_Rflush(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rflush *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; unmarshal_tag(ctx, &out->tag); } -FLATTEN static void unmarshal_Twalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twalk *out) { +LM_FLATTEN static void unmarshal_Twalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twalk *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -965,7 +968,7 @@ FLATTEN static void unmarshal_Twalk(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_s(ctx, &out->wname[i]); } -FLATTEN static void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwalk *out) { +LM_FLATTEN static void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwalk *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -977,7 +980,7 @@ FLATTEN static void unmarshal_Rwalk(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_qid(ctx, &out->wqid[i]); } -FLATTEN static void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) { +LM_FLATTEN static void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Topen *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -986,7 +989,7 @@ FLATTEN static void unmarshal_Topen(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_o(ctx, &out->mode); } -FLATTEN static void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) { +LM_FLATTEN static void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg_Ropen *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -995,7 +998,7 @@ FLATTEN static void unmarshal_Ropen(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_4(ctx, &out->iounit); } -FLATTEN static void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tcreate *out) { +LM_FLATTEN static void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tcreate *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1006,7 +1009,7 @@ FLATTEN static void unmarshal_Tcreate(struct _unmarshal_ctx *ctx, struct lib9p_m unmarshal_o(ctx, &out->mode); } -FLATTEN static void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) { +LM_FLATTEN static void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rcreate *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1015,7 +1018,7 @@ FLATTEN static void unmarshal_Rcreate(struct _unmarshal_ctx *ctx, struct lib9p_m unmarshal_4(ctx, &out->iounit); } -FLATTEN static void unmarshal_Tread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tread *out) { +LM_FLATTEN static void unmarshal_Tread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tread *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1025,7 +1028,7 @@ FLATTEN static void unmarshal_Tread(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_4(ctx, &out->count); } -FLATTEN static void unmarshal_Rread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rread *out) { +LM_FLATTEN static void unmarshal_Rread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rread *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1033,7 +1036,7 @@ FLATTEN static void unmarshal_Rread(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_d(ctx, &out->data); } -FLATTEN static void unmarshal_Twrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twrite *out) { +LM_FLATTEN static void unmarshal_Twrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twrite *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1043,7 +1046,7 @@ FLATTEN static void unmarshal_Twrite(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_d(ctx, &out->data); } -FLATTEN static void unmarshal_Rwrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwrite *out) { +LM_FLATTEN static void unmarshal_Rwrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwrite *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1051,7 +1054,7 @@ FLATTEN static void unmarshal_Rwrite(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_4(ctx, &out->count); } -FLATTEN static void unmarshal_Tclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tclunk *out) { +LM_FLATTEN static void unmarshal_Tclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tclunk *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1059,14 +1062,14 @@ FLATTEN static void unmarshal_Tclunk(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_fid(ctx, &out->fid); } -FLATTEN static void unmarshal_Rclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rclunk *out) { +LM_FLATTEN static void unmarshal_Rclunk(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rclunk *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; unmarshal_tag(ctx, &out->tag); } -FLATTEN static void unmarshal_Tremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tremove *out) { +LM_FLATTEN static void unmarshal_Tremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tremove *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1074,14 +1077,14 @@ FLATTEN static void unmarshal_Tremove(struct _unmarshal_ctx *ctx, struct lib9p_m unmarshal_fid(ctx, &out->fid); } -FLATTEN static void unmarshal_Rremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rremove *out) { +LM_FLATTEN static void unmarshal_Rremove(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rremove *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; unmarshal_tag(ctx, &out->tag); } -FLATTEN static void unmarshal_Tstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tstat *out) { +LM_FLATTEN static void unmarshal_Tstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tstat *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1089,7 +1092,7 @@ FLATTEN static void unmarshal_Tstat(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_fid(ctx, &out->fid); } -FLATTEN static void unmarshal_Rstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rstat *out) { +LM_FLATTEN static void unmarshal_Rstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rstat *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1098,7 +1101,7 @@ FLATTEN static void unmarshal_Rstat(struct _unmarshal_ctx *ctx, struct lib9p_msg unmarshal_stat(ctx, &out->stat); } -FLATTEN static void unmarshal_Twstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twstat *out) { +LM_FLATTEN static void unmarshal_Twstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Twstat *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1108,7 +1111,7 @@ FLATTEN static void unmarshal_Twstat(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_stat(ctx, &out->stat); } -FLATTEN static void unmarshal_Rwstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwstat *out) { +LM_FLATTEN static void unmarshal_Rwstat(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rwstat *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1117,7 +1120,7 @@ FLATTEN static void unmarshal_Rwstat(struct _unmarshal_ctx *ctx, struct lib9p_ms #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000_e -FLATTEN static void unmarshal_Tsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsession *out) { +LM_FLATTEN static void unmarshal_Tsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsession *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1125,14 +1128,14 @@ FLATTEN static void unmarshal_Tsession(struct _unmarshal_ctx *ctx, struct lib9p_ unmarshal_8(ctx, &out->key); } -FLATTEN static void unmarshal_Rsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsession *out) { +LM_FLATTEN static void unmarshal_Rsession(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsession *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; unmarshal_tag(ctx, &out->tag); } -FLATTEN static void unmarshal_Tsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsread *out) { +LM_FLATTEN static void unmarshal_Tsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tsread *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1145,7 +1148,7 @@ FLATTEN static void unmarshal_Tsread(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_s(ctx, &out->wname[i]); } -FLATTEN static void unmarshal_Rsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsread *out) { +LM_FLATTEN static void unmarshal_Rsread(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rsread *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1153,7 +1156,7 @@ FLATTEN static void unmarshal_Rsread(struct _unmarshal_ctx *ctx, struct lib9p_ms unmarshal_d(ctx, &out->data); } -FLATTEN static void unmarshal_Tswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tswrite *out) { +LM_FLATTEN static void unmarshal_Tswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Tswrite *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1167,7 +1170,7 @@ FLATTEN static void unmarshal_Tswrite(struct _unmarshal_ctx *ctx, struct lib9p_m unmarshal_d(ctx, &out->data); } -FLATTEN static void unmarshal_Rswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rswrite *out) { +LM_FLATTEN static void unmarshal_Rswrite(struct _unmarshal_ctx *ctx, struct lib9p_msg_Rswrite *out) { memset(out, 0, sizeof(*out)); ctx->net_offset += 4; ctx->net_offset += 1; @@ -1178,7 +1181,7 @@ FLATTEN static void unmarshal_Rswrite(struct _unmarshal_ctx *ctx, struct lib9p_m /* marshal_* ******************************************************************/ -ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) { +LM_ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) { lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")", (ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message", ctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"), @@ -1186,7 +1189,7 @@ ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) { return true; } -ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) { +LM_ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) { if (ctx->net_offset + 1 > ctx->ctx->max_msg_size) return _marshal_too_large(ctx); ctx->net_bytes[ctx->net_offset] = *val; @@ -1194,7 +1197,7 @@ ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) { return false; } -ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) { +LM_ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) { if (ctx->net_offset + 2 > ctx->ctx->max_msg_size) return _marshal_too_large(ctx); encode_u16le(*val, &ctx->net_bytes[ctx->net_offset]); @@ -1202,7 +1205,7 @@ ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) { return false; } -ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) { +LM_ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) { if (ctx->net_offset + 4 > ctx->ctx->max_msg_size) return true; encode_u32le(*val, &ctx->net_bytes[ctx->net_offset]); @@ -1210,7 +1213,7 @@ ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) { return false; } -ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { +LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { if (ctx->net_offset + 8 > ctx->ctx->max_msg_size) return true; encode_u64le(*val, &ctx->net_bytes[ctx->net_offset]); @@ -1219,15 +1222,15 @@ ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { } #if CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_u -ALWAYS_INLINE static bool marshal_tag(struct _marshal_ctx *ctx, lib9p_tag_t *val) { +LM_ALWAYS_INLINE static bool marshal_tag(struct _marshal_ctx *ctx, lib9p_tag_t *val) { return marshal_2(ctx, (uint16_t *)val); } -ALWAYS_INLINE static bool marshal_fid(struct _marshal_ctx *ctx, lib9p_fid_t *val) { +LM_ALWAYS_INLINE static bool marshal_fid(struct _marshal_ctx *ctx, lib9p_fid_t *val) { return marshal_4(ctx, (uint32_t *)val); } -ALWAYS_INLINE static bool marshal_d(struct _marshal_ctx *ctx, struct lib9p_d *val) { +LM_ALWAYS_INLINE static bool marshal_d(struct _marshal_ctx *ctx, struct lib9p_d *val) { return false || marshal_4(ctx, &val->len) || ({ bool err = false; @@ -1237,7 +1240,7 @@ ALWAYS_INLINE static bool marshal_d(struct _marshal_ctx *ctx, struct lib9p_d *va ; } -ALWAYS_INLINE static bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *val) { +LM_ALWAYS_INLINE static bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *val) { return false || marshal_2(ctx, &val->len) || ({ bool err = false; @@ -1247,17 +1250,17 @@ ALWAYS_INLINE static bool marshal_s(struct _marshal_ctx *ctx, struct lib9p_s *va ; } -ALWAYS_INLINE static bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) { +LM_ALWAYS_INLINE static bool marshal_dm(struct _marshal_ctx *ctx, lib9p_dm_t *val) { lib9p_dm_t masked_val = *val & dm_masks[ctx->ctx->version]; return marshal_4(ctx, (uint32_t *)&masked_val); } -ALWAYS_INLINE static bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) { +LM_ALWAYS_INLINE static bool marshal_qt(struct _marshal_ctx *ctx, lib9p_qt_t *val) { lib9p_qt_t masked_val = *val & qt_masks[ctx->ctx->version]; return marshal_1(ctx, (uint8_t *)&masked_val); } -ALWAYS_INLINE static bool marshal_qid(struct _marshal_ctx *ctx, struct lib9p_qid *val) { +LM_ALWAYS_INLINE static bool marshal_qid(struct _marshal_ctx *ctx, struct lib9p_qid *val) { return false || marshal_qt(ctx, &val->type) || marshal_4(ctx, &val->vers) @@ -1265,7 +1268,7 @@ ALWAYS_INLINE static bool marshal_qid(struct _marshal_ctx *ctx, struct lib9p_qid ; } -ALWAYS_INLINE static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { +LM_ALWAYS_INLINE static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { uint32_t _stat_size_offset; uint32_t _kern_type_offset; return false @@ -1291,12 +1294,12 @@ ALWAYS_INLINE static bool marshal_stat(struct _marshal_ctx *ctx, struct lib9p_st ; } -ALWAYS_INLINE static bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) { +LM_ALWAYS_INLINE static bool marshal_o(struct _marshal_ctx *ctx, lib9p_o_t *val) { lib9p_o_t masked_val = *val & o_masks[ctx->ctx->version]; return marshal_1(ctx, (uint8_t *)&masked_val); } -FLATTEN static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) { +LM_FLATTEN static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_Tversion *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1310,7 +1313,7 @@ FLATTEN static bool marshal_Tversion(struct _marshal_ctx *ctx, struct lib9p_msg_ ; } -FLATTEN static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion *val) { +LM_FLATTEN static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_Rversion *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1324,7 +1327,7 @@ FLATTEN static bool marshal_Rversion(struct _marshal_ctx *ctx, struct lib9p_msg_ ; } -FLATTEN static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) { +LM_FLATTEN static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tauth *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1342,7 +1345,7 @@ FLATTEN static bool marshal_Tauth(struct _marshal_ctx *ctx, struct lib9p_msg_Tau ; } -FLATTEN static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) { +LM_FLATTEN static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rauth *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1355,7 +1358,7 @@ FLATTEN static bool marshal_Rauth(struct _marshal_ctx *ctx, struct lib9p_msg_Rau ; } -FLATTEN static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach *val) { +LM_FLATTEN static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_Tattach *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1374,7 +1377,7 @@ FLATTEN static bool marshal_Tattach(struct _marshal_ctx *ctx, struct lib9p_msg_T ; } -FLATTEN static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach *val) { +LM_FLATTEN static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_Rattach *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1387,7 +1390,7 @@ FLATTEN static bool marshal_Rattach(struct _marshal_ctx *ctx, struct lib9p_msg_R ; } -FLATTEN static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *val) { +LM_FLATTEN static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Rerror *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1403,7 +1406,7 @@ FLATTEN static bool marshal_Rerror(struct _marshal_ctx *ctx, struct lib9p_msg_Re ; } -FLATTEN static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *val) { +LM_FLATTEN static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tflush *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1416,7 +1419,7 @@ FLATTEN static bool marshal_Tflush(struct _marshal_ctx *ctx, struct lib9p_msg_Tf ; } -FLATTEN static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *val) { +LM_FLATTEN static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rflush *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1428,7 +1431,7 @@ FLATTEN static bool marshal_Rflush(struct _marshal_ctx *ctx, struct lib9p_msg_Rf ; } -FLATTEN static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) { +LM_FLATTEN static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twalk *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1447,7 +1450,7 @@ FLATTEN static bool marshal_Twalk(struct _marshal_ctx *ctx, struct lib9p_msg_Twa ; } -FLATTEN static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) { +LM_FLATTEN static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwalk *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1464,7 +1467,7 @@ FLATTEN static bool marshal_Rwalk(struct _marshal_ctx *ctx, struct lib9p_msg_Rwa ; } -FLATTEN static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) { +LM_FLATTEN static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Topen *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1478,7 +1481,7 @@ FLATTEN static bool marshal_Topen(struct _marshal_ctx *ctx, struct lib9p_msg_Top ; } -FLATTEN static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) { +LM_FLATTEN static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Ropen *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1492,7 +1495,7 @@ FLATTEN static bool marshal_Ropen(struct _marshal_ctx *ctx, struct lib9p_msg_Rop ; } -FLATTEN static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) { +LM_FLATTEN static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Tcreate *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1508,7 +1511,7 @@ FLATTEN static bool marshal_Tcreate(struct _marshal_ctx *ctx, struct lib9p_msg_T ; } -FLATTEN static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) { +LM_FLATTEN static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_Rcreate *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1522,7 +1525,7 @@ FLATTEN static bool marshal_Rcreate(struct _marshal_ctx *ctx, struct lib9p_msg_R ; } -FLATTEN static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) { +LM_FLATTEN static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tread *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1537,7 +1540,7 @@ FLATTEN static bool marshal_Tread(struct _marshal_ctx *ctx, struct lib9p_msg_Tre ; } -FLATTEN static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) { +LM_FLATTEN static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rread *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1550,7 +1553,7 @@ FLATTEN static bool marshal_Rread(struct _marshal_ctx *ctx, struct lib9p_msg_Rre ; } -FLATTEN static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *val) { +LM_FLATTEN static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Twrite *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1565,7 +1568,7 @@ FLATTEN static bool marshal_Twrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tw ; } -FLATTEN static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *val) { +LM_FLATTEN static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rwrite *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1578,7 +1581,7 @@ FLATTEN static bool marshal_Rwrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rw ; } -FLATTEN static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *val) { +LM_FLATTEN static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tclunk *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1591,7 +1594,7 @@ FLATTEN static bool marshal_Tclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Tc ; } -FLATTEN static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *val) { +LM_FLATTEN static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rclunk *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1603,7 +1606,7 @@ FLATTEN static bool marshal_Rclunk(struct _marshal_ctx *ctx, struct lib9p_msg_Rc ; } -FLATTEN static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove *val) { +LM_FLATTEN static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_Tremove *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1616,7 +1619,7 @@ FLATTEN static bool marshal_Tremove(struct _marshal_ctx *ctx, struct lib9p_msg_T ; } -FLATTEN static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove *val) { +LM_FLATTEN static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_Rremove *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1628,7 +1631,7 @@ FLATTEN static bool marshal_Rremove(struct _marshal_ctx *ctx, struct lib9p_msg_R ; } -FLATTEN static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) { +LM_FLATTEN static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tstat *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1641,7 +1644,7 @@ FLATTEN static bool marshal_Tstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tst ; } -FLATTEN static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) { +LM_FLATTEN static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rstat *val) { uint32_t _size_offset; uint32_t _typ_offset; uint32_t _nstat_offset; @@ -1658,7 +1661,7 @@ FLATTEN static bool marshal_Rstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rst ; } -FLATTEN static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *val) { +LM_FLATTEN static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Twstat *val) { uint32_t _size_offset; uint32_t _typ_offset; uint32_t _nstat_offset; @@ -1676,7 +1679,7 @@ FLATTEN static bool marshal_Twstat(struct _marshal_ctx *ctx, struct lib9p_msg_Tw ; } -FLATTEN static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *val) { +LM_FLATTEN static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rwstat *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1690,7 +1693,7 @@ FLATTEN static bool marshal_Rwstat(struct _marshal_ctx *ctx, struct lib9p_msg_Rw #endif /* CONFIG_9P_ENABLE_9P2000 || CONFIG_9P_ENABLE_9P2000_e || CONFIG_9P_ENABLE_9P2000_u */ #if CONFIG_9P_ENABLE_9P2000_e -FLATTEN static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession *val) { +LM_FLATTEN static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_Tsession *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1703,7 +1706,7 @@ FLATTEN static bool marshal_Tsession(struct _marshal_ctx *ctx, struct lib9p_msg_ ; } -FLATTEN static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession *val) { +LM_FLATTEN static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_Rsession *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1715,7 +1718,7 @@ FLATTEN static bool marshal_Rsession(struct _marshal_ctx *ctx, struct lib9p_msg_ ; } -FLATTEN static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *val) { +LM_FLATTEN static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Tsread *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1733,7 +1736,7 @@ FLATTEN static bool marshal_Tsread(struct _marshal_ctx *ctx, struct lib9p_msg_Ts ; } -FLATTEN static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *val) { +LM_FLATTEN static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rsread *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1746,7 +1749,7 @@ FLATTEN static bool marshal_Rsread(struct _marshal_ctx *ctx, struct lib9p_msg_Rs ; } -FLATTEN static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite *val) { +LM_FLATTEN static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Tswrite *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -1765,7 +1768,7 @@ FLATTEN static bool marshal_Tswrite(struct _marshal_ctx *ctx, struct lib9p_msg_T ; } -FLATTEN static bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *val) { +LM_FLATTEN static bool marshal_Rswrite(struct _marshal_ctx *ctx, struct lib9p_msg_Rswrite *val) { uint32_t _size_offset; uint32_t _typ_offset; return false @@ -2833,12 +2836,12 @@ struct _table_version _lib9p_versions[LIB9P_VER_NUM] = { #endif /* CONFIG_9P_ENABLE_9P2000_u */ }; -FLATTEN bool _lib9p_validate_stat(struct _validate_ctx *ctx) { +LM_FLATTEN bool _lib9p_validate_stat(struct _validate_ctx *ctx) { return validate_stat(ctx); } -FLATTEN void _lib9p_unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) { +LM_FLATTEN void _lib9p_unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) { unmarshal_stat(ctx, out); } -FLATTEN bool _lib9p_marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { +LM_FLATTEN bool _lib9p_marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) { return marshal_stat(ctx, val); } diff --git a/lib9p/idl.gen b/lib9p/idl.gen index 262e5f0..ae7f1a5 100755 --- a/lib9p/idl.gen +++ b/lib9p/idl.gen @@ -708,7 +708,7 @@ def gen_c(versions: set[str], typs: list[Type]) -> str: return arg def unused(arg: str) -> str: - return f"UNUSED({arg})" + return f"LM_UNUSED({arg})" # strings ################################################################## ret += f""" @@ -724,7 +724,10 @@ static const char *version_strs[{c_ver_enum('NUM')}] = {{ ret += "};\n" ret += f""" const char *{idprefix}version_str(enum {idprefix}version ver) {{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wtype-limits" assert(0 <= ver && ver < {c_ver_enum('NUM')}); +#pragma GCC diagnostic pop return version_strs[ver]; }} """ @@ -733,7 +736,7 @@ const char *{idprefix}version_str(enum {idprefix}version ver) {{ ret += """ /* validate_* *****************************************************************/ -ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { +LM_ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t n) { if (__builtin_add_overflow(ctx->net_offset, n, &ctx->net_offset)) /* If needed-net-size overflowed uint32_t, then * there's no way that actual-net-size will live up to @@ -744,7 +747,7 @@ ALWAYS_INLINE static bool _validate_size_net(struct _validate_ctx *ctx, uint32_t return false; } -ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { +LM_ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t n) { if (__builtin_add_overflow(ctx->host_extra, n, &ctx->host_extra)) /* If needed-host-size overflowed size_t, then there's * no way that actual-net-size will live up to @@ -753,7 +756,7 @@ ALWAYS_INLINE static bool _validate_size_host(struct _validate_ctx *ctx, size_t return false; } -ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, +LM_ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, size_t cnt, _validate_fn_t item_fn, size_t item_host_size) { for (size_t i = 0; i < cnt; i++) @@ -768,7 +771,7 @@ ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, #define validate_8(ctx) _validate_size_net(ctx, 8) """ for typ in typs: - inline = "FLATTEN" if isinstance(typ, Message) else "ALWAYS_INLINE" + inline = "LM_FLATTEN" if isinstance(typ, Message) else "LM_ALWAYS_INLINE" argfn = unused if (isinstance(typ, Struct) and not typ.members) else used ret += "\n" ret += ifdef_push(1, c_ver_ifdef(typ.in_versions)) @@ -900,28 +903,28 @@ ALWAYS_INLINE static bool _validate_list(struct _validate_ctx *ctx, ret += """ /* unmarshal_* ****************************************************************/ -ALWAYS_INLINE static void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) { +LM_ALWAYS_INLINE static void unmarshal_1(struct _unmarshal_ctx *ctx, uint8_t *out) { *out = decode_u8le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 1; } -ALWAYS_INLINE static void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) { +LM_ALWAYS_INLINE static void unmarshal_2(struct _unmarshal_ctx *ctx, uint16_t *out) { *out = decode_u16le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 2; } -ALWAYS_INLINE static void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) { +LM_ALWAYS_INLINE static void unmarshal_4(struct _unmarshal_ctx *ctx, uint32_t *out) { *out = decode_u32le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 4; } -ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) { +LM_ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) { *out = decode_u64le(&ctx->net_bytes[ctx->net_offset]); ctx->net_offset += 8; } """ for typ in typs: - inline = "FLATTEN" if isinstance(typ, Message) else "ALWAYS_INLINE" + inline = "LM_FLATTEN" if isinstance(typ, Message) else "LM_ALWAYS_INLINE" argfn = unused if (isinstance(typ, Struct) and not typ.members) else used ret += "\n" ret += ifdef_push(1, c_ver_ifdef(typ.in_versions)) @@ -973,7 +976,7 @@ ALWAYS_INLINE static void unmarshal_8(struct _unmarshal_ctx *ctx, uint64_t *out) ret += """ /* marshal_* ******************************************************************/ -ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) { +LM_ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) { lib9p_errorf(ctx->ctx, LINUX_ERANGE, "%s too large to marshal into %s limit (limit=%"PRIu32")", (ctx->net_bytes[4] % 2 == 0) ? "T-message" : "R-message", ctx->ctx->version ? "negotiated" : ((ctx->net_bytes[4] % 2 == 0) ? "client" : "server"), @@ -981,7 +984,7 @@ ALWAYS_INLINE static bool _marshal_too_large(struct _marshal_ctx *ctx) { return true; } -ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) { +LM_ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) { if (ctx->net_offset + 1 > ctx->ctx->max_msg_size) return _marshal_too_large(ctx); ctx->net_bytes[ctx->net_offset] = *val; @@ -989,7 +992,7 @@ ALWAYS_INLINE static bool marshal_1(struct _marshal_ctx *ctx, uint8_t *val) { return false; } -ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) { +LM_ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) { if (ctx->net_offset + 2 > ctx->ctx->max_msg_size) return _marshal_too_large(ctx); encode_u16le(*val, &ctx->net_bytes[ctx->net_offset]); @@ -997,7 +1000,7 @@ ALWAYS_INLINE static bool marshal_2(struct _marshal_ctx *ctx, uint16_t *val) { return false; } -ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) { +LM_ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) { if (ctx->net_offset + 4 > ctx->ctx->max_msg_size) return true; encode_u32le(*val, &ctx->net_bytes[ctx->net_offset]); @@ -1005,7 +1008,7 @@ ALWAYS_INLINE static bool marshal_4(struct _marshal_ctx *ctx, uint32_t *val) { return false; } -ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { +LM_ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { if (ctx->net_offset + 8 > ctx->ctx->max_msg_size) return true; encode_u64le(*val, &ctx->net_bytes[ctx->net_offset]); @@ -1014,7 +1017,7 @@ ALWAYS_INLINE static bool marshal_8(struct _marshal_ctx *ctx, uint64_t *val) { } """ for typ in typs: - inline = "FLATTEN" if isinstance(typ, Message) else "ALWAYS_INLINE" + inline = "LM_FLATTEN" if isinstance(typ, Message) else "LM_ALWAYS_INLINE" argfn = unused if (isinstance(typ, Struct) and not typ.members) else used ret += "\n" ret += ifdef_push(1, c_ver_ifdef(typ.in_versions)) @@ -1133,13 +1136,13 @@ struct _table_version _{idprefix}versions[{c_ver_enum('NUM')}] = {{ ret += "};\n" ret += f""" -FLATTEN bool _{idprefix}validate_stat(struct _validate_ctx *ctx) {{ +LM_FLATTEN bool _{idprefix}validate_stat(struct _validate_ctx *ctx) {{ return validate_stat(ctx); }} -FLATTEN void _{idprefix}unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) {{ +LM_FLATTEN void _{idprefix}unmarshal_stat(struct _unmarshal_ctx *ctx, struct lib9p_stat *out) {{ unmarshal_stat(ctx, out); }} -FLATTEN bool _{idprefix}marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) {{ +LM_FLATTEN bool _{idprefix}marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val) {{ return marshal_stat(ctx, val); }} """ diff --git a/lib9p/internal.h b/lib9p/internal.h index 57f7aa7..b1a367d 100644 --- a/lib9p/internal.h +++ b/lib9p/internal.h @@ -8,7 +8,12 @@ #define _LIB9P_INTERNAL_H_ #include <stddef.h> /* for size_t */ -#include <limits.h> /* for SSIZE_MAX */ +#include <limits.h> /* for SSIZE_MAX, not set by newlib */ +#ifndef SSIZE_MAX +#define SSIZE_MAX (SIZE_MAX >> 1) +#endif + +#include <libmisc/macro.h> #include <lib9p/9p.h> @@ -36,15 +41,6 @@ static_assert(CONFIG_9P_MAX_ERR_SIZE <= UINT16_MAX); static_assert(CONFIG_9P_MAX_MSG_SIZE <= CONFIG_9P_MAX_HOSTMSG_SIZE); static_assert(CONFIG_9P_MAX_HOSTMSG_SIZE <= SSIZE_MAX); -/* C language *****************************************************************/ - -#define UNUSED(name) -#define ALWAYS_INLINE [[gnu::always_inline]] inline -#define FLATTEN [[gnu::flatten]] -#define ARRAY_LEN(arr) (sizeof(arr)/sizeof((arr)[0])) -#define CAT2(a, b) a##b -#define CAT3(a, b, c) a##b##c - /* specialized contexts *******************************************************/ struct _validate_ctx { @@ -99,22 +95,22 @@ bool _lib9p_marshal_stat(struct _marshal_ctx *ctx, struct lib9p_stat *val); /* unmarshal utilities ********************************************************/ -ALWAYS_INLINE static uint8_t decode_u8le(uint8_t *in) { +LM_ALWAYS_INLINE static uint8_t decode_u8le(uint8_t *in) { return in[0]; } -ALWAYS_INLINE static uint16_t decode_u16le(uint8_t *in) { +LM_ALWAYS_INLINE static uint16_t decode_u16le(uint8_t *in) { return (((uint16_t)(in[0])) << 0) | (((uint16_t)(in[1])) << 8) ; } -ALWAYS_INLINE static uint32_t decode_u32le(uint8_t *in) { +LM_ALWAYS_INLINE static uint32_t decode_u32le(uint8_t *in) { return (((uint32_t)(in[0])) << 0) | (((uint32_t)(in[1])) << 8) | (((uint32_t)(in[2])) << 16) | (((uint32_t)(in[3])) << 24) ; } -ALWAYS_INLINE static uint64_t decode_u64le(uint8_t *in) { +LM_ALWAYS_INLINE static uint64_t decode_u64le(uint8_t *in) { return (((uint64_t)(in[0])) << 0) | (((uint64_t)(in[1])) << 8) | (((uint64_t)(in[2])) << 16) @@ -152,20 +148,20 @@ static inline bool _is_valid_utf8(uint8_t *str, size_t len, bool forbid_nul) { /* marshal utilities **********************************************************/ -ALWAYS_INLINE static void encode_u8le(uint8_t in, uint8_t *out) { +LM_ALWAYS_INLINE static void encode_u8le(uint8_t in, uint8_t *out) { out[0] = in; } -ALWAYS_INLINE static void encode_u16le(uint16_t in, uint8_t *out) { +LM_ALWAYS_INLINE static void encode_u16le(uint16_t in, uint8_t *out) { out[0] = (uint8_t)((in >> 0) & 0xFF); out[1] = (uint8_t)((in >> 8) & 0xFF); } -ALWAYS_INLINE static void encode_u32le(uint32_t in, uint8_t *out) { +LM_ALWAYS_INLINE static void encode_u32le(uint32_t in, uint8_t *out) { out[0] = (uint8_t)((in >> 0) & 0xFF); out[1] = (uint8_t)((in >> 8) & 0xFF); out[2] = (uint8_t)((in >> 16) & 0xFF); out[3] = (uint8_t)((in >> 24) & 0xFF); } -ALWAYS_INLINE static void encode_u64le(uint64_t in, uint8_t *out) { +LM_ALWAYS_INLINE static void encode_u64le(uint64_t in, uint8_t *out) { out[0] = (uint8_t)((in >> 0) & 0xFF); out[1] = (uint8_t)((in >> 8) & 0xFF); out[2] = (uint8_t)((in >> 16) & 0xFF); diff --git a/lib9p/map.h b/lib9p/map.h index f42bb2c..b59c83d 100644 --- a/lib9p/map.h +++ b/lib9p/map.h @@ -25,10 +25,10 @@ #endif #ifndef MAP_KEY -#define MAP_KV(TNAME) CAT3(_,TNAME,_kv) -#define MAP_METHOD(TNAME, MNAME) CAT3(TNAME,_,MNAME) +#define MAP_KV(TNAME) LM_CAT3(_,TNAME,_kv) +#define MAP_METHOD(TNAME, MNAME) LM_CAT3(TNAME,_,MNAME) #define MAP_FOREACH(m, k, v) \ - for (size_t i = 0; i < ARRAY_LEN((m)->items); i++) \ + for (size_t i = 0; i < LM_ARRAY_LEN((m)->items); i++) \ if ( ({ k = (m)->items[i].key; v = &(m)->items[i].val; (m)->items[i].set; }) ) #endif @@ -58,7 +58,7 @@ struct NAME { static VAL_T *MAP_METHOD(NAME,load)(struct NAME *m, KEY_T k) { if (!m->len) return NULL; - for (size_t i = 0; i < ARRAY_LEN(m->items); i++) + for (size_t i = 0; i < LM_ARRAY_LEN(m->items); i++) if (m->items[i].set && m->items[i].key == k) return &(m->items[i].val); return NULL; @@ -74,9 +74,9 @@ static VAL_T *MAP_METHOD(NAME,store)(struct NAME *m, KEY_T k, VAL_T v) { *old = v; return old; } - if (m->len == ARRAY_LEN(m->items)) + if (m->len == LM_ARRAY_LEN(m->items)) return NULL; - for (size_t i = 0; i < ARRAY_LEN(m->items); i++) + for (size_t i = 0; i < LM_ARRAY_LEN(m->items); i++) if (!m->items[i].set) { m->len++; m->items[i].set = true; @@ -94,7 +94,7 @@ static VAL_T *MAP_METHOD(NAME,store)(struct NAME *m, KEY_T k, VAL_T v) { static bool MAP_METHOD(NAME,del)(struct NAME *m, KEY_T k) { if (!m->len) return NULL; - for (size_t i = 0; i < ARRAY_LEN(m->items); i++) + for (size_t i = 0; i < LM_ARRAY_LEN(m->items); i++) if (m->items[i].set && m->items[i].key == k) { m->items[i].set = false; m->len--; diff --git a/lib9p/srv.c b/lib9p/srv.c index 2fb2120..3535f9a 100644 --- a/lib9p/srv.c +++ b/lib9p/srv.c @@ -6,7 +6,6 @@ #include <alloca.h> #include <inttypes.h> /* for PRI* */ -#include <string.h> /* for strerror() */ #include <libcr/coroutine.h> #include <libcr_ipc/chan.h> @@ -14,6 +13,7 @@ #include <libcr_ipc/select.h> #include <libmisc/assert.h> #include <libmisc/vcall.h> +#include <libhw/generic/net.h> #define LOG_NAME 9P_SRV #include <libmisc/log.h> @@ -170,7 +170,7 @@ static void respond_error(struct _lib9p_srv_req *req) { req->net_bytes, decode_u32le(req->net_bytes)); cr_mutex_unlock(&sess->parent_conn->writelock); if (r < 0) - nonrespond_errorf("write: %s", strerror(-r)); + nonrespond_errorf("write: %s", net_strerror(-r)); } /* read coroutine *************************************************************/ @@ -182,7 +182,7 @@ static bool read_at_least(implements_net_stream_conn *fd, uint8_t *buf, size_t g while (*done < goal) { ssize_t r = VCALL(fd, read, &buf[*done], CONFIG_9P_MAX_MSG_SIZE - *done); if (r < 0) { - nonrespond_errorf("read: %s", strerror(-r)); + nonrespond_errorf("read: %s", net_strerror(-r)); return true; } else if (r == 0) { if (*done != 0) diff --git a/lib9p_util/CMakeLists.txt b/lib9p_util/CMakeLists.txt new file mode 100644 index 0000000..7a42c0c --- /dev/null +++ b/lib9p_util/CMakeLists.txt @@ -0,0 +1,13 @@ +# lib9p_util/CMakeLists.txt - TODO +# +# Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> +# SPDX-License-Identifier: AGPL-3.0-or-later + +add_library(lib9p_util INTERFACE) +target_include_directories(lib9p_util SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_sources(lib9p_util INTERFACE + static.c +) +target_link_libraries(lib9p_util INTERFACE + lib9p +) diff --git a/cmd/srv9p/static9p.h b/lib9p_util/include/util9p/static.h index 7a3d476..9ec03ef 100644 --- a/cmd/srv9p/static9p.h +++ b/lib9p_util/include/util9p/static.h @@ -1,11 +1,11 @@ -/* srv9p/static9p.h - Serve static files over 9P +/* util9p/static.h - Serve static files over 9P * * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ -#ifndef _SRV9P_STATIC9P_H_ -#define _SRV9P_STATIC9P_H_ +#ifndef _UTIL9P_STATIC_H_ +#define _UTIL9P_STATIC_H_ #include <lib9p/srv.h> @@ -23,25 +23,25 @@ typedef struct { char *name; lib9p_dm_t perm; uint32_t atime, mtime; -} _static_common; +} _util9p_static_common; -struct static_dir { - _static_common; +struct util9p_static_dir { + _util9p_static_common; /* NULL-terminated */ implements_lib9p_srv_file *members[]; }; -struct static_file { - _static_common; +struct util9p_static_file { + _util9p_static_common; char *data_start; /* must not be NULL */ char *data_end; /* may be NULL, in which case data_size is used */ size_t data_size; /* only used if .data_end==NULL */ }; -extern struct lib9p_srv_file_vtable static_dir_vtable; -extern struct lib9p_srv_file_vtable static_file_vtable; +extern struct lib9p_srv_file_vtable util9p_static_dir_vtable; +extern struct lib9p_srv_file_vtable util9p_static_file_vtable; -#endif /* _SRV9P_STATIC9P_H_ */ +#endif /* _UTIL9P_STATIC_H_ */ diff --git a/cmd/srv9p/static9p.c b/lib9p_util/static.c index b5b18e0..454b57e 100644 --- a/cmd/srv9p/static9p.c +++ b/lib9p_util/static.c @@ -1,55 +1,55 @@ -/* srv9p/static9p.c - Serve static files over 9P +/* lib9p_util/static.c - Serve static files over 9P * * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ #include <libmisc/assert.h> +#include <libmisc/macro.h> #include <libmisc/vcall.h> -#include "static9p.h" +#include <util9p/static.h> -#define UNUSED(name) #define p9_str(cstr) ((struct lib9p_s){ .len = strlen(cstr), .utf8 = cstr }) #define p9_nulstr ((struct lib9p_s){ .len = 0, .utf8 = NULL }) /* common *********************************************************************/ -static implements_lib9p_srv_file *static_common_clone(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { - _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); +static implements_lib9p_srv_file *util9p_static_common_clone(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + _util9p_static_common *self = VCALL_SELF(_util9p_static_common, implements_lib9p_srv_file, _self); assert(self); assert(ctx); return self; } -static void static_common_free(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { - _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); +static void util9p_static_common_free(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + _util9p_static_common *self = VCALL_SELF(_util9p_static_common, implements_lib9p_srv_file, _self); assert(self); assert(ctx); /* do nothing */ } -static uint32_t static_common_io(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, lib9p_o_t UNUSED(flags)) { - _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); +static uint32_t util9p_static_common_io(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, lib9p_o_t LM_UNUSED(flags)) { + _util9p_static_common *self = VCALL_SELF(_util9p_static_common, implements_lib9p_srv_file, _self); assert(self); assert(ctx); return 0; } -static void static_common_wstat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, - struct lib9p_stat UNUSED(new)) { - _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); +static void util9p_static_common_wstat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, + struct lib9p_stat LM_UNUSED(new)) { + _util9p_static_common *self = VCALL_SELF(_util9p_static_common, implements_lib9p_srv_file, _self); assert(self); assert(ctx); lib9p_error(&ctx->basectx, LINUX_EROFS, "read-only part of filesystem"); } -static void static_common_remove(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { - _static_common *self = VCALL_SELF(_static_common, implements_lib9p_srv_file, _self); +static void util9p_static_common_remove(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + _util9p_static_common *self = VCALL_SELF(_util9p_static_common, implements_lib9p_srv_file, _self); assert(self); assert(ctx); @@ -58,8 +58,8 @@ static void static_common_remove(implements_lib9p_srv_file *_self, struct lib9p_ /* dir ************************************************************************/ -static struct lib9p_stat static_dir_stat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { - struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); +static struct lib9p_stat util9p_static_dir_stat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + struct util9p_static_dir *self = VCALL_SELF(struct util9p_static_dir, implements_lib9p_srv_file, _self); assert(self); assert(ctx); @@ -86,9 +86,9 @@ static struct lib9p_stat static_dir_stat(implements_lib9p_srv_file *_self, struc }; } -static implements_lib9p_srv_file *static_dir_dopen(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, - char *childname) { - struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); +static implements_lib9p_srv_file *util9p_static_dir_dopen(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, + char *childname) { + struct util9p_static_dir *self = VCALL_SELF(struct util9p_static_dir, implements_lib9p_srv_file, _self); assert(self); assert(ctx); @@ -106,10 +106,10 @@ static implements_lib9p_srv_file *static_dir_dopen(implements_lib9p_srv_file *_s return NULL; } -static implements_lib9p_srv_file *static_dir_dcreate(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, - char *UNUSED(childname), - lib9p_dm_t UNUSED(perm), lib9p_o_t UNUSED(flags)) { - struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); +static implements_lib9p_srv_file *util9p_static_dir_dcreate(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, + char *LM_UNUSED(childname), + lib9p_dm_t LM_UNUSED(perm), lib9p_o_t LM_UNUSED(flags)) { + struct util9p_static_dir *self = VCALL_SELF(struct util9p_static_dir, implements_lib9p_srv_file, _self); assert(self); assert(ctx); @@ -117,11 +117,11 @@ static implements_lib9p_srv_file *static_dir_dcreate(implements_lib9p_srv_file * return NULL; } -static size_t static_dir_dread(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, - uint8_t *buf, - uint32_t byte_count, - size_t _obj_offset) { - struct static_dir *self = VCALL_SELF(struct static_dir, implements_lib9p_srv_file, _self); +static size_t util9p_static_dir_dread(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, + uint8_t *buf, + uint32_t byte_count, + size_t _obj_offset) { + struct util9p_static_dir *self = VCALL_SELF(struct util9p_static_dir, implements_lib9p_srv_file, _self); assert(self); assert(ctx); @@ -147,24 +147,24 @@ static size_t static_dir_dread(implements_lib9p_srv_file *_self, struct lib9p_sr return obj_offset - _obj_offset; } -struct lib9p_srv_file_vtable static_dir_vtable = { - .clone = static_common_clone, - .free = static_common_free, +struct lib9p_srv_file_vtable util9p_static_dir_vtable = { + .clone = util9p_static_common_clone, + .free = util9p_static_common_free, - .io = static_common_io, - .stat = static_dir_stat, - .wstat = static_common_wstat, - .remove = static_common_remove, + .io = util9p_static_common_io, + .stat = util9p_static_dir_stat, + .wstat = util9p_static_common_wstat, + .remove = util9p_static_common_remove, - .dopen = static_dir_dopen, - .dcreate = static_dir_dcreate, + .dopen = util9p_static_dir_dopen, + .dcreate = util9p_static_dir_dcreate, - .dread = static_dir_dread, + .dread = util9p_static_dir_dread, }; /* file ***********************************************************************/ -static inline size_t static_file_size(struct static_file *file) { +static inline size_t util9p_static_file_size(struct util9p_static_file *file) { assert(file); #if __unix__ @@ -175,8 +175,8 @@ static inline size_t static_file_size(struct static_file *file) { return (size_t)((uintptr_t)file->data_end - (uintptr_t)file->data_start); } -static struct lib9p_stat static_file_stat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { - struct static_file *self = VCALL_SELF(struct static_file, implements_lib9p_srv_file, _self); +static struct lib9p_stat util9p_static_file_stat(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx) { + struct util9p_static_file *self = VCALL_SELF(struct util9p_static_file, implements_lib9p_srv_file, _self); assert(self); assert(ctx); @@ -191,7 +191,7 @@ static struct lib9p_stat static_file_stat(implements_lib9p_srv_file *_self, stru .file_mode = self->perm & 0444, .file_atime = self->atime, .file_mtime = self->mtime, - .file_size = (uint64_t)static_file_size(self), + .file_size = (uint64_t)util9p_static_file_size(self), .file_name = p9_str(self->name), .file_owner_uid = p9_str(self->u_name), .file_owner_gid = p9_str(self->g_name), @@ -203,15 +203,15 @@ static struct lib9p_stat static_file_stat(implements_lib9p_srv_file *_self, stru }; } -static uint32_t static_file_pread(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, - void *buf, - uint32_t byte_count, - uint64_t byte_offset) { - struct static_file *self = VCALL_SELF(struct static_file, implements_lib9p_srv_file, _self); +static uint32_t util9p_static_file_pread(implements_lib9p_srv_file *_self, struct lib9p_srv_ctx *ctx, + void *buf, + uint32_t byte_count, + uint64_t byte_offset) { + struct util9p_static_file *self = VCALL_SELF(struct util9p_static_file, implements_lib9p_srv_file, _self); assert(self); assert(ctx); - size_t data_size = static_file_size(self); + size_t data_size = util9p_static_file_size(self); if (byte_offset > (uint64_t)data_size) { lib9p_error(&ctx->basectx, @@ -227,15 +227,15 @@ static uint32_t static_file_pread(implements_lib9p_srv_file *_self, struct lib9p return (uint32_t)(end_off-beg_off); } -struct lib9p_srv_file_vtable static_file_vtable = { - .clone = static_common_clone, - .free = static_common_free, +struct lib9p_srv_file_vtable util9p_static_file_vtable = { + .clone = util9p_static_common_clone, + .free = util9p_static_common_free, - .io = static_common_io, - .stat = static_file_stat, - .wstat = static_common_wstat, - .remove = static_common_remove, + .io = util9p_static_common_io, + .stat = util9p_static_file_stat, + .wstat = util9p_static_common_wstat, + .remove = util9p_static_common_remove, - .pread = static_file_pread, + .pread = util9p_static_file_pread, .pwrite = NULL, }; diff --git a/libcr/coroutine.c b/libcr/coroutine.c index aa23d58..7278225 100644 --- a/libcr/coroutine.c +++ b/libcr/coroutine.c @@ -9,6 +9,7 @@ #include <string.h> /* for strncpy(), memset() */ #include <libmisc/assert.h> +#include <libmisc/macro.h> #define LOG_NAME COROUTINE #include <libmisc/log.h> @@ -128,18 +129,6 @@ * no longer exists. */ -/* preprocessor macros ********************************************************/ - -/** Return `n` rounded up to the nearest multiple of `d` */ -#define ROUND_UP(n, d) ( ( ((n)+(d)-1) / (d) ) * (d) ) -#define ARRAY_LEN(arr) (sizeof(arr)/sizeof((arr)[0])) -#define NEXT_POWER_OF_2(x) ((1ULL)<<((sizeof(unsigned long long)*8)-__builtin_clzll(x))) - -#define UNUSED(name) - -#define ALWAYS_INLINE [[gnu::always_inline]] inline -#define NEVER_INLINE [[gnu::noinline]] - /* platform support ***********************************************************/ /* As part of sbc-harness, this only really needs to support ARM-32, but being @@ -211,7 +200,7 @@ sigprocmask(SIG_SETMASK, &zero, NULL); } #if CONFIG_COROUTINE_GDB - static void _cr_gdb_intrhandler(int UNUSED(sig)) {} + static void _cr_gdb_intrhandler(int LM_UNUSED(sig)) {} #endif static void cr_plat_init(void) { #if CONFIG_COROUTINE_GDB @@ -231,7 +220,7 @@ ); return isr_number != 0; } - ALWAYS_INLINE static bool _cr_plat_are_interrupts_enabled(void) { + LM_ALWAYS_INLINE static bool _cr_plat_are_interrupts_enabled(void) { assert(!cr_plat_is_in_intrhandler()); uint32_t primask; asm volatile ("mrs %0, PRIMASK" @@ -240,7 +229,7 @@ return primask == 0; } - ALWAYS_INLINE static void cr_plat_wait_for_interrupt(void) { + LM_ALWAYS_INLINE static void cr_plat_wait_for_interrupt(void) { assert(!cr_plat_is_in_intrhandler()); assert(!_cr_plat_are_interrupts_enabled()); asm volatile ("wfi\n" @@ -271,7 +260,7 @@ #define CR_PLAT_STACK_GROWS_DOWNWARD 1 #if CONFIG_COROUTINE_MEASURE_STACK - ALWAYS_INLINE static uintptr_t cr_plat_get_sp(void) { + LM_ALWAYS_INLINE static uintptr_t cr_plat_get_sp(void) { uintptr_t sp; asm volatile ("mov %0, sp":"=r"(sp)); return sp; @@ -303,7 +292,7 @@ #define CR_PLAT_STACK_GROWS_DOWNWARD 1 #if CONFIG_COROUTINE_MEASURE_STACK - ALWAYS_INLINE static uintptr_t cr_plat_get_sp(void) { + LM_ALWAYS_INLINE static uintptr_t cr_plat_get_sp(void) { uintptr_t sp; asm volatile ("movq %%rsp, %0":"=r"(sp)); return sp; @@ -419,10 +408,10 @@ static const uint8_t stack_pattern[] = { }; #endif #if CONFIG_COROUTINE_PROTECT_STACK - #define STACK_GUARD_SIZE \ - ROUND_UP(sizeof(stack_pattern), CR_PLAT_STACK_ALIGNMENT) + #define CR_STACK_GUARD_SIZE \ + LM_ROUND_UP(sizeof(stack_pattern), CR_PLAT_STACK_ALIGNMENT) #else - #define STACK_GUARD_SIZE 0 + #define CR_STACK_GUARD_SIZE 0 #endif /* global variables ***********************************************************/ @@ -463,7 +452,7 @@ static struct { * compiler will optimize `%array_len` to &(array_len-1)`, (b) * we don't have to worry about funny wrap-around behavior * when head or tail overflow. */ - cid_t buf[NEXT_POWER_OF_2(CONFIG_COROUTINE_NUM)]; + cid_t buf[LM_NEXT_POWER_OF_2(CONFIG_COROUTINE_NUM)]; } coroutine_ringbuf = {0}; static cid_t coroutine_running = 0; static size_t coroutine_cnt = 0; @@ -471,28 +460,28 @@ static size_t coroutine_cnt = 0; /* utility functions **********************************************************/ static inline const char* coroutine_state_str(enum coroutine_state state) { - assert(state < ARRAY_LEN(coroutine_state_strs)); + assert(state < LM_ARRAY_LEN(coroutine_state_strs)); return coroutine_state_strs[state]; } static inline void coroutine_ringbuf_push(cid_t val) { - coroutine_ringbuf.buf[coroutine_ringbuf.head++ % ARRAY_LEN(coroutine_ringbuf.buf)] = val; - assert((coroutine_ringbuf.head % ARRAY_LEN(coroutine_ringbuf.buf)) != - (coroutine_ringbuf.tail % ARRAY_LEN(coroutine_ringbuf.buf))); + coroutine_ringbuf.buf[coroutine_ringbuf.head++ % LM_ARRAY_LEN(coroutine_ringbuf.buf)] = val; + assert((coroutine_ringbuf.head % LM_ARRAY_LEN(coroutine_ringbuf.buf)) != + (coroutine_ringbuf.tail % LM_ARRAY_LEN(coroutine_ringbuf.buf))); } static inline cid_t coroutine_ringbuf_pop(void) { if (coroutine_ringbuf.tail == coroutine_ringbuf.head) return 0; - return coroutine_ringbuf.buf[coroutine_ringbuf.tail++ % ARRAY_LEN(coroutine_ringbuf.buf)]; + return coroutine_ringbuf.buf[coroutine_ringbuf.tail++ % LM_ARRAY_LEN(coroutine_ringbuf.buf)]; } #if CONFIG_COROUTINE_GDB -NEVER_INLINE void cr_gdb_breakpoint(void) { +LM_NEVER_INLINE void cr_gdb_breakpoint(void) { /* Prevent the call from being optimized away. */ asm (""); } -NEVER_INLINE void cr_gdb_readjmp(cr_plat_jmp_buf *env) { +LM_NEVER_INLINE void cr_gdb_readjmp(cr_plat_jmp_buf *env) { if (!cr_plat_setjmp(&coroutine_gdb_env)) cr_plat_longjmp(env, 2); } @@ -516,7 +505,7 @@ static inline void assert_cid(cid_t cid) { assert(coroutine_table[cid-1].stack_size); uint8_t *stack = coroutine_table[cid-1].stack; assert(stack); - for (size_t i = 0; i < STACK_GUARD_SIZE; i++) { + for (size_t i = 0; i < CR_STACK_GUARD_SIZE; i++) { size_t j = coroutine_table[cid-1].stack_size - (i+1); assert(stack[i] == stack_pattern[i%sizeof(stack_pattern)]); assert(stack[j] == stack_pattern[j%sizeof(stack_pattern)]); @@ -583,8 +572,8 @@ cid_t coroutine_add_with_stack_size(size_t stack_size, #endif #if CONFIG_COROUTINE_VALGRIND coroutine_table[child-1].stack_id = VALGRIND_STACK_REGISTER( - coroutine_table[child-1].stack + STACK_GUARD_SIZE, - coroutine_table[child-1].stack + stack_size - STACK_GUARD_SIZE); + coroutine_table[child-1].stack + CR_STACK_GUARD_SIZE, + coroutine_table[child-1].stack + stack_size - CR_STACK_GUARD_SIZE); #endif coroutine_running = child; @@ -594,9 +583,9 @@ cid_t coroutine_add_with_stack_size(size_t stack_size, void *stack_base = coroutine_table[child-1].stack #if CR_PLAT_STACK_GROWS_DOWNWARD + stack_size - - STACK_GUARD_SIZE + - CR_STACK_GUARD_SIZE #else - + STACK_GUARD_SIZE + + CR_STACK_GUARD_SIZE #endif ; debugf("...stack =%p", coroutine_table[child-1].stack); @@ -782,7 +771,7 @@ void cr_cid_info(cid_t cid, struct cr_cid_info *ret) { assert(ret); /* stack_cap */ - ret->stack_cap = coroutine_table[cid-1].stack_size - 2*STACK_GUARD_SIZE; + ret->stack_cap = coroutine_table[cid-1].stack_size - 2*CR_STACK_GUARD_SIZE; /* stack_max */ ret->stack_max = ret->stack_cap; @@ -790,9 +779,9 @@ void cr_cid_info(cid_t cid, struct cr_cid_info *ret) { for (;;) { size_t i = #if CR_PLAT_STACK_GROWS_DOWNWARD - STACK_GUARD_SIZE + ret->stack_cap - ret->stack_max + CR_STACK_GUARD_SIZE + ret->stack_cap - ret->stack_max #else - ret->stack_max - 1 - STACK_GUARD_SIZE + ret->stack_max - 1 - CR_STACK_GUARD_SIZE #endif ; if (ret->stack_max == 0 || @@ -812,9 +801,9 @@ void cr_cid_info(cid_t cid, struct cr_cid_info *ret) { assert(sp); uintptr_t sb = (uintptr_t)coroutine_table[cid-1].stack; #if CR_PLAT_STACK_GROWS_DOWNWARD - ret->stack_cur = (sb - STACK_GUARD_SIZE) - sp; + ret->stack_cur = (sb - CR_STACK_GUARD_SIZE) - sp; #else - ret->stack_cur = sp - (sb + STACK_GUARD_SIZE); + ret->stack_cur = sp - (sb + CR_STACK_GUARD_SIZE); #endif } diff --git a/libhw/host_alarmclock.c b/libhw/host_alarmclock.c index 8b9bdcf..5f7e494 100644 --- a/libhw/host_alarmclock.c +++ b/libhw/host_alarmclock.c @@ -54,8 +54,6 @@ implements_alarmclock *bootclock = &clock_monotonic; /* Main implementation ********************************************************/ -#define UNUSED(name) - static uint64_t hostclock_get_time_ns(implements_alarmclock *_alarmclock) { struct hostclock *alarmclock = VCALL_SELF(struct hostclock, implements_alarmclock, _alarmclock); @@ -69,7 +67,7 @@ static uint64_t hostclock_get_time_ns(implements_alarmclock *_alarmclock) { return ns_from_host_ns_time(ts); } -static void hostclock_handle_sig_alarm(int UNUSED(sig), siginfo_t *info, void *UNUSED(ucontext)) { +static void hostclock_handle_sig_alarm(int LM_UNUSED(sig), siginfo_t *info, void *LM_UNUSED(ucontext)) { struct hostclock *alarmclock = info->si_value.sival_ptr; assert(alarmclock); diff --git a/libhw/host_net.c b/libhw/host_net.c index 2ba8b23..917e764 100644 --- a/libhw/host_net.c +++ b/libhw/host_net.c @@ -20,6 +20,7 @@ #include <libcr/coroutine.h> #include <libmisc/assert.h> +#include <libmisc/macro.h> #include <libmisc/vcall.h> #include <libhw/generic/alarmclock.h> @@ -31,11 +32,9 @@ /* common *********************************************************************/ -#define UNUSED(name) - static int hostnet_sig_io = 0; -static void hostnet_handle_sig_io(int UNUSED(sig), siginfo_t *info, void *UNUSED(ucontext)) { +static void hostnet_handle_sig_io(int LM_UNUSED(sig), siginfo_t *info, void *LM_UNUSED(ucontext)) { cr_unpause_from_intrhandler((cid_t)info->si_value.sival_int); } diff --git a/libhw/rp2040_hwtimer.c b/libhw/rp2040_hwtimer.c index 4499642..c8c281e 100644 --- a/libhw/rp2040_hwtimer.c +++ b/libhw/rp2040_hwtimer.c @@ -68,7 +68,7 @@ static uint64_t rp2040_hwtimer_get_time_ns(implements_alarmclock *) { return timer_time_us_64(timer_hw) * (NS_PER_S/US_PER_S); } -#define NS_TO_US_ROUNDUP(x) ( ( (x) + (NS_PER_S/US_PER_S)-1) / (NS_PER_S/US_PER_S) ) +#define NS_TO_US_ROUNDUP(x) LM_CEILDIV(x, NS_PER_S/US_PER_S) static void rp2040_hwtimer_intrhandler(void) { uint irq_num = __get_current_exception() - VTABLE_FIRST_IRQ; diff --git a/libhw/w5500.c b/libhw/w5500.c index f36b9cf..cebcf8e 100644 --- a/libhw/w5500.c +++ b/libhw/w5500.c @@ -105,9 +105,6 @@ /* C language *****************************************************************/ -#define UNUSED(name) -#define ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0])) - static const char *w5500_state_str(uint8_t state) { switch (state) { case STATE_CLOSED: return "STATE_CLOSED"; @@ -328,9 +325,9 @@ static inline void w5500_socket_close(struct _w5500_socket *socket) { static struct w5500 *w5500_chips[CONFIG_W5500_NUM] = {0}; -static void w5500_intrhandler(uint gpio, uint32_t UNUSED(event_mask)) { +static void w5500_intrhandler(uint gpio, uint32_t LM_UNUSED(event_mask)) { debugf("w5500_intrhandler(): interrupt on pin %u", gpio); - for (size_t i = 0; i < ARRAY_LEN(w5500_chips); i++) + for (size_t i = 0; i < LM_ARRAY_LEN(w5500_chips); i++) if (w5500_chips[i] && w5500_chips[i]->pin_intr == gpio) cr_sema_signal_from_intrhandler(&w5500_chips[i]->intr); } @@ -374,7 +371,7 @@ void _w5500_init(struct w5500 *chip, /* Finally, wire in the interrupt handler. */ bool saved = cr_save_and_disable_interrupts(); - for (size_t i = 0; i < ARRAY_LEN(w5500_chips); i++) { + for (size_t i = 0; i < LM_ARRAY_LEN(w5500_chips); i++) { if (w5500_chips[i] == NULL) { w5500_chips[i] = chip; break; diff --git a/libhw_generic/CMakeLists.txt b/libhw_generic/CMakeLists.txt index 9c88937..0356770 100644 --- a/libhw_generic/CMakeLists.txt +++ b/libhw_generic/CMakeLists.txt @@ -12,4 +12,5 @@ target_link_libraries(libhw_generic INTERFACE target_sources(libhw_generic INTERFACE alarmclock.c + net.c ) diff --git a/libhw_generic/include/libhw/generic/net.h b/libhw_generic/include/libhw/generic/net.h index a016d51..0f9872e 100644 --- a/libhw_generic/include/libhw/generic/net.h +++ b/libhw_generic/include/libhw/generic/net.h @@ -23,6 +23,8 @@ #define NET_ECLOSED 6 #define NET_EMSGSIZE 7 +const char *net_strerror(int net_errno); + /* Address types **************************************************************/ struct net_ip4_addr { diff --git a/libhw_generic/net.c b/libhw_generic/net.c new file mode 100644 index 0000000..e2785ae --- /dev/null +++ b/libhw_generic/net.c @@ -0,0 +1,31 @@ +/* libhw_generic/net.c - Device-independent <libhw/generic/net.h> utilities + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libmisc/assert.h> + +#include <libhw/generic/net.h> + +#define NET_EOTHER 1 +#define NET_EARP_TIMEOUT 2 +#define NET_EACK_TIMEOUT 3 +#define NET_ERECV_TIMEOUT 4 +#define NET_ETHREAD 5 +#define NET_ECLOSED 6 +#define NET_EMSGSIZE 7 + +const char *net_strerror(int net_errno) { + switch (net_errno) { + case NET_EOTHER: return "unknown error"; + case NET_EARP_TIMEOUT: return "ARP timeout"; + case NET_EACK_TIMEOUT: return "TCP ACK timeout"; + case NET_ERECV_TIMEOUT: return "receive timeout"; + case NET_ETHREAD: return "thread error"; + case NET_ECLOSED: return "already closed"; + case NET_EMSGSIZE: return "message too long"; + default: + assert_notreached("invalid net_errno"); + } +} diff --git a/libmisc/CMakeLists.txt b/libmisc/CMakeLists.txt index 02b19d5..83e91fe 100644 --- a/libmisc/CMakeLists.txt +++ b/libmisc/CMakeLists.txt @@ -15,6 +15,7 @@ add_lib_test(libmisc test_assert) add_lib_test(libmisc test_endian) add_lib_test(libmisc test_hash) add_lib_test(libmisc test_log) +add_lib_test(libmisc test_macro) add_lib_test(libmisc test_private) add_lib_test(libmisc test_rand) add_lib_test(libmisc test_vcall) diff --git a/libmisc/include/libmisc/log.h b/libmisc/include/libmisc/log.h index b4f5461..8c6d6be 100644 --- a/libmisc/include/libmisc/log.h +++ b/libmisc/include/libmisc/log.h @@ -9,6 +9,8 @@ #include <stdint.h> /* for uint8_t */ +#include <libmisc/macro.h> + #ifndef LOG_NAME #error "each compilation unit that includes <libmisc/log.h> must define LOG_NAME" #endif @@ -18,17 +20,13 @@ #else #define _LOG_NDEBUG 0 #endif -#define __LOG_STR(x) #x -#define _LOG_STR(x) __LOG_STR(x) -#define __LOG_CAT3(a, b, c) a ## b ## c -#define _LOG_CAT3(a, b, c) __LOG_CAT3(a, b, c) [[format(printf, 1, 2)]] int _log_printf(const char *format, ...); -#define n_errorf(nam, fmt, ...) do { _log_printf("error: " _LOG_STR(nam) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) -#define n_infof(nam, fmt, ...) do { _log_printf("info : " _LOG_STR(nam) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) -#define n_debugf(nam, fmt, ...) do { if (_LOG_CAT3(CONFIG_, nam, _DEBUG) && !_LOG_NDEBUG) \ - _log_printf("debug: " _LOG_STR(nam) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) +#define n_errorf(nam, fmt, ...) do { _log_printf("error: " LM_STR_(nam) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) +#define n_infof(nam, fmt, ...) do { _log_printf("info : " LM_STR_(nam) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) +#define n_debugf(nam, fmt, ...) do { if (LM_CAT3_(CONFIG_, nam, _DEBUG) && !_LOG_NDEBUG) \ + _log_printf("debug: " LM_STR_(nam) ": " fmt "\n" __VA_OPT__(,) __VA_ARGS__); } while (0) #define errorf(fmt, ...) n_errorf(LOG_NAME, fmt, __VA_ARGS__) #define infof(fmt, ...) n_infof(LOG_NAME, fmt, __VA_ARGS__) diff --git a/libmisc/include/libmisc/macro.h b/libmisc/include/libmisc/macro.h new file mode 100644 index 0000000..9bb068f --- /dev/null +++ b/libmisc/include/libmisc/macro.h @@ -0,0 +1,55 @@ +/* libmisc/macro.h - Useful C preprocessor macros + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBMISC_MACRO_H_ +#define _LIBMISC_MACRO_H_ + +/* for function definitions */ + +#define LM_UNUSED(argname) +#define LM_ALWAYS_INLINE [[gnu::always_inline]] inline +#define LM_NEVER_INLINE [[gnu::noinline]] +#define LM_FLATTEN [[gnu::flatten]] + +/* numeric */ + +#define LM_ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0])) +#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) ) +#define LM_ROUND_UP(n, d) ( LM_CEILDIV(n, d) * (d) ) /** Return `n` rounded up to the nearest multiple of `d` */ +#define LM_NEXT_POWER_OF_2(x) ((1ULL)<<((sizeof(unsigned long long)*8)-__builtin_clzll(x))) + +/* strings */ + +#define LM_STR(x) #x +#define LM_STR_(x) LM_STR(x) + +/* token pasting */ + +#define LM_CAT2(a, b) a ## b +#define LM_CAT3(a, b, c) a ## b ## c + +#define LM_CAT2_(a, b) LM_CAT2(a, b) +#define LM_CAT3_(a, b, c) LM_CAT3(a, b, c) + +/* macro arguments */ + +#define LM_SECOND(a, b, ...) b +#define LM_EAT(...) +#define LM_EXPAND(...) __VA_ARGS__ + +/* conditionals */ + +#define LM_T xxTxx +#define LM_F xxFxx + +#define LM_SENTINEL() bogus, LM_T /* a magic sentinel value */ +#define LM_IS_SENTINEL(...) LM_SECOND(__VA_ARGS__, LM_F) + +#define LM_IF(cond) LM_CAT2(_LM_IF__, cond) /* LM_IF(cond)(then)(else) */ +#define _LM_IF__xxTxx(...) __VA_ARGS__ LM_EAT +#define _LM_IF__xxFxx(...) LM_EXPAND + +#endif /* _LIBMISC_MACRO_H_ */ diff --git a/libmisc/include/libmisc/private.h b/libmisc/include/libmisc/private.h index bc5e7ad..1db7915 100644 --- a/libmisc/include/libmisc/private.h +++ b/libmisc/include/libmisc/private.h @@ -7,31 +7,10 @@ #ifndef _LIBMISC_PRIVATE_H_ #define _LIBMISC_PRIVATE_H_ -/* primitive utilities */ +#include <libmisc/macro.h> -#define _SECOND(a, b, ...) b - -#define _CAT(a, b) a ## b -#define _CAT2(a, b) _CAT(a, b) -#define _EAT(...) -#define _EXPAND(...) __VA_ARGS__ - -/* conditionals */ - -#define _T xxTxx -#define _F xxFxx - -#define _SENTINEL() bogus, _T /* a magic sentinel value */ -#define _IS_SENTINEL(...) _SECOND(__VA_ARGS__, _F) - -#define _IF(cond) _CAT(_IF__, cond) /* _IF(cond)(then)(else) */ -#define _IF__xxTxx(...) __VA_ARGS__ _EAT -#define _IF__xxFxx(...) _EXPAND - -/* high-level functionality */ - -#define YES _SENTINEL() -#define BEGIN_PRIVATE(name) _IF(_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(struct {) -#define END_PRIVATE(name) _IF(_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(} _CAT2(_HIDDEN_, __COUNTER__);) +#define YES LM_SENTINEL() +#define BEGIN_PRIVATE(name) LM_IF(LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(struct {) +#define END_PRIVATE(name) LM_IF(LM_IS_SENTINEL(IMPLEMENTATION_FOR_##name))()(} LM_CAT2_(_HIDDEN_, __COUNTER__);) #endif /* _LIBMISC_PRIVATE_H_ */ diff --git a/libmisc/tests/test_assert.c b/libmisc/tests/test_assert.c index 5b28561..189f6de 100644 --- a/libmisc/tests/test_assert.c +++ b/libmisc/tests/test_assert.c @@ -9,12 +9,11 @@ #include <string.h> #include <stdlib.h> +#include <libmisc/macro.h> #include <libmisc/assert.h> #include "test.h" -#define UNUSED(name) - /* Intercept failures and logging *********************************************/ bool global_failed; @@ -64,23 +63,20 @@ int vprintf(const char *format, va_list ap) { } \ } while (0) -#define _STR(x) #x -#define STR(x) _STR(x) - /* Actual tests ***************************************************************/ static_assert(sizeof(char) == 1); int main() { test_should_succeed(assert(true)); - test_should_fail(assert(false), "error: ASSERT: "__FILE__":"STR(__LINE__)":main(): assertion \"false\" failed\n"); + test_should_fail(assert(false), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed\n"); test_should_succeed(assert_msg(true, "foo")); - test_should_fail(assert_msg(false, "foo"), "error: ASSERT: "__FILE__":"STR(__LINE__)":main(): assertion \"false\" failed: foo\n"); + test_should_fail(assert_msg(false, "foo"), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed: foo\n"); test_should_succeed(assert_msg(true, NULL)); - test_should_fail(assert_msg(false, NULL), "error: ASSERT: "__FILE__":"STR(__LINE__)":main(): assertion \"false\" failed\n"); + test_should_fail(assert_msg(false, NULL), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed\n"); - test_should_fail(assert_notreached("xxx"), "error: ASSERT: "__FILE__":"STR(__LINE__)":main(): assertion \"notreached\" failed: xxx\n"); + test_should_fail(assert_notreached("xxx"), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"notreached\" failed: xxx\n"); if (global_log) { free(global_log); diff --git a/libmisc/tests/test_macro.c b/libmisc/tests/test_macro.c new file mode 100644 index 0000000..7cbf9d3 --- /dev/null +++ b/libmisc/tests/test_macro.c @@ -0,0 +1,32 @@ +/* libmisc/tests/test_macro.c - Tests for <libmisc/macro.h> + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <libmisc/macro.h> + +#include "test.h" + +int main() { + /* valid down to 0. */ + test_assert(LM_NEXT_POWER_OF_2(0) == 1); + test_assert(LM_NEXT_POWER_OF_2(1) == 2); + test_assert(LM_NEXT_POWER_OF_2(2) == 4); + test_assert(LM_NEXT_POWER_OF_2(3) == 4); + test_assert(LM_NEXT_POWER_OF_2(4) == 8); + test_assert(LM_NEXT_POWER_OF_2(5) == 8); + test_assert(LM_NEXT_POWER_OF_2(6) == 8); + test_assert(LM_NEXT_POWER_OF_2(7) == 8); + test_assert(LM_NEXT_POWER_OF_2(8) == 16); + /* ... */ + test_assert(LM_NEXT_POWER_OF_2(16) == 32); + /* ... */ + test_assert(LM_NEXT_POWER_OF_2(0x7000000000000000) == 0x8000000000000000); + /* ... */ + test_assert(LM_NEXT_POWER_OF_2(0x8000000000000000-1) == 0x8000000000000000); + /* Valid up to 0x8000000000000000-1 = (1<<63)-1 */ + test_assert(LM_NEXT_POWER_OF_2(0x8000000000000000) == 0); /* :( */ + + return 0; +} @@ -50,7 +50,7 @@ Which file to include: | `blksize_t` | `<sys/types.h>` | signed | | `pid_t` | `<sys/types.h>` | signed | | `ssize_t` | `<sys/types.h>` | signed | -| `SSIZE_MAX` | `<limits.h>` | | +| `SSIZE_MAX` | `<limits.h>` | not in newlib | | `suseconds_t` | `<sys/types.h>` | signed | | `clock_t` | `<sys/types.h>` | could be float | | `time_t` | `<sys/types.h>` | signed | |