2
0
Fork 0

genodeSources: patch ld to load read-only segments

This commit is contained in:
Ehmry - 2020-11-16 00:38:21 +01:00
parent f74b789840
commit c1c5f4f852
2 changed files with 95 additions and 1 deletions

View File

@ -296,7 +296,11 @@ let
'';
};
basePatches = [ ./patches/cxx-align.patch ./patches/core-diag.patch ];
basePatches = [
./patches/cxx-align.patch
./patches/core-diag.patch
./patches/ld-ro.patch
];
in makePackages // depotPackages // {

View File

@ -0,0 +1,90 @@
From 8c4bb7d84838e8c01673caa8ad45a4c042ccdd11 Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Mon, 6 Apr 2020 16:32:13 +0530
Subject: [PATCH] ld: support for loading read-only segments
---
repos/base/src/lib/ldso/include/file.h | 24 ++++++++++++++++++--
repos/base/src/lib/ldso/include/region_map.h | 10 ++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/repos/base/src/lib/ldso/include/file.h b/repos/base/src/lib/ldso/include/file.h
index 1c9ce53ca3..6688f0edd2 100644
--- a/repos/base/src/lib/ldso/include/file.h
+++ b/repos/base/src/lib/ldso/include/file.h
@@ -34,6 +34,9 @@ namespace Linker {
static inline bool is_rw(Elf::Phdr const &ph) {
return ((ph.p_flags & PF_MASK) == (PF_R | PF_W)); }
+
+ static inline bool is_ro(Elf::Phdr const &ph) {
+ return ((ph.p_flags & PF_MASK) == PF_R); }
}
@@ -280,15 +283,21 @@ struct Linker::Elf_file : File
else if (is_rw(*ph))
load_segment_rw(*ph, i);
+ else if (is_ro(*ph))
+ load_segment_ro(*ph);
+
else {
- error("LD: Non-RW/RX segment");
+ auto X = ph->p_flags & PF_X ? "X" : "-";
+ auto W = ph->p_flags & PF_W ? "W" : "-";
+ auto R = ph->p_flags & PF_R ? "R" : "-";
+ error("LD: unhandled ", X,W,R, " segment at file offset ", Hex(ph->p_offset));
throw Invalid_file();
}
}
}
/**
- * Map read-only segment
+ * Map read-execute-only segment
*/
void load_segment_rx(Elf::Phdr const &p)
{
@@ -318,6 +327,17 @@ struct Linker::Elf_file : File
env.rm().detach(src);
}
+ /**
+ * Map read-only segment
+ */
+ void load_segment_ro(Elf::Phdr const &p)
+ {
+ Region_map::r()->attach_readonly(rom_cap,
+ trunc_page(p.p_vaddr) + reloc_base,
+ round_page(p.p_memsz),
+ trunc_page(p.p_offset));
+ }
+
/**
* Unmap segements, RM regions, and free allocated dataspaces
*/
diff --git a/repos/base/src/lib/ldso/include/region_map.h b/repos/base/src/lib/ldso/include/region_map.h
index cbee34c639..b30c2221da 100644
--- a/repos/base/src/lib/ldso/include/region_map.h
+++ b/repos/base/src/lib/ldso/include/region_map.h
@@ -122,6 +122,16 @@ class Linker::Region_map
[&] () { _env.upgrade(Parent::Env::pd(), "ram_quota=8K"); });
}
+ Local_addr attach_readonly(Dataspace_capability ds, addr_t local_addr,
+ size_t size = 0, off_t offset = 0)
+ {
+ return retry<Genode::Out_of_ram>(
+ [&] () {
+ return _rm.attach(ds, size, offset, true, local_addr - _base, false, false);
+ },
+ [&] () { _env.upgrade(Parent::Env::pd(), "ram_quota=8K"); });
+ }
+
void detach(Local_addr local_addr) { _rm.detach((addr_t)local_addr - _base); }
};
--
2.28.0