diff options
Diffstat (limited to 'rts/linker/Elf.c')
-rw-r--r-- | rts/linker/Elf.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/rts/linker/Elf.c b/rts/linker/Elf.c index 313666197b..3e19d3a2db 100644 --- a/rts/linker/Elf.c +++ b/rts/linker/Elf.c @@ -778,7 +778,9 @@ ocGetNames_ELF ( ObjectCode* oc ) // (i.e. we cannot map the secions separately), or if the section // size is small. else if (!oc->imageMapped || size < getPageSize() / 3) { - start = m32_alloc(oc->m32, size, 8); + bool executable = kind == SECTIONKIND_CODE_OR_RODATA; + m32_allocator *allocator = executable ? oc->rx_m32 : oc->rw_m32; + start = m32_alloc(allocator, size, 8); if (start == NULL) goto fail; memcpy(start, oc->image + offset, size); alloc = SECTION_M32; @@ -1769,6 +1771,28 @@ do_Elf_Rela_relocations ( ObjectCode* oc, char* ehdrC, #endif /* !aarch64_HOST_ARCH */ +static bool +ocMprotect_Elf( ObjectCode *oc ) +{ + for(int i=0; i < oc->n_sections; i++) { + Section *section = &oc->sections[i]; + if(section->size == 0) continue; + switch (section->kind) { + case SECTIONKIND_CODE_OR_RODATA: + if (section->alloc != SECTION_M32) { + // N.B. m32 handles protection of its allocations during + // flushing. + mmapForLinkerMarkExecutable(section->mapped_start, section->mapped_size); + } + break; + default: + break; + } + } + + return true; +} + int ocResolve_ELF ( ObjectCode* oc ) { @@ -1855,7 +1879,7 @@ ocResolve_ELF ( ObjectCode* oc ) ocFlushInstructionCache( oc ); #endif - return 1; + return ocMprotect_Elf(oc); } int ocRunInit_ELF( ObjectCode *oc ) |