提交 a60b9e06 编写于 作者: S Szabolcs Nagy 提交者: Rich Felker

fix tls offsets when p_vaddr%p_align != 0 on TLS_ABOVE_TP targets

currently the bfd linker does not seem to create tls segments where
p_vaddr%p_align != 0, but this is valid in ELF and then the runtime
computed tls offset must satisfy

  offset%p_align == (base+p_vaddr)%p_align

and in case of local exec tls (main executable) the smallest such
offset must be used (otherwise it is incompatible with the offset
computed by the static linker). the !TLS_ABOVE_TP case is handled
correctly (the offset is negative then in the formula).

the ldso code for TLS_ABOVE_TP is changed so the static tls offset
of each module satisfies the formula.
上级 6104dae9
......@@ -1125,8 +1125,8 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
p->tls_id = ++tls_cnt;
tls_align = MAXP2(tls_align, p->tls.align);
#ifdef TLS_ABOVE_TP
p->tls.offset = tls_offset + ( (tls_align-1) &
-(tls_offset + (uintptr_t)p->tls.image) );
p->tls.offset = tls_offset + ( (p->tls.align-1) &
(-tls_offset + (uintptr_t)p->tls.image) );
tls_offset = p->tls.offset + p->tls.size;
#else
tls_offset += p->tls.size + p->tls.align - 1;
......@@ -1796,7 +1796,8 @@ _Noreturn void __dls3(size_t *sp)
app.tls_id = tls_cnt = 1;
#ifdef TLS_ABOVE_TP
app.tls.offset = GAP_ABOVE_TP;
app.tls.offset += -GAP_ABOVE_TP & (app.tls.align-1);
app.tls.offset += (-GAP_ABOVE_TP + (uintptr_t)app.tls.image)
& (app.tls.align-1);
tls_offset = app.tls.offset + app.tls.size;
#else
tls_offset = app.tls.offset = app.tls.size
......
......@@ -115,7 +115,8 @@ static void static_init_tls(size_t *aux)
& (main_tls.align-1);
#ifdef TLS_ABOVE_TP
main_tls.offset = GAP_ABOVE_TP;
main_tls.offset += -GAP_ABOVE_TP & (main_tls.align-1);
main_tls.offset += (-GAP_ABOVE_TP + (uintptr_t)main_tls.image)
& (main_tls.align-1);
#else
main_tls.offset = main_tls.size;
#endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册