base-common: copy all sparse ELF segments, including read-only
This commit is contained in:
parent
5e87eee9b8
commit
d348e96b84
|
@ -68,9 +68,11 @@ Child::Process::Loaded_executable::Loaded_executable(Type type,
|
|||
bool const write = seg.flags().w;
|
||||
bool const exec = seg.flags().x;
|
||||
|
||||
if (write) {
|
||||
Dataspace_capability ds_cap = ldso_ds;
|
||||
off_t offset = 0;
|
||||
|
||||
/* read-write segment */
|
||||
if (write || seg.file_size() < seg.mem_size()) {
|
||||
/* segment must be copied */
|
||||
|
||||
/*
|
||||
* Note that a failure to allocate a RAM dataspace after other
|
||||
|
@ -83,10 +85,9 @@ Child::Process::Loaded_executable::Loaded_executable(Type type,
|
|||
*/
|
||||
|
||||
/* alloc dataspace */
|
||||
Dataspace_capability ds_cap;
|
||||
try { ds_cap = ram.alloc(size); }
|
||||
catch (Out_of_ram) {
|
||||
error("allocation of read-write segment failed"); throw; };
|
||||
error("allocation of ELF segment failed"); throw; };
|
||||
|
||||
/* attach dataspace */
|
||||
void *base;
|
||||
|
@ -117,26 +118,32 @@ Child::Process::Loaded_executable::Loaded_executable(Type type,
|
|||
/* detach dataspace */
|
||||
local_rm.detach(base);
|
||||
|
||||
off_t const offset = 0;
|
||||
try { remote_rm.attach_at(ds_cap, addr, size, offset); }
|
||||
try {
|
||||
if (exec)
|
||||
remote_rm.attach_executable(ds_cap, addr, size, offset);
|
||||
else
|
||||
remote_rm.attach_at(ds_cap, addr, size, offset);
|
||||
}
|
||||
catch (Region_map::Region_conflict) {
|
||||
error("region conflict while remotely attaching ELF segment");
|
||||
error("addr=", (void *)addr, " size=", (void *)size, " offset=", (void *)offset);
|
||||
throw; }
|
||||
|
||||
} else {
|
||||
|
||||
/* read-only segment */
|
||||
offset = seg.file_offset();
|
||||
|
||||
if (seg.file_size() != seg.mem_size())
|
||||
warning("filesz and memsz for read-only segment differ");
|
||||
if (!ds_cap.valid())
|
||||
Genode::error("segment dataspace is not valid");
|
||||
|
||||
if (!Dataspace_client(ds_cap).size())
|
||||
Genode::error("segment dataspace is zero sized");
|
||||
|
||||
off_t const offset = seg.file_offset();
|
||||
try {
|
||||
if (exec)
|
||||
remote_rm.attach_executable(ldso_ds, addr, size, offset);
|
||||
remote_rm.attach_executable(ds_cap, addr, size, offset);
|
||||
else
|
||||
remote_rm.attach_at(ldso_ds, addr, size, offset);
|
||||
remote_rm.attach_at(ds_cap, addr, size, offset);
|
||||
}
|
||||
catch (Region_map::Region_conflict) {
|
||||
error("region conflict while remotely attaching read-only ELF segment");
|
||||
|
|
Loading…
Reference in New Issue