Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
* Fix incorrenctly handling TLS offsets for subsequent libraries; now
  correctly relocating indices relative to the TLS region
* Improve TLS example even more
* A bit more cleanup
  • Loading branch information
0152la committed Jun 4, 2024
1 parent 2b6e65f commit f47b3c9
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 20 deletions.
2 changes: 0 additions & 2 deletions include/compartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/**
Expand Down
31 changes: 16 additions & 15 deletions src/compartment.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
}
Expand Down
8 changes: 8 additions & 0 deletions tests/simple_thrloc_var-external.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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);
}
20 changes: 17 additions & 3 deletions tests/simple_thrloc_var.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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;
}

0 comments on commit f47b3c9

Please sign in to comment.