91 lines
2.7 KiB
Diff
91 lines
2.7 KiB
Diff
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
|
|
|