fix: code in non-executable ELF sections
This commit is contained in:
parent
c85eface68
commit
e4d874d88a
4 changed files with 45 additions and 0 deletions
3
tccasm.c
3
tccasm.c
|
@ -893,6 +893,9 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||||
if (old_nb_section != s1->nb_sections)
|
if (old_nb_section != s1->nb_sections)
|
||||||
cur_text_section->sh_addralign = 1;
|
cur_text_section->sh_addralign = 1;
|
||||||
}
|
}
|
||||||
|
/* The section directive supports flags, but they are unsupported.
|
||||||
|
For now, just assume any section contains code. */
|
||||||
|
cur_text_section->sh_flags |= SHF_EXECINSTR;
|
||||||
break;
|
break;
|
||||||
case TOK_ASMDIR_previous:
|
case TOK_ASMDIR_previous:
|
||||||
{
|
{
|
||||||
|
|
1
tccgen.c
1
tccgen.c
|
@ -8303,6 +8303,7 @@ static void gen_function(Sym *sym)
|
||||||
cur_scope = root_scope = &f;
|
cur_scope = root_scope = &f;
|
||||||
nocode_wanted = 0;
|
nocode_wanted = 0;
|
||||||
|
|
||||||
|
cur_text_section->sh_flags |= SHF_EXECINSTR;
|
||||||
ind = cur_text_section->data_offset;
|
ind = cur_text_section->data_offset;
|
||||||
if (sym->a.aligned) {
|
if (sym->a.aligned) {
|
||||||
size_t newoff = section_add(cur_text_section, 0,
|
size_t newoff = section_add(cur_text_section, 0,
|
||||||
|
|
28
tests/exec_section_in_asm.c
Normal file
28
tests/exec_section_in_asm.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/* Previously in TinyCC, ELF sections defined in assembly would always have the
|
||||||
|
execute bit not set, so you would get segmentation faults when code in these
|
||||||
|
sections was exectuted. This file is a minimal example of a file that will put
|
||||||
|
the resulting code in a non-executable section (and invoke it) prior to the fix.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void *memset(void *dst, int c, int len);
|
||||||
|
|
||||||
|
__asm__ (
|
||||||
|
".section .text.nolibc_memset\n"
|
||||||
|
".weak memset\n"
|
||||||
|
"memset:\n"
|
||||||
|
"xchgl %eax, %esi\n\t"
|
||||||
|
"movq %rdx, %rcx\n\t"
|
||||||
|
"pushq %rdi\n\t"
|
||||||
|
"rep stosb\n\t"
|
||||||
|
"popq %rax\n\t"
|
||||||
|
"retq\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
char buf[10];
|
||||||
|
memset(&buf[0], 'A', 9);
|
||||||
|
buf[9] = 0;
|
||||||
|
puts(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
13
tests/exec_section_in_c.c
Normal file
13
tests/exec_section_in_c.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* Previously in TinyCC, ELF sections defined in attributes would always have
|
||||||
|
the execute bit not set, so you would get segmentation faults when code in these
|
||||||
|
sections was exectuted. This file is a minimal example of a file that will put
|
||||||
|
the resulting code in a non-executable section (and invoke it) prior to the fix.
|
||||||
|
*/
|
||||||
|
__attribute__((section(".text.wumbo")))
|
||||||
|
int wumbo (int arg) {
|
||||||
|
return arg * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
return wumbo(2);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue