diff --git a/stand/common/metadata.c b/stand/common/metadata.c --- a/stand/common/metadata.c +++ b/stand/common/metadata.c @@ -44,6 +44,7 @@ #include #include "bootstrap.h" +#include "modinfo.h" #ifdef LOADER_GELI_SUPPORT #include "geliboot.h" @@ -92,68 +93,8 @@ return(addr); } -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ - static int align; - #define MOD_ALIGN(l) roundup(l, align) -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c) \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += MOD_ALIGN(strlen(s) + 1); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += MOD_ALIGN(sizeof(s)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c);\ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += MOD_ALIGN(mm->md_size); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} static vm_offset_t md_copymodules(vm_offset_t addr, int kern64) diff --git a/stand/common/modinfo.h b/stand/common/modinfo.h new file mode 100644 --- /dev/null +++ b/stand/common/modinfo.h @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 2022, Netflix, Inc. + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef COMMON_MODINFO_H +#define COMMON_MODINFO_H + +/* + * Copy module-related data into the load area, where it can be + * used as a directory for loaded modules. + * + * Module data is presented in a self-describing format. Each datum + * is preceded by a 32-bit identifier and a 32-bit size field. + * + * Currently, the following data are saved: + * + * MOD_NAME (variable) module name (string) + * MOD_TYPE (variable) module type (string) + * MOD_ARGS (variable) module parameters (string) + * MOD_ADDR sizeof(vm_offset_t) module load address + * MOD_SIZE sizeof(size_t) module size + * MOD_METADATA (variable) type-specific metadata + * + * Clients are required to define a MOD_ALIGN(l) macro which rounds the passed + * in length to the required alignment for the kernel being booted. + */ + +#define COPY32(v, a, c) { \ + uint32_t x = (v); \ + if (c) \ + archsw.arch_copyin(&x, a, sizeof(x)); \ + a += sizeof(x); \ +} + +#define MOD_STR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(strlen(s) + 1, a, c) \ + if (c) \ + archsw.arch_copyin(s, a, strlen(s) + 1);\ + a += MOD_ALIGN(strlen(s) + 1); \ +} + +#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) +#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) +#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) + +#define MOD_VAR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(sizeof(s), a, c); \ + if (c) \ + archsw.arch_copyin(&s, a, sizeof(s)); \ + a += MOD_ALIGN(sizeof(s)); \ +} + +#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) +#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) + +#define MOD_METADATA(a, mm, c) { \ + COPY32(MODINFO_METADATA | mm->md_type, a, c);\ + COPY32(mm->md_size, a, c); \ + if (c) \ + archsw.arch_copyin(mm->md_data, a, mm->md_size);\ + a += MOD_ALIGN(mm->md_size); \ +} + +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ +} + +#endif /* COMMON_MODINFO_H */ diff --git a/stand/efi/loader/bootinfo.c b/stand/efi/loader/bootinfo.c --- a/stand/efi/loader/bootinfo.c +++ b/stand/efi/loader/bootinfo.c @@ -44,6 +44,7 @@ #include #include "bootstrap.h" +#include "modinfo.h" #include "loader_efi.h" #if defined(__amd64__) @@ -60,6 +61,11 @@ #include "geliboot.h" #endif +/* + * Align to a pointer / long + */ +#define MOD_ALIGN(l) roundup(l, sizeof(u_long)) + int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, bool exit_bs); @@ -164,66 +170,6 @@ return(last); } -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define MOD_ALIGN(l) roundup(l, sizeof(u_long)) -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1); \ - a += MOD_ALIGN(strlen(s) + 1); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += MOD_ALIGN(sizeof(s)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size); \ - a += MOD_ALIGN(mm->md_size); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} - static vm_offset_t bi_copymodules(vm_offset_t addr) { diff --git a/stand/i386/libi386/bootinfo32.c b/stand/i386/libi386/bootinfo32.c --- a/stand/i386/libi386/bootinfo32.c +++ b/stand/i386/libi386/bootinfo32.c @@ -34,6 +34,7 @@ #include #include #include "bootstrap.h" +#include "modinfo.h" #include "libi386.h" #include "btxv86.h" @@ -44,64 +45,10 @@ static struct bootinfo bi; /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata + * We have 4 byte alignment for 32-bit targets. This code is compiled as 32-bit + * code... */ #define MOD_ALIGN(l) roundup(l, sizeof(u_long)) -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1); \ - a += MOD_ALIGN(strlen(s) + 1); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += MOD_ALIGN(sizeof(s)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size); \ - a += MOD_ALIGN(mm->md_size); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} static vm_offset_t bi_copymodules32(vm_offset_t addr) diff --git a/stand/i386/libi386/bootinfo64.c b/stand/i386/libi386/bootinfo64.c --- a/stand/i386/libi386/bootinfo64.c +++ b/stand/i386/libi386/bootinfo64.c @@ -37,6 +37,7 @@ #include #include #include "bootstrap.h" +#include "modinfo.h" #include "libi386.h" #include "btxv86.h" @@ -45,64 +46,10 @@ #endif /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata + * We have 8 byte alignment for 64-bit targets. This code is compiled as 64-bit + * code... */ #define MOD_ALIGN(l) roundup(l, sizeof(uint64_t)) -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1); \ - a += MOD_ALIGN(strlen(s) + 1); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += MOD_ALIGN(sizeof(s)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size); \ - a += MOD_ALIGN(mm->md_size); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} static vm_offset_t bi_copymodules64(vm_offset_t addr) diff --git a/stand/userboot/userboot/bootinfo32.c b/stand/userboot/userboot/bootinfo32.c --- a/stand/userboot/userboot/bootinfo32.c +++ b/stand/userboot/userboot/bootinfo32.c @@ -34,6 +34,7 @@ #include #include "bootstrap.h" +#include "modinfo.h" #include "libuserboot.h" #ifdef LOADER_GELI_SUPPORT @@ -43,64 +44,9 @@ static struct bootinfo bi; /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata + * We have 4 byte alignment for 32-bit targets. */ #define MOD_ALIGN(l) roundup(l, sizeof(uint32_t)) -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += MOD_ALIGN(strlen(s) + 1); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += MOD_ALIGN(sizeof(s)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += MOD_ALIGN(mm->md_size); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} static vm_offset_t bi_copymodules32(vm_offset_t addr) diff --git a/stand/userboot/userboot/bootinfo64.c b/stand/userboot/userboot/bootinfo64.c --- a/stand/userboot/userboot/bootinfo64.c +++ b/stand/userboot/userboot/bootinfo64.c @@ -37,67 +37,14 @@ #include #include "bootstrap.h" +#include "modinfo.h" #include "libuserboot.h" /* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata + * We have 8 byte alignment for 64-bit targets. This code is compiled as 32-bit + * code... */ #define MOD_ALIGN(l) roundup(l, sizeof(uint64_t)) -#define COPY32(v, a, c) { \ - uint32_t x = (v); \ - if (c) \ - archsw.arch_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(strlen(s) + 1, a, c); \ - if (c) \ - archsw.arch_copyin(s, a, strlen(s) + 1);\ - a += MOD_ALIGN(strlen(s) + 1); \ -} - -#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) -#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) -#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) - -#define MOD_VAR(t, a, s, c) { \ - COPY32(t, a, c); \ - COPY32(sizeof(s), a, c); \ - if (c) \ - archsw.arch_copyin(&s, a, sizeof(s)); \ - a += MOD_ALIGN(sizeof(s)); \ -} - -#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) -#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) - -#define MOD_METADATA(a, mm, c) { \ - COPY32(MODINFO_METADATA | mm->md_type, a, c); \ - COPY32(mm->md_size, a, c); \ - if (c) \ - archsw.arch_copyin(mm->md_data, a, mm->md_size);\ - a += MOD_ALIGN(mm->md_size); \ -} - -#define MOD_END(a, c) { \ - COPY32(MODINFO_END, a, c); \ - COPY32(0, a, c); \ -} static vm_offset_t bi_copymodules64(vm_offset_t addr)