diff options
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust.cpp | 2 | ||||
| -rw-r--r-- | src/rt/rust_crate.cpp | 86 | ||||
| -rw-r--r-- | src/rt/rust_internal.h | 5 | ||||
| -rw-r--r-- | src/rt/rust_log.cpp | 4 |
4 files changed, 95 insertions, 2 deletions
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 9600b4d5..013705f2 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -80,6 +80,7 @@ extern "C" CDECL int rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, char **argv) { + crate->update_log_settings(getenv("RUST_LOG")); rust_srv *srv = new rust_srv(); rust_kernel *kernel = new rust_kernel(srv); kernel->start(); @@ -102,6 +103,7 @@ rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, dom->root_task->start(crate->get_exit_task_glue(), crate->abi_tag, main_fn, (uintptr_t)&main_args, sizeof(main_args)); + int ret = dom->start_main_loop(); delete args; kernel->destroy_domain(dom); diff --git a/src/rt/rust_crate.cpp b/src/rt/rust_crate.cpp index 23f01c07..e7ee0350 100644 --- a/src/rt/rust_crate.cpp +++ b/src/rt/rust_crate.cpp @@ -65,6 +65,92 @@ rust_crate::get_debug_abbrev(rust_dom *dom) const { return mem_area(dom, 0, 0); } +struct mod_entry { + const char* name; + int* state; +}; + +struct cratemap { + mod_entry* entries; + cratemap* children[1]; +}; + +struct log_directive { + char* name; + size_t level; +}; + +const size_t max_log_directives = 255; + +size_t parse_logging_spec(char* spec, log_directive* dirs) { + size_t dir = 0; + while (dir < max_log_directives && *spec) { + char* start = spec; + char cur; + while (true) { + cur = *spec; + if (cur == ',' || cur == '=' || cur == '\0') { + if (start == spec) {spec++; break;} + *spec = '\0'; + spec++; + size_t level = 3; + if (cur == '=') { + level = *spec - '0'; + if (level > 3) level = 1; + if (*spec) ++spec; + } + dirs[dir].name = start; + dirs[dir++].level = level; + break; + } + spec++; + } + } + return dir; +} + +void update_crate_map(cratemap* map, log_directive* dirs, size_t n_dirs) { + // First update log levels for this crate + for (mod_entry* cur = map->entries; cur->name; cur++) { + size_t level = 1, longest_match = 0; + for (size_t d = 0; d < n_dirs; d++) { + if (strstr(cur->name, dirs[d].name) == cur->name && + strlen(dirs[d].name) > longest_match) { + longest_match = strlen(dirs[d].name); + level = dirs[d].level; + } + } + *cur->state = level; + } + + // Then recurse on linked crates + for (size_t i = 0; map->children[i]; i++) { + update_crate_map(map->children[i], dirs, n_dirs); + } +} + +void rust_crate::update_log_settings(char* settings) const { + // Only try this if the crate was generated by Rustc, not rustboot + if (image_base_off) return; + + // This is a rather ugly parser for strings in the form + // "crate1,crate2.mod3,crate3.x=2". Log levels range 0=err, 1=warn, + // 2=info, 3=debug. Default is 1. Words without an '=X' part set the log + // level for that module (and submodules) to 3. + char* buffer = NULL; + log_directive dirs[256]; + size_t dir = 0; + if (settings) { + buffer = (char*)malloc(strlen(settings)); + strcpy(buffer, settings); + dir = parse_logging_spec(buffer, &dirs[0]); + } + + update_crate_map((cratemap*)crate_map, &dirs[0], dir); + + free(buffer); +} + // // Local Variables: // mode: C++ diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index 4a1f3e45..695fc21d 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -248,6 +248,9 @@ public: size_t n_libs; uintptr_t abi_tag; + // FIXME: not generated by rustboot, should only be accessed in crates + // generated by rustc. + void* crate_map; // Crates are immutable, constructed by the compiler. @@ -259,6 +262,8 @@ public: uintptr_t get_gc_glue() const; uintptr_t get_exit_task_glue() const; + void update_log_settings(char* settings) const; + struct mem_area { rust_dom *dom; diff --git a/src/rt/rust_log.cpp b/src/rt/rust_log.cpp index 3017b549..076c4b0a 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -9,6 +9,7 @@ #include <stdlib.h> #include <string.h> +// FIXME somehow unify this with the parsing happening in rust_crate.cpp static uint32_t read_type_bit_mask() { uint32_t bits = rust_log::ULOG | rust_log::ERR; @@ -18,14 +19,13 @@ read_type_bit_mask() { str[0] = ','; strcpy(str + 1, env_str); - bits = 0; + bits = rust_log::ULOG; bits |= strstr(str, ",err") ? rust_log::ERR : 0; bits |= strstr(str, ",mem") ? rust_log::MEM : 0; bits |= strstr(str, ",comm") ? rust_log::COMM : 0; bits |= strstr(str, ",task") ? rust_log::TASK : 0; bits |= strstr(str, ",up") ? rust_log::UPCALL : 0; bits |= strstr(str, ",dom") ? rust_log::DOM : 0; - bits |= strstr(str, ",ulog") ? rust_log::ULOG : 0; bits |= strstr(str, ",trace") ? rust_log::TRACE : 0; bits |= strstr(str, ",dwarf") ? rust_log::DWARF : 0; bits |= strstr(str, ",cache") ? rust_log::CACHE : 0; |