[userboot] migrate from print() to printl()
Change-Id: I8764ab08368b6bfa32f2df968bbd64389b81de6a
Esse commit está contido em:
commit de
CQ bot account: commit-bot@chromium.org
pai
2273afa447
commit
1381b36113
@@ -22,9 +22,9 @@ mx_handle_t bootdata_get_bootfs(mx_handle_t log, mx_handle_t vmar_self,
|
||||
size_t actual;
|
||||
mx_status_t status = mx_vmo_read(bootdata_vmo, &bootdata,
|
||||
off, sizeof(bootdata), &actual);
|
||||
check(log, status, "mx_vmo_read failed on bootdata VMO\n");
|
||||
check(log, status, "mx_vmo_read failed on bootdata VMO");
|
||||
if (actual != sizeof(bootdata))
|
||||
fail(log, MX_ERR_INVALID_ARGS, "short read on bootdata VMO\n");
|
||||
fail(log, "short read on bootdata VMO");
|
||||
|
||||
size_t hdrsz = sizeof(bootdata);
|
||||
if (bootdata.flags & BOOTDATA_FLAG_EXTRA) {
|
||||
@@ -37,8 +37,7 @@ mx_handle_t bootdata_get_bootfs(mx_handle_t log, mx_handle_t vmar_self,
|
||||
// Quietly skip container header.
|
||||
bootdata.length = 0;
|
||||
} else {
|
||||
fail(log, MX_ERR_INVALID_ARGS,
|
||||
"container in the middle of bootdata\n");
|
||||
fail(log, "container in the middle of bootdata");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -48,7 +47,7 @@ mx_handle_t bootdata_get_bootfs(mx_handle_t log, mx_handle_t vmar_self,
|
||||
status = decompress_bootdata(vmar_self, bootdata_vmo, off,
|
||||
bootdata.length + hdrsz,
|
||||
&bootfs_vmo, &errmsg);
|
||||
check(log, status, errmsg);
|
||||
check(log, status, "%s", errmsg);
|
||||
|
||||
// Signal that we've already processed this one.
|
||||
bootdata.type = BOOTDATA_BOOTFS_DISCARD;
|
||||
@@ -63,5 +62,5 @@ mx_handle_t bootdata_get_bootfs(mx_handle_t log, mx_handle_t vmar_self,
|
||||
off += BOOTDATA_ALIGN(hdrsz + bootdata.length);
|
||||
}
|
||||
|
||||
fail(log, MX_ERR_INVALID_ARGS, "no '/boot' bootfs in bootstrap message\n");
|
||||
fail(log, "no '/boot' bootfs in bootstrap message\n");
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ static const bootfs_entry_t* bootfs_search(mx_handle_t log,
|
||||
const void* p = fs->contents;
|
||||
|
||||
if (fs->len < sizeof(bootfs_header_t))
|
||||
fail(log, MX_ERR_INVALID_ARGS, "bootfs is too small\n");
|
||||
fail(log, "bootfs is too small");
|
||||
|
||||
const bootfs_header_t* hdr = p;
|
||||
if ((hdr->magic != BOOTFS_MAGIC) || (hdr->dirsize > fs->len))
|
||||
fail(log, MX_ERR_INVALID_ARGS, "bootfs bad magic or size\n");
|
||||
fail(log, "bootfs bad magic or size");
|
||||
|
||||
size_t filename_len = strlen(filename) + 1;
|
||||
|
||||
@@ -59,8 +59,7 @@ static const bootfs_entry_t* bootfs_search(mx_handle_t log,
|
||||
|
||||
size_t sz = BOOTFS_RECSIZE(e);
|
||||
if ((e->name_len < 1) || (sz > avail))
|
||||
fail(log, MX_ERR_INVALID_ARGS,
|
||||
"bootfs has bogus namelen in header\n");
|
||||
fail(log, "bootfs has bogus namelen in header");
|
||||
|
||||
if (e->name_len == filename_len) {
|
||||
if (!memcmp(e->name, filename, filename_len))
|
||||
@@ -76,18 +75,17 @@ static const bootfs_entry_t* bootfs_search(mx_handle_t log,
|
||||
|
||||
mx_handle_t bootfs_open(mx_handle_t log, const char* purpose,
|
||||
struct bootfs *fs, const char* filename) {
|
||||
print(log, "searching bootfs for ", purpose,
|
||||
" \"", filename, "\"\n", NULL);
|
||||
printl(log, "searching bootfs for '%s'", filename);
|
||||
|
||||
const bootfs_entry_t* e = bootfs_search(log, fs, filename);
|
||||
if (e == NULL) {
|
||||
print(log, "file not found\n", NULL);
|
||||
printl(log, "file not found");
|
||||
return MX_HANDLE_INVALID;
|
||||
}
|
||||
if (e->data_off > fs->len)
|
||||
fail(log, MX_ERR_INVALID_ARGS, "bogus offset in bootfs header!\n");
|
||||
fail(log, "bogus offset in bootfs header!");
|
||||
if (fs->len - e->data_off < e->data_len)
|
||||
fail(log, MX_ERR_INVALID_ARGS, "bogus size in bootfs header!\n");
|
||||
fail(log, "bogus size in bootfs header!");
|
||||
|
||||
// Clone a private copy of the file's subset of the bootfs VMO.
|
||||
// TODO(mcgrathr): Create a plain read-only clone when the feature
|
||||
@@ -96,7 +94,7 @@ mx_handle_t bootfs_open(mx_handle_t log, const char* purpose,
|
||||
mx_status_t status = mx_vmo_clone(fs->vmo, MX_VMO_CLONE_COPY_ON_WRITE,
|
||||
e->data_off, e->data_len, &vmo);
|
||||
if (status != MX_OK)
|
||||
fail(log, status, "mx_vmo_clone failed\n");
|
||||
fail(log, "mx_vmo_clone failed: %d", status);
|
||||
|
||||
mx_object_set_property(vmo, MX_PROP_NAME, filename, strlen(filename));
|
||||
|
||||
@@ -108,7 +106,7 @@ mx_handle_t bootfs_open(mx_handle_t log, const char* purpose,
|
||||
MX_RIGHT_TRANSFER | MX_RIGHT_DUPLICATE | MX_RIGHT_GET_PROPERTY,
|
||||
&vmo);
|
||||
if (status != MX_OK)
|
||||
fail(log, status, "mx_handle_replace failed\n");
|
||||
fail(log, "mx_handle_replace failed: %d", status);
|
||||
|
||||
return vmo;
|
||||
}
|
||||
|
||||
@@ -32,8 +32,7 @@ static void loader_config(struct loader_state* state, const char* string) {
|
||||
state->exclusive = true;
|
||||
}
|
||||
if (len >= sizeof(state->prefix) - 1) {
|
||||
fail(state->log, MX_ERR_INVALID_ARGS,
|
||||
"loader-service config string too long\n");
|
||||
fail(state->log, "loader-service config string too long");
|
||||
}
|
||||
memcpy(state->prefix, string, len);
|
||||
state->prefix[len++] = '/';
|
||||
@@ -57,7 +56,7 @@ static mx_handle_t load_object(struct loader_state* state, const char* name) {
|
||||
if (vmo == MX_HANDLE_INVALID && state->prefix_len > 0 && !state->exclusive)
|
||||
vmo = try_load_object(state, name, 0);
|
||||
if (vmo == MX_HANDLE_INVALID)
|
||||
fail(state->log, MX_ERR_NOT_FOUND, "cannot find shared library\n");
|
||||
fail(state->log, "cannot find shared library '%s'", name);
|
||||
return vmo;
|
||||
}
|
||||
|
||||
@@ -76,17 +75,15 @@ static bool handle_loader_rpc(struct loader_state* state,
|
||||
// This is the normal error for the other end going away,
|
||||
// which happens when the process dies.
|
||||
if (status == MX_ERR_PEER_CLOSED) {
|
||||
print(state->log,
|
||||
"loader-service channel peer closed on read\n", NULL);
|
||||
printl(state->log, "loader-service channel peer closed on read");
|
||||
return false;
|
||||
}
|
||||
|
||||
check(state->log, status,
|
||||
"mx_channel_read on loader-service channel failed\n");
|
||||
"mx_channel_read on loader-service channel failed");
|
||||
|
||||
if (size < sizeof(msgbuf.msg))
|
||||
fail(state->log, MX_ERR_OUT_OF_RANGE,
|
||||
"loader-service request message too small\n");
|
||||
fail(state->log, "loader-service request message too small");
|
||||
|
||||
// Forcibly null-terminate the message data argument.
|
||||
msgbuf.buffer[sizeof(msgbuf) - 1] = 0;
|
||||
@@ -94,11 +91,11 @@ static bool handle_loader_rpc(struct loader_state* state,
|
||||
mx_handle_t handle = MX_HANDLE_INVALID;
|
||||
switch (msgbuf.msg.opcode) {
|
||||
case LOADER_SVC_OP_DONE:
|
||||
print(state->log, "loader-service received DONE request\n", NULL);
|
||||
printl(state->log, "loader-service received DONE request");
|
||||
return false;
|
||||
|
||||
case LOADER_SVC_OP_DEBUG_PRINT:
|
||||
print(state->log, "loader-service: debug: ", string, "\n", NULL);
|
||||
printl(state->log, "loader-service: debug: %s", string);
|
||||
break;
|
||||
|
||||
case LOADER_SVC_OP_CONFIG:
|
||||
@@ -110,13 +107,11 @@ static bool handle_loader_rpc(struct loader_state* state,
|
||||
break;
|
||||
|
||||
case LOADER_SVC_OP_LOAD_SCRIPT_INTERP:
|
||||
fail(state->log, MX_ERR_INVALID_ARGS,
|
||||
"loader-service received LOAD_SCRIPT_INTERP request\n");
|
||||
fail(state->log, "loader-service received LOAD_SCRIPT_INTERP request");
|
||||
break;
|
||||
|
||||
default:
|
||||
fail(state->log, MX_ERR_INVALID_ARGS,
|
||||
"loader-service received invalid opcode\n");
|
||||
fail(state->log, "loader-service received invalid opcode");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -128,14 +123,14 @@ static bool handle_loader_rpc(struct loader_state* state,
|
||||
status = mx_channel_write(channel, 0, &msgbuf.msg, sizeof(msgbuf.msg),
|
||||
&handle, handle == MX_HANDLE_INVALID ? 0 : 1);
|
||||
check(state->log, status,
|
||||
"mx_channel_write on loader-service channel failed\n");
|
||||
"mx_channel_write on loader-service channel failed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void loader_service(mx_handle_t log, struct bootfs* bootfs,
|
||||
mx_handle_t channel) {
|
||||
print(log, "waiting for loader-service requests...\n", NULL);
|
||||
printl(log, "waiting for loader-service requests...");
|
||||
|
||||
struct loader_state state = {
|
||||
.log = log,
|
||||
@@ -153,17 +148,16 @@ void loader_service(mx_handle_t log, struct bootfs* bootfs,
|
||||
break;
|
||||
}
|
||||
check(log, status,
|
||||
"mx_object_wait_one failed on loader-service channel\n");
|
||||
"mx_object_wait_one failed on loader-service channel");
|
||||
if (signals & MX_CHANNEL_PEER_CLOSED) {
|
||||
print(log, "loader-service channel peer closed\n", NULL);
|
||||
printl(log, "loader-service channel peer closed");
|
||||
break;
|
||||
}
|
||||
if (!(signals & MX_CHANNEL_READABLE)) {
|
||||
fail(log, MX_ERR_BAD_STATE,
|
||||
"unexpected signal state on loader-service channel\n");
|
||||
fail(log, "unexpected signal state on loader-service channel");
|
||||
}
|
||||
} while (handle_loader_rpc(&state, channel));
|
||||
|
||||
check(log, mx_handle_close(channel),
|
||||
"mx_handle_close failed on loader-service channel\n");
|
||||
"mx_handle_close failed on loader-service channel");
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ void parse_options(mx_handle_t log, struct options *o, char** strings) {
|
||||
initialize_options(o);
|
||||
for (char** sp = strings; *sp != NULL; ++sp) {
|
||||
const char* arg = *sp;
|
||||
print(log, "option \"", arg, "\"\n", NULL);
|
||||
printl(log, "option \"%s\"", arg);
|
||||
apply_option(o, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,9 @@
|
||||
#define STACK_VMO_NAME "userboot-child-initial-stack"
|
||||
|
||||
static noreturn void do_shutdown(mx_handle_t log, mx_handle_t rroot) {
|
||||
print(log, "Process exited. Executing \"", SHUTDOWN_COMMAND, "\".\n",
|
||||
NULL);
|
||||
printl(log, "Process exited. Executing \"" SHUTDOWN_COMMAND "\".");
|
||||
mx_debug_send_command(rroot, SHUTDOWN_COMMAND, strlen(SHUTDOWN_COMMAND));
|
||||
print(log, "still here after shutdown!\n", NULL);
|
||||
printl(log, "still here after shutdown!");
|
||||
while (true)
|
||||
__builtin_trap();
|
||||
}
|
||||
@@ -64,7 +63,7 @@ static mx_handle_t reserve_low_address_space(mx_handle_t log,
|
||||
mx_info_vmar_t info;
|
||||
check(log, mx_object_get_info(root_vmar, MX_INFO_VMAR,
|
||||
&info, sizeof(info), NULL, NULL),
|
||||
"mx_object_get_info failed on child root VMAR handle\n");
|
||||
"mx_object_get_info failed on child root VMAR handle");
|
||||
mx_handle_t vmar;
|
||||
uintptr_t addr;
|
||||
size_t reserve_size =
|
||||
@@ -73,9 +72,9 @@ static mx_handle_t reserve_low_address_space(mx_handle_t log,
|
||||
reserve_size - info.base,
|
||||
MX_VM_FLAG_SPECIFIC, &vmar, &addr);
|
||||
check(log, status,
|
||||
"mx_vmar_allocate failed for low address space reservation\n");
|
||||
"mx_vmar_allocate failed for low address space reservation");
|
||||
if (addr != info.base)
|
||||
fail(log, MX_ERR_BAD_STATE, "mx_vmar_allocate gave wrong address?!?\n");
|
||||
fail(log, "mx_vmar_allocate gave wrong address?!?");
|
||||
return vmar;
|
||||
}
|
||||
|
||||
@@ -97,7 +96,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
uint32_t nhandles;
|
||||
|
||||
mx_status_t status = mxr_message_size(bootstrap_pipe, &nbytes, &nhandles);
|
||||
check(log, status, "mxr_message_size failed on bootstrap pipe!\n");
|
||||
check(log, status, "mxr_message_size failed on bootstrap pipe!");
|
||||
|
||||
// Read the bootstrap message from the kernel.
|
||||
MXR_PROCESSARGS_BUFFER(buffer,
|
||||
@@ -108,7 +107,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
status = mxr_processargs_read(bootstrap_pipe,
|
||||
buffer, nbytes, handles, nhandles,
|
||||
&pargs, &handle_info);
|
||||
check(log, status, "mxr_processargs_read failed on bootstrap message!\n");
|
||||
check(log, status, "mxr_processargs_read failed on bootstrap message!");
|
||||
|
||||
// All done with the channel from the kernel now. Let it go.
|
||||
mx_handle_close(bootstrap_pipe);
|
||||
@@ -116,13 +115,11 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
// We're adding some extra handles, so we have to rearrange the
|
||||
// incoming message buffer to make space for their info slots.
|
||||
if (pargs->args_off != 0 || pargs->args_num != 0) {
|
||||
fail(log, MX_ERR_INVALID_ARGS,
|
||||
"unexpected bootstrap message layout: args\n");
|
||||
fail(log, "unexpected bootstrap message layout: args");
|
||||
}
|
||||
if (pargs->environ_off != (pargs->handle_info_off +
|
||||
nhandles * sizeof(uint32_t))) {
|
||||
fail(log, MX_ERR_INVALID_ARGS,
|
||||
"unexpected bootstrap message layout: environ\n");
|
||||
fail(log, "unexpected bootstrap message layout: environ");
|
||||
}
|
||||
const size_t environ_size = nbytes - pargs->environ_off;
|
||||
pargs->environ_off += EXTRA_HANDLE_COUNT * sizeof(uint32_t);
|
||||
@@ -135,7 +132,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
char* environ[pargs->environ_num + 1];
|
||||
status = mxr_processargs_strings(buffer, nbytes, NULL, environ, NULL);
|
||||
check(log, status,
|
||||
"mxr_processargs_strings failed on bootstrap message\n");
|
||||
"mxr_processargs_strings failed on bootstrap message");
|
||||
|
||||
// Process the kernel command line, which gives us options and also
|
||||
// becomes the environment strings for our child.
|
||||
@@ -182,17 +179,15 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
}
|
||||
}
|
||||
if (vdso_vmo == MX_HANDLE_INVALID)
|
||||
fail(log, MX_ERR_INVALID_ARGS, "no vDSO handle in bootstrap message\n");
|
||||
fail(log, "no vDSO handle in bootstrap message");
|
||||
if (resource_root == MX_HANDLE_INVALID)
|
||||
fail(log, MX_ERR_INVALID_ARGS,
|
||||
"no resource handle in bootstrap message\n");
|
||||
fail(log, "no resource handle in bootstrap message");
|
||||
if (job == MX_HANDLE_INVALID)
|
||||
fail(log, MX_ERR_INVALID_ARGS, "no job handle in bootstrap message\n");
|
||||
fail(log, "no job handle in bootstrap message");
|
||||
if (vmar_root_handle_loc == NULL)
|
||||
fail(log, MX_ERR_INVALID_ARGS,
|
||||
"no vmar root handle in bootstrap message\n");
|
||||
fail(log, "no vmar root handle in bootstrap message");
|
||||
if (bootdata_vmo == MX_HANDLE_INVALID)
|
||||
fail(log, MX_ERR_INVALID_ARGS, "no bootdata VMO in bootstrap message\n");
|
||||
fail(log, "no bootdata VMO in bootstrap message");
|
||||
|
||||
// Hang on to our own process handle. If we closed it, our process
|
||||
// would be killed. Exiting will clean it up.
|
||||
@@ -204,7 +199,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
status = mx_handle_duplicate(resource_root, MX_RIGHT_SAME_RIGHTS,
|
||||
&root_resource_handle);
|
||||
if (status < 0)
|
||||
fail(log, status, "mx_handle_duplicate failed\n");
|
||||
fail(log, "mx_handle_duplicate failed: %d", status);
|
||||
|
||||
// Locate the first bootfs bootdata section and decompress it.
|
||||
// We need it to load devmgr and libc from.
|
||||
@@ -224,7 +219,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
mx_handle_t to_child;
|
||||
mx_handle_t child_start_handle;
|
||||
status = mx_channel_create(0, &to_child, &child_start_handle);
|
||||
check(log, status, "mx_channel_create failed\n");
|
||||
check(log, status, "mx_channel_create failed");
|
||||
|
||||
const char* filename = o.value[OPTION_FILENAME];
|
||||
mx_handle_t proc;
|
||||
@@ -232,7 +227,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
status = mx_process_create(job, filename, strlen(filename), 0,
|
||||
&proc, &vmar);
|
||||
if (status < 0)
|
||||
fail(log, status, "mx_process_create failed\n");
|
||||
fail(log, "mx_process_create failed: %d", status);
|
||||
|
||||
mx_handle_t reserve_vmar = reserve_low_address_space(log, vmar);
|
||||
|
||||
@@ -240,7 +235,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
mx_handle_t thread;
|
||||
status = mx_thread_create(proc, filename, strlen(filename), 0, &thread);
|
||||
if (status < 0)
|
||||
fail(log, status, "mx_thread_create failed\n");
|
||||
fail(log, "mx_thread_create failed: %d", status);
|
||||
|
||||
mx_vaddr_t entry, vdso_base;
|
||||
size_t stack_size = MAGENTA_DEFAULT_STACK_SIZE;
|
||||
@@ -254,14 +249,14 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
mx_handle_t stack_vmo;
|
||||
status = mx_vmo_create(stack_size, 0, &stack_vmo);
|
||||
if (status < 0)
|
||||
fail(log, status, "mx_vmo_create failed for child stack\n");
|
||||
fail(log, "mx_vmo_create failed for child stack: %d", status);
|
||||
mx_object_set_property(stack_vmo, MX_PROP_NAME,
|
||||
STACK_VMO_NAME, sizeof(STACK_VMO_NAME) - 1);
|
||||
mx_vaddr_t stack_base;
|
||||
status = mx_vmar_map(vmar, 0, stack_vmo, 0, stack_size,
|
||||
MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE,
|
||||
&stack_base);
|
||||
check(log, status, "mx_vmar_map failed for child stack\n");
|
||||
check(log, status, "mx_vmar_map failed for child stack");
|
||||
uintptr_t sp = compute_initial_stack_pointer(stack_base, stack_size);
|
||||
if (stack_vmo_handle_loc != NULL) {
|
||||
// This is our own stack VMO handle, but we don't need it for anything.
|
||||
@@ -274,15 +269,14 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
|
||||
// We're done doing mappings, so clear out the reservation VMAR.
|
||||
check(log, mx_vmar_destroy(reserve_vmar),
|
||||
"mx_vmar_destroy failed on reservation VMAR handle\n");
|
||||
"mx_vmar_destroy failed on reservation VMAR handle");
|
||||
check(log, mx_handle_close(reserve_vmar),
|
||||
"mx_handle_close failed on reservation VMAR handle\n");
|
||||
"mx_handle_close failed on reservation VMAR handle");
|
||||
|
||||
// Reuse the slot for the child's handle.
|
||||
status = mx_handle_duplicate(proc, MX_RIGHT_SAME_RIGHTS, proc_handle_loc);
|
||||
if (status < 0)
|
||||
fail(log, status,
|
||||
"mx_handle_duplicate failed on child process handle\n");
|
||||
fail(log, "mx_handle_duplicate failed on child process handle: %d", status);
|
||||
|
||||
if (thread_handle_loc != NULL) {
|
||||
// Reuse the slot for the child's handle.
|
||||
@@ -290,8 +284,7 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
status = mx_handle_duplicate(thread, MX_RIGHT_SAME_RIGHTS,
|
||||
thread_handle_loc);
|
||||
if (status < 0)
|
||||
fail(log, status,
|
||||
"mx_handle_duplicate failed on child thread handle\n");
|
||||
fail(log, "mx_handle_duplicate failed on child thread handle: %d", status);
|
||||
}
|
||||
|
||||
// Reuse the slot for the child's root VMAR handle. We don't need to hold
|
||||
@@ -303,18 +296,18 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
// processes from here on.
|
||||
status = mx_channel_write(to_child, 0, buffer, nbytes,
|
||||
handles, nhandles + EXTRA_HANDLE_COUNT);
|
||||
check(log, status, "mx_channel_write to child failed\n");
|
||||
check(log, status, "mx_channel_write to child failed");
|
||||
status = mx_handle_close(to_child);
|
||||
check(log, status, "mx_handle_close failed on channel handle\n");
|
||||
check(log, status, "mx_handle_close failed on channel handle");
|
||||
|
||||
// Start the process going.
|
||||
status = mx_process_start(proc, thread, entry, sp,
|
||||
child_start_handle, vdso_base);
|
||||
check(log, status, "mx_process_start failed\n");
|
||||
check(log, status, "mx_process_start failed");
|
||||
status = mx_handle_close(thread);
|
||||
check(log, status, "mx_handle_close failed on thread handle\n");
|
||||
check(log, status, "mx_handle_close failed on thread handle");
|
||||
|
||||
print(log, "process ", o.value[OPTION_FILENAME], " started.\n", NULL);
|
||||
printl(log, "process %s started.", o.value[OPTION_FILENAME]);
|
||||
|
||||
// Now become the loader service for as long as that's needed.
|
||||
if (loader_service_channel != MX_HANDLE_INVALID)
|
||||
@@ -324,20 +317,19 @@ static noreturn void bootstrap(mx_handle_t log, mx_handle_t bootstrap_pipe) {
|
||||
bootfs_unmount(vmar_self, log, &bootfs);
|
||||
|
||||
if (o.value[OPTION_SHUTDOWN] != NULL) {
|
||||
print(log, "Waiting for ", o.value[OPTION_FILENAME], " to exit...\n",
|
||||
NULL);
|
||||
printl(log, "Waiting for %s to exit...", o.value[OPTION_FILENAME]);
|
||||
status = mx_object_wait_one(
|
||||
proc, MX_PROCESS_TERMINATED, MX_TIME_INFINITE, NULL);
|
||||
check(log, status, "mx_object_wait_one on process failed\n");
|
||||
check(log, status, "mx_object_wait_one on process failed");
|
||||
do_shutdown(log, root_resource_handle);
|
||||
}
|
||||
|
||||
// Now we've accomplished our purpose in life, and we can die happy.
|
||||
|
||||
status = mx_handle_close(proc);
|
||||
check(log, status, "mx_handle_close failed on process handle\n");
|
||||
check(log, status, "mx_handle_close failed on process handle");
|
||||
|
||||
print(log, "finished!\n", NULL);
|
||||
printl(log, "finished!");
|
||||
mx_process_exit(0);
|
||||
}
|
||||
|
||||
@@ -347,8 +339,7 @@ noreturn void _start(void* start_arg) {
|
||||
mx_handle_t log = MX_HANDLE_INVALID;
|
||||
mx_log_create(0, &log);
|
||||
if (log == MX_HANDLE_INVALID)
|
||||
print(log, "mx_log_create failed, using mx_debug_write instead\n",
|
||||
NULL);
|
||||
printl(log, "mx_log_create failed, using mx_debug_write instead");
|
||||
|
||||
mx_handle_t bootstrap_pipe = (uintptr_t)start_arg;
|
||||
bootstrap(log, bootstrap_pipe);
|
||||
|
||||
@@ -28,11 +28,11 @@ static mx_vaddr_t load(mx_handle_t log, mx_handle_t vmar, mx_handle_t vmo,
|
||||
elf_load_header_t header;
|
||||
uintptr_t phoff;
|
||||
mx_status_t status = elf_load_prepare(vmo, NULL, 0, &header, &phoff);
|
||||
check(log, status, "elf_load_prepare failed\n");
|
||||
check(log, status, "elf_load_prepare failed");
|
||||
|
||||
elf_phdr_t phdrs[header.e_phnum];
|
||||
status = elf_load_read_phdrs(vmo, phdrs, phoff, header.e_phnum);
|
||||
check(log, status, "elf_load_read_phdrs failed\n");
|
||||
check(log, status, "elf_load_read_phdrs failed");
|
||||
|
||||
if (interp_off != NULL &&
|
||||
elf_load_find_interp(phdrs, header.e_phnum, interp_off, interp_len))
|
||||
@@ -50,7 +50,7 @@ static mx_vaddr_t load(mx_handle_t log, mx_handle_t vmar, mx_handle_t vmo,
|
||||
segments_vmar,
|
||||
return_entry ? NULL : &addr,
|
||||
return_entry ? &addr : NULL);
|
||||
check(log, status, "elf_load_map_segments failed\n");
|
||||
check(log, status, "elf_load_map_segments failed");
|
||||
|
||||
if (close_vmo)
|
||||
mx_handle_close(vmo);
|
||||
@@ -120,24 +120,24 @@ static void stuff_loader_bootstrap(mx_handle_t log,
|
||||
};
|
||||
check(log, mx_handle_duplicate(log, MX_RIGHT_SAME_RIGHTS,
|
||||
&handles[BOOTSTRAP_LOGGER]),
|
||||
"mx_handle_duplicate failed\n");
|
||||
"mx_handle_duplicate failed");
|
||||
check(log, mx_handle_duplicate(proc, MX_RIGHT_SAME_RIGHTS,
|
||||
&handles[BOOTSTRAP_PROC]),
|
||||
"mx_handle_duplicate failed\n");
|
||||
"mx_handle_duplicate failed");
|
||||
check(log, mx_handle_duplicate(root_vmar, MX_RIGHT_SAME_RIGHTS,
|
||||
&handles[BOOTSTRAP_ROOT_VMAR]),
|
||||
"mx_handle_duplicate failed\n");
|
||||
"mx_handle_duplicate failed");
|
||||
check(log, mx_handle_duplicate(thread, MX_RIGHT_SAME_RIGHTS,
|
||||
&handles[BOOTSTRAP_THREAD]),
|
||||
"mx_handle_duplicate failed\n");
|
||||
"mx_handle_duplicate failed");
|
||||
check(log, mx_channel_create(0, loader_svc,
|
||||
&handles[BOOTSTRAP_LOADER_SVC]),
|
||||
"mx_channel_create failed\n");
|
||||
"mx_channel_create failed");
|
||||
|
||||
mx_status_t status = mx_channel_write(
|
||||
to_child, 0, &msg, sizeof(msg), handles, countof(handles));
|
||||
check(log, status,
|
||||
"mx_channel_write of loader bootstrap message failed\n");
|
||||
"mx_channel_write of loader bootstrap message failed");
|
||||
}
|
||||
|
||||
mx_vaddr_t elf_load_bootfs(mx_handle_t log, struct bootfs *fs, mx_handle_t proc,
|
||||
@@ -158,12 +158,12 @@ mx_vaddr_t elf_load_bootfs(mx_handle_t log, struct bootfs *fs, mx_handle_t proc,
|
||||
vmo, &interp[sizeof(INTERP_PREFIX) - 1],
|
||||
interp_off, interp_len, &n);
|
||||
if (status < 0)
|
||||
fail(log, status, "mx_vmo_read failed\n");
|
||||
fail(log, "mx_vmo_read failed: %d", status);
|
||||
if (n != interp_len)
|
||||
fail(log, ERR_ELF_BAD_FORMAT, "mx_vmo_read short read\n");
|
||||
fail(log, "mx_vmo_read short read");
|
||||
interp[sizeof(INTERP_PREFIX) - 1 + interp_len] = '\0';
|
||||
|
||||
print(log, filename, " has PT_INTERP \"", interp, "\"\n", NULL);
|
||||
printl(log, "'%s' has PT_INTERP \"%s\"", filename, interp);
|
||||
|
||||
mx_handle_t interp_vmo =
|
||||
bootfs_open(log, "dynamic linker", fs, interp);
|
||||
|
||||
@@ -18,39 +18,6 @@
|
||||
#define LOG_WRITE_FAIL \
|
||||
(LOG_PREFIX "Error printing error message. No error message printed.\n")
|
||||
|
||||
void print(mx_handle_t log, const char* s, ...) {
|
||||
char buffer[MX_LOG_RECORD_MAX - sizeof(mx_log_record_t)];
|
||||
static_assert(sizeof(LOG_PREFIX) < sizeof(buffer), "buffer too small");
|
||||
|
||||
memcpy(buffer, LOG_PREFIX, sizeof(LOG_PREFIX) - 1);
|
||||
char* p = &buffer[sizeof(LOG_PREFIX) - 1];
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, s);
|
||||
do {
|
||||
size_t len = strlen(s);
|
||||
if ((size_t)(&buffer[sizeof(buffer)] - p) <= len)
|
||||
__builtin_trap();
|
||||
memcpy(p, s, len);
|
||||
p += len;
|
||||
s = va_arg(ap, const char*);
|
||||
} while (s != NULL);
|
||||
va_end(ap);
|
||||
|
||||
if (log == MX_HANDLE_INVALID) {
|
||||
mx_debug_write(buffer, p - buffer);
|
||||
} else {
|
||||
mx_status_t status = mx_log_write(log, p - buffer, buffer, 0);
|
||||
if (status != MX_OK)
|
||||
mx_debug_write(LOG_WRITE_FAIL, strlen(LOG_WRITE_FAIL));
|
||||
}
|
||||
}
|
||||
|
||||
void fail(mx_handle_t log, mx_status_t status, const char* msg) {
|
||||
print(log, msg, NULL);
|
||||
mx_process_exit(status);
|
||||
}
|
||||
|
||||
static char* hexstring(char* s, size_t len, uint64_t n) {
|
||||
char tmp[16];
|
||||
char* hex = tmp;
|
||||
@@ -172,4 +139,14 @@ void printl(mx_handle_t log, const char* fmt, ...) {
|
||||
va_start(ap, fmt);
|
||||
vprintl(log, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void fail(mx_handle_t log, const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vprintl(log, fmt, ap);
|
||||
va_end(ap);
|
||||
mx_process_exit(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,16 +11,13 @@
|
||||
|
||||
// printl() is printf-like, understanding %s %p %d %u %x %zu %zd %zx.
|
||||
// No other formatting features are supported.
|
||||
void printl(mx_handle_t log, const char* fmt, ...);
|
||||
void __PRINTFLIKE(2, 3) printl(mx_handle_t log, const char* fmt, ...);
|
||||
void vprintl(mx_handle_t log, const char* fmt, va_list ap);
|
||||
|
||||
void print(mx_handle_t log, const char* s, ...) __attribute__((sentinel));
|
||||
_Noreturn void fail(mx_handle_t log, mx_status_t status, const char* msg);
|
||||
// fail() combines printl() with process exit
|
||||
_Noreturn void __PRINTFLIKE(2, 3) fail(mx_handle_t log, const char* fmt, ...);
|
||||
|
||||
static inline void check(mx_handle_t log,
|
||||
mx_status_t status, const char* msg) {
|
||||
if (status != MX_OK)
|
||||
fail(log, status, msg);
|
||||
}
|
||||
#define check(log, status, msg...) \
|
||||
do { if (status != MX_OK) fail(log, msg); } while (0)
|
||||
|
||||
#pragma GCC visibility pop
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário