This patch extends the interface of the dynamic linker with the ability
to replace the running binary executable by another one. It is
designated for the implementation of execve. The interface consists of
two new functions.
'Dynamic_linker::keep' marks the specified shared object as unloadable.
This can be used to pin a set of libraries (i.e., the libc) within the
local address space while replacing the binary and other higher-level
libraries.
'Dynamic_linker::respawn' unloads the current binary, loads the one
specifed as first argument, and looks up the entry point symbol of the
new binary, which would be "main" for POSIX programs.
In addition to implementing the new interface, the patch adjusts the
linker at various places that previously assumed the binary to be
constant over runtime.
Issue #3481
This patch is a follow-up commit for "ld: load dynamic linker at static
address on Linux". It suppresses the stderr output of 'dd' when marking
the ELF binary as executable.
Issue #3479
This patch enhances the 'base/shared_object.h' interface of the dynamic
linker with the function 'for_each_loaded_object', which allows the
caller to obtain information about the currently loaded binary and
shared libraries.
The new interface is a base mechanism needed for implementing 'fork' in
the libc.
Issue #3478
This enforces the use of unsigned 64-bit values for time in the duration type,
the timeout framework, the timer session, the userland timer-drivers, and the
alarm framework on all platforms. The commit also adapts the code that uses
these tools accross all basic repositories (base, base-*, os. gems, libports,
ports, dde_*) to use unsigned 64-bit values for time as well as far as this
does not imply profound modifications.
Fixes#3208
Track the dataspaces used by attach and add handling of flushing VM space
when dataspace gets destroyed (not triggered via the vm_session interface).
Issue #3111
This patch adds the items necessary for building Genode components with
stack protection enabled, but it is not initialized at runtime. They are
provided at the moment as a convenience and do not implement a security
feature.
Fix#3066
This patch adjusts the implementation of the base library and core such
that the code no longer relies on deprecated APIs except for very few
cases, mainly to keep those deprecated APIs in tact for now.
The most prominent changes are:
- Removing the use of base/printf.h
- Removing of the log backend for printf. The 'Console' with the
format-string parser is still there along with 'snprintf.h' because
the latter is still used at a few places, most prominently the
'Connection' classes.
- Removing the notion of a RAM session, which does not exist in
Genode anymore. Still the types were preserved (by typedefs to
PD session) to keep up compatibility. But this transition should
come to an end now.
- Slight rennovation of core's tracing service, e.g., the use of an
Attached_dataspace as the Argument_buffer.
- Reducing the reliance on global accessors like deprecated_env() or
core_env(). Still there is a longish way to go to eliminate all such
calls. A useful pattern (or at least a stop-gap solution) is to
pass the 'Env' to the individual compilation units via init functions.
- Avoiding the use of the old 'Child_policy::resolve_session_request'
interface that returned a 'Service' instead of a 'Route'.
Issue #1987
The notion of a RAM session does not exist anymore. Hence, we have to
adjust the name of 'init_env_ram_session'. Since this change modifies
the ABI, it comes as separate commit.
Issue #2407
- support to create multiple vCPUs
- support to implement Vm_session methods client side within base library
- adjust muen specific virtualbox4 version to compile/link
Issue #3111
The former 'Genode::Timed_semaphore' mechanism is moved to the private
part of the two remaining users, namely dde_rump and the libc. Note
there are now two private copies of 'timed_semaphore.h'. This should be
regarded as an interim step until the use of this mechanism is removed
from both users.
This patch also cleans up the mechanism from legacy Genode API calls and
global side effects (alarm-thread singleton). The test/timed_semaphore
is now located at the libports repository as it now tests a mechanism of
the libc. The former timed_semaphore library is no more.
Fixes#3121
Since the timer and timeout handling is part of the base library (the
dynamic linker), it belongs to the base repository.
Besides moving the timer and its related infrastructure (alarm, timeout
libs, tests) to the base repository, this patch also moves the timer
from the 'drivers' subdirectory directly to 'src' and disamibuates the
timer's build locations for the various kernels. Otherwise the different
timer implementations could interfere with each other when using one
build directory with multiple kernels.
Note that this patch changes the include paths for the former os/timer,
os/alarm.h, os/duration.h, and os/timed_semaphore.h to base/.
Issue #3101
Integrate the code of the Alarm framework directly into the Timeout
framework. The former Alarm-framework methods are all private to the
corresponding classes of the Timeout framework and get prefixed with
'_alarm__'. The latter avoids name clashes and makes it easier to
simplify the code later.
Issue #2704
With this patch, init responds to the exit of a child by closing all
sessions of the child. E.g., if a child is a GUI application, its
nitpicker session is closed at the time of exit, not at the time when
the start node disappears from init's configuration.
Since this change requires a modification of the 'Genode::Child' class,
it takes the chance to make the child-destruction less brutal. The
new version ensures that all threads of the destructed subsystem are
destructed before other sessions, in particular PD sessions. This
eliminates spurious page-fault warnings during the child destruction.
On Fiasco.OC, closing the CPU session of a thread while being called by
the thread causes a deadlock. Hence, we skip the eager destruction of
CPU sessions on this kernel.
Related to issue #2659
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
Ensure that the timer does not handle timeouts again within 1000
microseconds after the last handling of timeouts. This makes denial of
service attacks harder. This commit does not limit the rate of timeout
signals handled inside the timer but it causes the timer to do it less
often. If a client continuously installs a very small timeout at the
timer it still causes a signal to be submitted to the timer each time
and some extra CPU time to be spent in the internal handling method. But
only every 1000 microseconds this internal handling causes user timeouts
to trigger.
If we would want to limit also the call of the internal handling method
to ensure that CPU time is spent beside the RPCs only every 1000
microseconds, things would get more complex. For instance, on NOVA
Time_source::schedule_timeout(0) must be called each time a new timeout
gets installed and becomes head of the scheduling queue. We cannot
simply overwrite the already running timeout with the new one.
Ref #2490
We moved the stack-area segment 128 MiB behind text and data to comply
with assumptions in the kernel ELF loader.
This commit also reenables static binaries on linux and removes the
unused stack_area.stdlib.ld script.
Fixes#2521
The 'Stack_area_ram_session' is now a 'Stack_area_ram_allocator', which
simplifies the code and remove a dependency from the 'Ram_session'
interface, which we want to remove after all.
Issue #2407
This patch allows core's 'Signal_transmitter' implementation to sidestep
the 'Env::Pd' interface and thereby adhere to a stricter layering within
core. The 'Signal_transmitter' now uses - on kernels that depend on it -
a dedicated (and fairly freestanding) RPC proxy mechanism for signal
deliver, instead of channeling signals through the 'Pd_session::submit'
RPC function.
Previously, the Genode::Timer::curr_time always used the
Timer_session::elapsed_ms RPC as back end. Now, Genode::Timer reads
this remote time only in a periodic fashion independently from the calls
to Genode::Timer::curr_time. If now one calls Genode::Timer::curr_time,
the function takes the last read remote time value and adapts it using
the timestamp difference since the remote-time read. The conversion
factor from timestamps to time is estimated on every remote-time read
using the last read remote-time value and the timestamp difference since
the last remote time read.
This commit also re-works the timeout test. The test now has two stages.
In the first stage, it tests fast polling of the
Genode::Timer::curr_time. This stage checks the error between locally
interpolated and timer-driver time as well as wether the locally
interpolated time is monotone and sufficiently homogeneous. In the
second stage several periodic and one-shot timeouts are scheduled at
once. This stage checks if the timeouts trigger sufficiently precise.
This commit adds the new Kernel::time syscall to base-hw. The syscall is
solely used by the Genode::Timer on base-hw as substitute for the
timestamp. This is because on ARM, the timestamp function uses the ARM
performance counter that stops counting when the WFI (wait for
interrupt) instruction is active. This instruction, however is used by
the base-hw idle contexts that get active when no user thread needs to
be scheduled. Thus, the ARM performance counter is not a good choice for
time interpolation and we use the kernel internal time instead.
With this commit, the timeout library becomes a basic library. That means
that it is linked against the LDSO which then provides it to the program it
serves. Furthermore, you can't use the timeout library anymore without the
LDSO because through the kernel-dependent LDSO make-files we can achieve a
kernel-dependent timeout implementation.
This commit introduces a structured Duration type that shall successively
replace the use of Microseconds, Milliseconds, and integer types for duration
values.
Open issues:
* The timeout test fails on Raspberry PI because of precision errors in the
first stage. However, this does not render the framework unusable in general
on the RPI but merely is an issue when speaking of microseconds precision.
* If we run on ARM with another Kernel than HW the timestamp speed may
continuously vary from almost 0 up to CPU speed. The Timer, however,
only uses interpolation if the timestamp speed remained stable (12.5%
tolerance) for at least 3 observation periods. Currently, one period is
100ms, so its 300ms. As long as this is not the case,
Timer_session::elapsed_ms is called instead.
Anyway, it might happen that the CPU load was stable for some time so
interpolation becomes active and now the timestamp speed drops. In the
worst case, we would now have 100ms of slowed down time. The bad thing
about it would be, that this also affects the timeout of the period.
Thus, it might "freeze" the local time for more than 100ms.
On the other hand, if the timestamp speed suddenly raises after some
stable time, interpolated time can get too fast. This would shorten the
period but nonetheless may result in drifting away into the far future.
Now we would have the problem that we can't deliver the real time
anymore until it has caught up because the output of Timer::curr_time
shall be monotone. So, effectively local time might "freeze" again for
more than 100ms.
It would be a solution to not use the Trace::timestamp on ARM w/o HW but
a function whose return value causes the Timer to never use
interpolation because of its stability policy.
Fixes#2400
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes#2398
The 'Ram_allocator' interface contains the subset of the RAM session
interface that is needed to satisfy the needs of the 'Heap' and
'Sliced_heap'. Its small size makes it ideal for intercepting memory
allocations as done by the new 'Constrained_ram_allocator' wrapper
class, which is meant to replace the existing 'base/allocator_guard.h'
and 'os/ram_session_guard.h'.
Issue #2398
This patch enhances the 'Child' and 'Child_policy' with the ability to
separate the different steps of bootstrapping children. If the
'Child_policy::initiate_env_sessions()' returns false, the child's
environment sessions remain unrouted at construction time. This way,
child objects for many children can be initialized to a state that
allows the children to represent services for other children. Therefore,
session routing can be applied before any child executes.
At this stage, the environment RAM sessions of all children can be
created. Note that this step still has the limitation that RAM sessions
are generally expected to be provided by either the parent or a local
service.
Once all children are equipped with RAM, they can in principle receive
session-quota donations. Hence, all other environment sessions can now
be arbitrarily routed and initiated.
Once the environment of a child is complete, the child's process and
initial thread is created.
This method is a hook to enable a runtime to respond to state changes.
In particular, in init this hook is used to trigger the generation of a
new state report, if configured.
Furthermore, the patch introduces the 'generate_client_side_info' and
'generate_server_side_info' methods to the 'Session_state', which
generates an XML representation of the session states to appear in
reports produced by init.
Issue #2246
The new return value of 'resolve_session_request' allows the child
policy to define the label used as the policy selector at the server.
Because this patch introduces the distinction of the child-provided
label from the label as presented to the server along with the session
request, the latter is now handled as a dedicated 'Session_state'
argument.
Issue #2248
There existed a race when 'wait_and_dispatch_one_signal' is called form
a RPC context, because the 'signal_proxy' or 'main' will block and the
signal semaphore, when the EP then calls 'wait_and_dispatch_one_signal',
the signal proxy is woken up ands sends an RPC to the EP, leading to a
dead lock if no further signal arrive, because the EP will then remain
blocked in the signal semaphore.
Therefore, for this case, the signal proxy will now perform a semaphore
up operation and does not perform an RPC if the EP is within
'wait_and_dispatch_one_signal'.
This patch enables warnings if one of the deprecate functions that rely
in the implicit use of the global Genode::env() accessor are called.
For the time being, some places within the base framework continue
to rely on the global function while omitting the warning by calling
'env_deprecated' instead of 'env'.
Issue #1987
This patch make the ABI mechanism available to shared libraries other
than Genode's dynamic linker. It thereby allows us to introduce
intermediate ABIs at the granularity of shared libraries. This is useful
for slow-moving ABIs such as the libc's interface but it will also
become handy for the package management.
To implement the feature, the build system had to be streamlined a bit.
In particular, archive dependencies and shared-lib dependencies are now
handled separately, and the global list of 'SHARED_LIBS' is no more.
Now, the variable with the same name holds the per-target list of shared
libraries used by the target.