diff --git a/include/compartment.h b/include/compartment.h index 4846eef..f94466e 100644 --- a/include/compartment.h +++ b/include/compartment.h @@ -147,8 +147,6 @@ struct LibDependency void *tls_sec_addr; size_t tls_sec_size; size_t tls_data_size; - unsigned short tls_vars_count; - unsigned int tls_vars_idx_start; }; /** diff --git a/src/compartment.c b/src/compartment.c index fcdd110..e632f57 100644 --- a/src/compartment.c +++ b/src/compartment.c @@ -223,6 +223,7 @@ comp_map(struct Compartment *to_map) err(1, "Error mapping compartment %zu scratch memory", to_map->id); } + size_t tls_allocd = 0x0; for (size_t i = 0; i < to_map->libs_count; ++i) { // Bind `.got.plt` entries @@ -237,14 +238,15 @@ comp_map(struct Compartment *to_map) &to_map->libs[i]->rela_maps[j].target_func_address, sizeof(void *)); } + // Map .tdata sections if (to_map->libs[i]->tls_data_size != 0) { assert(to_map->libs[i]->tls_sec_addr); // TODO why sizeof(void*) ? - memcpy((char *) to_map->libs_tls_sects->region_start - + sizeof(void *) * to_map->libs[i]->tls_vars_idx_start, + memcpy((char *) to_map->libs_tls_sects->region_start + tls_allocd, to_map->libs[i]->tls_sec_addr, to_map->libs[i]->tls_data_size); + tls_allocd += to_map->libs[i]->tls_sec_size; } } @@ -441,8 +443,6 @@ parse_lib_file(char *lib_name, struct Compartment *new_comp) new_lib->tls_sec_addr = 0x0; new_lib->tls_sec_size = 0; new_lib->tls_data_size = 0; - new_lib->tls_vars_count = 0; - new_lib->tls_vars_idx_start = 0; parse_lib_segs(&lib_ehdr, lib_fd, new_lib, new_comp); @@ -548,8 +548,6 @@ parse_lib_segs(Elf64_Ehdr *lib_ehdr, int lib_fd, struct LibDependency *lib_dep, } lib_dep->tls_sec_addr = (void *) lib_phdr.p_vaddr; lib_dep->tls_sec_size = lib_phdr.p_memsz; - // TODO check - lib_dep->tls_vars_count = lib_phdr.p_memsz / lib_phdr.p_align; } if (lib_phdr.p_type != PT_LOAD) @@ -877,14 +875,22 @@ static void resolve_rela_syms(struct Compartment *new_comp) { // Find all symbols for eager relocation mapping + size_t prev_tls_secs_size = 0; for (size_t i = 0; i < new_comp->libs_count; ++i) { for (size_t j = 0; j < new_comp->libs[i]->rela_maps_count; ++j) { struct LibRelaMapping *curr_rela_map = &new_comp->libs[i]->rela_maps[j]; - if (curr_rela_map->target_func_address != 0 - || curr_rela_map->rela_sym_type == STT_TLS) + + if (curr_rela_map->rela_sym_type == STT_TLS) + { + curr_rela_map->target_func_address = (char*) + curr_rela_map->target_func_address + prev_tls_secs_size; + continue; + } + + if (curr_rela_map->target_func_address != 0) { continue; } @@ -921,6 +927,7 @@ resolve_rela_syms(struct Compartment *new_comp) curr_rela_map->target_func_address = extract_sym_offset(new_comp, found_sym); } + prev_tls_secs_size += new_comp->libs[i]->tls_sec_size; } } @@ -968,9 +975,7 @@ find_lib_dep_sym_in_comp(const char *to_find, cond = cond && comp_to_search->libs[i]->lib_syms[j].sym_type == sym_type; - // Symbols of type `TLS` could have valid 0-offset values; but - // other symbols cannot - basically a pseudo-check that this is a - // valid, defined symbol to relocate against + // Symbols cannot have 0-offset values if (sym_type != STT_TLS) { cond = cond @@ -1068,7 +1073,6 @@ resolve_comp_tls_regions(struct Compartment *new_comp) unsigned short *lib_idxs = malloc(new_comp->libs_count * sizeof(unsigned short)); unsigned short actual_idxs = 0; - size_t tls_vars = 0; size_t comp_tls_size = 0; for (size_t i = 0; i < new_comp->libs_count; ++i) { @@ -1079,9 +1083,6 @@ resolve_comp_tls_regions(struct Compartment *new_comp) comp_tls_size += new_comp->libs[i]->tls_sec_size; new_comp->libs_tls_sects->libs_count += 1; - new_comp->libs[i]->tls_vars_idx_start = tls_vars; - tls_vars += new_comp->libs[i]->tls_vars_count; - lib_idxs[actual_idxs] = i; actual_idxs += 1; } diff --git a/tests/simple_thrloc_var-external.c b/tests/simple_thrloc_var-external.c index 7957b95..fc4dba9 100644 --- a/tests/simple_thrloc_var-external.c +++ b/tests/simple_thrloc_var-external.c @@ -3,6 +3,7 @@ _Thread_local int ex_val; _Thread_local int ex_val_used; _Thread_local static int ex_val_stat = 242; +_Thread_local int from_int; int get_ext() @@ -23,3 +24,10 @@ use_val() ex_val_used = 24; assert(ex_val_used == 24); } + +void +do_ext_check(int val) +{ + from_int = val; + assert(from_int == ex_val_stat); +} diff --git a/tests/simple_thrloc_var.c b/tests/simple_thrloc_var.c index db5cc51..0b1dbcc 100644 --- a/tests/simple_thrloc_var.c +++ b/tests/simple_thrloc_var.c @@ -4,9 +4,13 @@ _Thread_local int val; _Thread_local static int val2 = 4242; _Thread_local static int val3 = INT_MAX; +_Thread_local static long val4 = LONG_MAX; +_Thread_local long val5; -int -get_ext(); +int get_ext(); +int get_ext_stat(); +void use_val(); +void do_ext_check(int); int do_val2() @@ -22,7 +26,17 @@ main(void) int i = do_val2(); assert(val == 42); assert(i == 4242); - val = val3; + assert(val3 == INT_MAX); + long v4_local = val4; + assert(v4_local == LONG_MAX); + val5 = 21; + assert(val5 * 2 == val); + + // Check external library functions assert(get_ext() == 420); + assert(get_ext_stat() == 242); + do_ext_check(242); + use_val(); + return 0; }