[libj6] Change to a more SysV style process init args
Pull out the old linked list of args structures in favor of doing things the SysV ABI-specified way.
This commit is contained in:
@@ -12,39 +12,42 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define add_header(name) \
|
||||
static constexpr j6_arg_type type_id = j6_arg_type_ ## name; \
|
||||
j6_arg_header header;
|
||||
#else
|
||||
#define add_header(name) \
|
||||
j6_arg_header header;
|
||||
#endif
|
||||
enum j6_aux_type {
|
||||
// The SysV ABI-specified aux vector types
|
||||
j6_aux_null, // AT_NULL
|
||||
j6_aux_ignore, // AT_IGNORE
|
||||
j6_aux_execfd, // AD_EXECFD - File descriptor of the exe to load
|
||||
j6_aux_phdr, // AD_PHDR - Program headers pointer for the exe to load
|
||||
j6_aux_phent, // AD_PHENT - Size of a program header entry
|
||||
j6_aux_phnum, // AD_PHNUM - Number of program header entries
|
||||
j6_aux_pagesz, // AD_PAGESZ - System page size
|
||||
j6_aux_base, // AD_BASE - Base address of dynamic loader
|
||||
j6_aux_flags, // AD_FLAGS - Flags
|
||||
j6_aux_entry, // AD_ENTRY - Entrypoint for the exe to load
|
||||
j6_aux_notelf, // AD_NOTELF - If non-zero, this program is not ELF
|
||||
j6_aux_uid, // AD_UID - User ID
|
||||
j6_aux_euid, // AD_EUID - Effective User ID
|
||||
j6_aux_gid, // AD_GID - Group ID
|
||||
j6_aux_egid, // AD_EGID - Effective Group ID
|
||||
|
||||
enum j6_arg_type {
|
||||
j6_arg_type_none,
|
||||
j6_arg_type_sysv_init,
|
||||
j6_arg_type_loader,
|
||||
j6_arg_type_driver,
|
||||
j6_arg_type_handles,
|
||||
j6_aux_start = 0xf000,
|
||||
j6_aux_handles, // Pointer to a j6_arg_handles structure
|
||||
j6_aux_device, // Pointer to a j6_arg_driver structure
|
||||
j6_aux_loader, // Pointer to a j6_arg_loader structure
|
||||
};
|
||||
|
||||
struct j6_arg_header
|
||||
struct j6_aux
|
||||
{
|
||||
uint32_t size;
|
||||
uint16_t type;
|
||||
uint16_t reserved;
|
||||
j6_arg_header *next;
|
||||
};
|
||||
|
||||
struct j6_arg_none
|
||||
{
|
||||
add_header(none);
|
||||
uint64_t type;
|
||||
union {
|
||||
uint64_t value;
|
||||
void *pointer;
|
||||
void (*func)();
|
||||
};
|
||||
};
|
||||
|
||||
struct j6_arg_loader
|
||||
{
|
||||
add_header(loader);
|
||||
uintptr_t loader_base;
|
||||
uintptr_t image_base;
|
||||
uintptr_t *got;
|
||||
@@ -54,8 +57,8 @@ struct j6_arg_loader
|
||||
|
||||
struct j6_arg_driver
|
||||
{
|
||||
add_header(driver);
|
||||
uint64_t device;
|
||||
uint32_t size;
|
||||
uint8_t data [0];
|
||||
};
|
||||
|
||||
@@ -67,32 +70,13 @@ struct j6_arg_handle_entry
|
||||
|
||||
struct j6_arg_handles
|
||||
{
|
||||
add_header(handles);
|
||||
size_t nhandles;
|
||||
j6_arg_handle_entry handles[0];
|
||||
};
|
||||
|
||||
struct j6_init_args
|
||||
{
|
||||
uint64_t argv[2];
|
||||
j6_arg_header *args;
|
||||
};
|
||||
|
||||
|
||||
/// Find the first handle of the given type held by this process
|
||||
j6_handle_t API j6_find_first_handle(j6_object_type obj_type);
|
||||
|
||||
/// Find the first handle tagged with the given proto in the process init args
|
||||
j6_handle_t API j6_find_init_handle(uint64_t proto);
|
||||
|
||||
/// Get the init args
|
||||
const j6_init_args * j6_get_init_args();
|
||||
|
||||
/// Drivers may use driver_main instead of main
|
||||
int driver_main(unsigned, const char **, const char **, const j6_init_args *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#undef add_header
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// The kernel depends on libj6 for some shared code,
|
||||
// but should not include the user-specific code.
|
||||
#include "j6/init.h"
|
||||
#include "j6/types.h"
|
||||
#ifndef __j6kernel
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -10,65 +12,45 @@
|
||||
#include <j6/types.h>
|
||||
|
||||
namespace {
|
||||
constexpr size_t static_arr_count = 32;
|
||||
j6_handle_descriptor handle_array[static_arr_count];
|
||||
j6_init_args init_args = { 0, 0, 0 };
|
||||
} // namespace
|
||||
char const * const *envp = nullptr;
|
||||
const j6_aux *aux = nullptr;
|
||||
|
||||
j6_handle_t
|
||||
j6_find_first_handle(j6_object_type obj_type)
|
||||
{
|
||||
size_t count = static_arr_count;
|
||||
j6_handle_descriptor *handles = handle_array;
|
||||
j6_status_t s = j6_handle_list(handles, &count);
|
||||
|
||||
if (s != j6_err_insufficient && s != j6_status_ok)
|
||||
return j6_handle_invalid;
|
||||
|
||||
if (count > static_arr_count)
|
||||
count = static_arr_count;
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
j6_handle_descriptor &desc = handle_array[i];
|
||||
if (desc.type == obj_type) return desc.handle;
|
||||
const j6_aux * find_aux(uint64_t type) {
|
||||
if (!aux) return nullptr;
|
||||
for (j6_aux const *p = aux; p->type; ++p)
|
||||
if (p->type == type) return p;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return j6_handle_invalid;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
j6_handle_t
|
||||
j6_find_init_handle(uint64_t proto)
|
||||
{
|
||||
j6_arg_header *arg = init_args.args;
|
||||
while (arg) {
|
||||
if (arg->type == j6_arg_type_handles) {
|
||||
j6_arg_handles *harg = reinterpret_cast<j6_arg_handles*>(arg);
|
||||
for (unsigned i = 0; i < harg->nhandles; ++i) {
|
||||
j6_arg_handle_entry &ent = harg->handles[i];
|
||||
if (ent.proto == proto)
|
||||
return ent.handle;
|
||||
}
|
||||
}
|
||||
arg = arg->next;
|
||||
const j6_aux *aux_handles = find_aux(j6_aux_handles);
|
||||
if (!aux_handles)
|
||||
return j6_handle_invalid;
|
||||
|
||||
const j6_arg_handles *arg = reinterpret_cast<const j6_arg_handles*>(aux_handles->pointer);
|
||||
for (unsigned i = 0; i < arg->nhandles; ++i) {
|
||||
const j6_arg_handle_entry &ent = arg->handles[i];
|
||||
if (ent.proto == proto)
|
||||
return ent.handle;
|
||||
}
|
||||
|
||||
return j6_handle_invalid;
|
||||
}
|
||||
|
||||
|
||||
const j6_init_args * API
|
||||
j6_get_init_args()
|
||||
{
|
||||
return &init_args;
|
||||
}
|
||||
|
||||
extern "C" void API
|
||||
__init_libj6(uint64_t argv0, uint64_t argv1, j6_arg_header *args)
|
||||
__init_libj6(const uint64_t *stack)
|
||||
{
|
||||
init_args.argv[0] = argv0;
|
||||
init_args.argv[1] = argv1;
|
||||
init_args.args = args;
|
||||
}
|
||||
// Walk the stack to get the aux vector
|
||||
uint64_t argc = *stack++;
|
||||
stack += argc + 1; // Skip argv's and sentinel
|
||||
|
||||
envp = reinterpret_cast<char const * const *>(stack);
|
||||
while (*stack++); // Skip envp's and sentinel
|
||||
|
||||
aux = reinterpret_cast<const j6_aux*>(stack);
|
||||
}
|
||||
|
||||
#endif // __j6kernel
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
extern driver_main
|
||||
global main:function weak (main.end - main)
|
||||
main:
|
||||
jmp driver_main
|
||||
main.end:
|
||||
|
||||
Reference in New Issue
Block a user