summaryrefslogtreecommitdiff
path: root/rts/linker/Elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/linker/Elf.c')
-rw-r--r--rts/linker/Elf.c28
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 )