From c1c5f4f852055bb0b72bd8981c6688a3b0f32b96 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 16 Nov 2020 00:38:21 +0100 Subject: [PATCH] genodeSources: patch ld to load read-only segments --- packages/genodelabs/default.nix | 6 +- packages/genodelabs/patches/ld-ro.patch | 90 +++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 packages/genodelabs/patches/ld-ro.patch diff --git a/packages/genodelabs/default.nix b/packages/genodelabs/default.nix index bab5b30..4f25f65 100644 --- a/packages/genodelabs/default.nix +++ b/packages/genodelabs/default.nix @@ -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 // { diff --git a/packages/genodelabs/patches/ld-ro.patch b/packages/genodelabs/patches/ld-ro.patch new file mode 100644 index 0000000..e5026ca --- /dev/null +++ b/packages/genodelabs/patches/ld-ro.patch @@ -0,0 +1,90 @@ +From 8c4bb7d84838e8c01673caa8ad45a4c042ccdd11 Mon Sep 17 00:00:00 2001 +From: Emery Hemingway +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( ++ [&] () { ++ 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 +