kernel: tls: align tdata/tbss sections in stack

This lets the linker tell us what kind of alignment is required
for both tdata and tbss data when copying them into stack.
If they are not aligned as expected by the toolchain, generated
code would be accessing incorrect location for thread variables.

Fixes #32015

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2021-02-04 20:05:45 -08:00 committed by Anas Nashif
parent e61dbe59b0
commit 371752bce3
3 changed files with 9 additions and 2 deletions

View file

@ -309,9 +309,11 @@ extern char z_kobject_data_begin[];
extern char __tdata_start[];
extern char __tdata_end[];
extern char __tdata_size[];
extern char __tdata_align[];
extern char __tbss_start[];
extern char __tbss_end[];
extern char __tbss_size[];
extern char __tbss_align[];
extern char __tls_start[];
extern char __tls_end[];
extern char __tls_size[];

View file

@ -21,10 +21,12 @@
PROVIDE(__tdata_start = LOADADDR(tdata));
PROVIDE(__tdata_size = SIZEOF(tdata));
PROVIDE(__tdata_end = __tdata_start + __tdata_size);
PROVIDE(__tdata_align = ALIGNOF(tdata));
PROVIDE(__tbss_start = LOADADDR(tbss));
PROVIDE(__tbss_size = SIZEOF(tbss));
PROVIDE(__tbss_end = __tbss_start + __tbss_size);
PROVIDE(__tbss_align = ALIGNOF(tbss));
PROVIDE(__tls_start = __tdata_start);
PROVIDE(__tls_end = __tbss_end);

View file

@ -28,7 +28,10 @@
*/
static inline size_t z_tls_data_size(void)
{
return (size_t)__tls_size;
size_t tdata_size = ROUND_UP(__tdata_size, __tdata_align);
size_t tbss_size = ROUND_UP(__tbss_size, __tbss_align);
return tdata_size + tbss_size;
}
/**
@ -48,7 +51,7 @@ static inline void z_tls_copy(char *dest)
memcpy(dest, __tdata_start, tdata_size);
/* Clear BSS data (tbss) */
dest += tdata_size;
dest += ROUND_UP(tdata_size, __tdata_align);
memset(dest, 0, tbss_size);
}