Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions components/lwp/arch/risc-v/rv64/lwp_gcc.S
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ arch_ret_to_user_impl:
// TODO: we don't support kernel gdb server in risc-v yet
// so we don't check debug state here and handle debugging bussiness

/* Signal handling takes sleeping locks and must remain schedulable. */
OPEN_INTERRUPT
call lwp_check_exit_request
beqz a0, 1f
mv a0, x0
Expand All @@ -121,6 +123,7 @@ arch_ret_to_user_impl:
call lwp_thread_signal_catch

ret_to_user_exit:
CLOSE_INTERRUPT
RESTORE_ALL
// `RESTORE_ALL` also reset sp to user sp, and setup sscratch
sret
Expand All @@ -130,8 +133,10 @@ ret_to_user_exit:
* And handle pending signals;
*/
arch_signal_quit:
OPEN_INTERRUPT
LOAD a0, FRAME_OFF_SP(sp)
call arch_signal_ucontext_restore
CLOSE_INTERRUPT

/* reset kernel sp to the stack */
addi sp, sp, CTX_REG_NR * REGBYTES
Expand Down Expand Up @@ -167,6 +172,7 @@ arch_thread_signal_enter:
LOAD t0, FRAME_OFF_SP(a2)
mv a3, t0
call arch_signal_ucontext_save
CLOSE_INTERRUPT

/** restore kernel sp */
addi sp, s3, CTX_REG_NR * REGBYTES
Expand Down
35 changes: 32 additions & 3 deletions components/lwp/lwp_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,31 @@ static int elf_zero_bss(struct rt_lwp *lwp, int fd, const Elf_Phdr *phdr, rt_uba
return RT_EOK;
}

/**
* @brief Derive the memory protection flags from an ELF segment's p_flags.
*
* @param p_flags ELF program header flags (PF_R, PF_W, PF_X).
*
* @return Protection flags suitable for elf_map().
*/
static size_t elf_prot_from_pflags(uint32_t p_flags)
{
size_t prot = PROT_NONE;
if (p_flags & PF_R)
{
prot |= PROT_READ;
}
if (p_flags & PF_W)
{
prot |= PROT_WRITE;
}
if (p_flags & PF_X)
{
prot |= PROT_EXEC;
}
return prot;
}

Comment on lines +609 to +626

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个在后续的:

rt_inline rt_size_t lwp_user_mm_attr_to_kernel(int prot)
{
RT_UNUSED(prot);
rt_size_t k_attr = 0;
#ifdef LWP_USING_MPROTECT
if ((prot & PROT_EXEC) || (prot & PROT_WRITE) ||
((prot & PROT_READ) && (prot & PROT_WRITE)))
k_attr = MMU_MAP_U_RWCB;
else if (prot == PROT_NONE)
k_attr = MMU_MAP_K_RWCB;
else
k_attr = MMU_MAP_U_ROCB;
#else /* !LWP_USING_MPROTECT */
k_attr = MMU_MAP_U_RWCB;
#endif /* LWP_USING_MPROTECT */
return k_attr;
}

不开启 LWP_USING_MPROTECT 会默认设置为 MMU_MAP_U_RWCB,此处是否需要添加 LWP_USING_MPROTECT 控制比较好一些

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

并且原本 elf_file_mmap 的注释放到了elf_prot_from_pflags 前面了

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的 prot 只有在开启 LWP_USING_MPROTECT 时才真正生效:lwp_user_mm_attr_to_kernel() 在未开启 MPROTECT 时(lwp_user_mm.h 的 #else 分支)会忽略入参并统一返回 MMU_MAP_U_RWCB,所以映射行为和修改前完全一致,这里不需要再额外加 #ifdef 控制。

已在 commit 7fae086 的调用点补充注释说明这一点,避免后续读者误以为未开启 MPROTECT 时会被映射成只读/可执行。

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修正(commit 7fae086):把 elf_prot_from_pflags() 移到 elf_file_mmap() 的 kernel-doc 注释之前,并给这个 helper 单独补了简短注释,elf_file_mmap() 的文档重新紧挨着函数。

/**
* @brief Map ELF segments into memory.
*
Expand Down Expand Up @@ -626,7 +651,6 @@ static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ub
const Elf_Phdr *tmp_phdr = phdr; /* Current program header */
int fd = elf_info->fd; /* File descriptor for ELF file */
rt_ubase_t load_addr; /* Calculated load address */
size_t prot = PROT_READ | PROT_WRITE; /* Memory protection flags */
size_t flags = MAP_FIXED | MAP_PRIVATE; /* Memory mapping flags */

/* Iterate through all program headers */
Expand Down Expand Up @@ -659,8 +683,13 @@ static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ub
flags &= ~MAP_FIXED;
}

/* Map the segment into memory */
map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, prot, flags, map_size);
/*
* Map the segment with the permissions described by p_flags. When
* LWP_USING_MPROTECT is disabled, lwp_user_mm_attr_to_kernel() ignores
* the protection and always maps the segment as MMU_MAP_U_RWCB, so
* this behaves exactly as before until MPROTECT is enabled.
*/
map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, elf_prot_from_pflags(tmp_phdr->p_flags), flags, map_size);
if (!map_va)
{
LOG_E("%s : elf_map failed", __func__);
Expand Down
5 changes: 3 additions & 2 deletions components/lwp/lwp_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,10 @@ static void sigqueue_enqueue(lwp_sigqueue_t sigqueue, lwp_siginfo_t siginfo)
rt_bool_t inserted = RT_FALSE;
rt_list_for_each_entry(idx, &sigqueue->siginfo_list, node)
{
if (idx->ksiginfo.signo >= siginfo->ksiginfo.signo)
/* Keep ascending signal order and FIFO order for equal signals. */
if (idx->ksiginfo.signo > siginfo->ksiginfo.signo)
{
rt_list_insert_after(&idx->node, &siginfo->node);
rt_list_insert_before(&idx->node, &siginfo->node);
inserted = RT_TRUE;
break;
}
Expand Down
Loading