diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index db27a823fbc315477e2c9ec8613edfe909228efb..c7ad35b52fd6e24bcba7e59cd71bf6503296135b 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -428,8 +428,7 @@ fn T_crate(type_names tn) -> TypeRef { T_int(), // int n_rust_syms T_int(), // int n_c_syms T_int(), // int n_libs - T_int(), // uintptr_t abi_tag - T_int() // void* crate_map + T_int() // uintptr_t abi_tag )); tn.associate(s, t); ret t; @@ -6624,8 +6623,7 @@ fn create_typedefs(@crate_ctxt cx) { llvm.LLVMAddTypeName(cx.llmod, _str.buf("tydesc"), T_tydesc(cx.tn)); } -fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues, - ValueRef crate_map) { +fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues) { let ValueRef crate_addr = p2i(crate_ptr); @@ -6653,8 +6651,7 @@ fn create_crate_constant(ValueRef crate_ptr, @glue_fns glues, C_null(T_int()), // int n_rust_syms C_null(T_int()), // int n_c_syms C_null(T_int()), // int n_libs - C_int(abi.abi_x86_rustc_fastcall), // uintptr_t abi_tag - p2i(crate_map) // void* crate_map + C_int(abi.abi_x86_rustc_fastcall) // uintptr_t abi_tag )); llvm.LLVMSetInitializer(crate_ptr, crate_val); @@ -6684,9 +6681,9 @@ fn find_main_fn(@crate_ctxt cx) -> ValueRef { fail; } -fn trans_main_fn(@local_ctxt cx, ValueRef llcrate) { +fn trans_main_fn(@local_ctxt cx, ValueRef llcrate, ValueRef crate_map) { auto T_main_args = vec(T_int(), T_int()); - auto T_rust_start_args = vec(T_int(), T_int(), T_int(), T_int()); + auto T_rust_start_args = vec(T_int(), T_int(), T_int(), T_int(), T_int()); auto main_name; if (_str.eq(std.os.target_os(), "win32")) { @@ -6717,7 +6714,8 @@ fn trans_main_fn(@local_ctxt cx, ValueRef llcrate) { llvm.LLVMAppendBasicBlock(llmain, _str.buf("")); auto b = new_builder(llbb); - auto start_args = vec(p2i(llrust_main), p2i(llcrate), llargc, llargv); + auto start_args = vec(p2i(llrust_main), p2i(llcrate), llargc, llargv, + p2i(crate_map)); b.Ret(b.Call(llrust_start, start_args)); } @@ -7200,12 +7198,15 @@ fn make_common_glue(str output, bool optimize, llvm.LLVMSetTarget(llmod, _str.buf(x86.get_target_triple())); auto td = mk_target_data(x86.get_data_layout()); auto tn = mk_type_names(); + let ValueRef crate_ptr = + llvm.LLVMAddGlobal(llmod, T_crate(tn), _str.buf("rust_crate")); auto intrinsics = declare_intrinsics(llmod); llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm())); auto glues = make_glues(llmod, tn); + create_crate_constant(crate_ptr, glues); make_memcpy_glue(glues.memcpy_glue); make_bzero_glue(glues.bzero_glue); @@ -7326,8 +7327,7 @@ fn trans_crate(session.session sess, @ast.crate crate, trans_vec_append_glue(cx); auto crate_map = create_crate_map(ccx); if (!shared) { - trans_main_fn(cx, crate_ptr); - create_crate_constant(crate_ptr, ccx.glues, crate_map); + trans_main_fn(cx, crate_ptr, crate_map); } // Translate the metadata. diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 013705f26c268d9fa4345360f6e71d1ab185d7cf..6a42173636ebe2569ea47a92efa5264c237f3f70 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -78,9 +78,11 @@ command_line_args : public dom_owned extern "C" CDECL int rust_start(uintptr_t main_fn, rust_crate const *crate, int argc, - char **argv) { + char **argv, void* crate_map) { - crate->update_log_settings(getenv("RUST_LOG")); + // Only when we're on rustc is the last argument passed + if (!crate->get_image_base()) + update_log_settings(crate_map, getenv("RUST_LOG")); rust_srv *srv = new rust_srv(); rust_kernel *kernel = new rust_kernel(srv); kernel->start(); diff --git a/src/rt/rust_crate.cpp b/src/rt/rust_crate.cpp index e7ee0350468b343b7032323acdf7354f47d377cd..23f01c0747fa7cf9288e702640dae77e8313fb4b 100644 --- a/src/rt/rust_crate.cpp +++ b/src/rt/rust_crate.cpp @@ -65,92 +65,6 @@ 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 695fc21d98e76e7ea8e75fb149cc7d4084449623..4a1f3e458b351f9e8b63e915eefd9b43782af81e 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -248,9 +248,6 @@ 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. @@ -262,8 +259,6 @@ 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 076c4b0ae7a0edba2ebc783d3c9fea0ae3a70431..8f074cdf3cb3578b312b2b674cc77546ca91cfa5 100644 --- a/src/rt/rust_log.cpp +++ b/src/rt/rust_log.cpp @@ -218,3 +218,86 @@ void rust_log::reset_indent(uint32_t indent) { _indent = indent; } + +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; + +// 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. +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 update_log_settings(void* crate_map, char* settings) { + 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); +} diff --git a/src/rt/rust_log.h b/src/rt/rust_log.h index 3b40869b71c721697202e48b410fcca7f2d9d172..150d239a74d1317c87451ac4f30170910b9de368 100644 --- a/src/rt/rust_log.h +++ b/src/rt/rust_log.h @@ -93,4 +93,6 @@ rust_log::is_tracing(uint32_t type_bits) { return type_bits & _type_bit_mask; } +void update_log_settings(void* crate_map, char* settings); + #endif /* RUST_LOG_H */