This fixes#7942.
We can't unmap these methods because they can be called after the boot
process from lspci(8) utility, or by using the SystemMonitor program
(and looking into the "PCI devices" tab).
It's prone to finding "technically uninitialized but can never happen"
cases, particularly in Optional<T> and Variant<Ts...>.
The general case seems to be that it cannot infer the dependency
between Variant's index (or Optional's boolean state) and a particular
alternative (or Optional's buffer) being untouched.
So it can flag cases like this:
```c++
if (index == StaticIndexForF)
new (new_buffer) F(move(*bit_cast<F*>(old_buffer)));
```
The code in that branch can _technically_ make a partially initialized
`F`, but that path can never be taken since the buffer holding an
object of type `F` and the condition being true are correlated, and so
will never be taken _unless_ the buffer holds an object of type `F`.
This commit also removed the various 'diagnostic ignored' pragmas used
to work around this warning, as they no longer do anything.
We call it E1000E, because the layout for these cards is somewhat not
the same like E1000 supported cards.
Also, this card supports advanced features that are not supported on
8254x cards.
Instead of initializing network adapters in init.cpp, let's move that
logic into a separate class to handle this.
Also, it seems like a good idea to shift responsiblity on enumeration
of network adapters after the boot process, so this singleton will take
care of finding the appropriate network adapter when asked to with an
IPv4 address or interface name.
With this change being merged, we simplify the creation logic of
NetworkAdapter derived classes, so we enumerate the PCI bus only once,
searching for driver candidates when doing so, and we let each driver
to test if it is resposible for the specified PCI device.
When a process executes another program, its unveil state is reset. For
this, we not only need to clear all nodes from m_unveiled_paths, but
also reset the metadata of m_unveiled_paths (the root node) itself.
This fixes the following bug:
1) A process unveils "/", then executes another program.
2) That other program also unveils some path.
3) "/" is now unveiled for the new program.
If m_unveiled_paths.is_empty(), the root node (which is m_unveiled_paths
itself) is the matching veil. This means we should not return nullptr in
this case, but just use the code path for the general case.
This fixes a bug where calling e.g. unveil("/", "r") would refuse you
access to anything, because find_matching_unveiled_path would wrongly
return nullptr.
Since find_matching_unveiled_path can no longer return nullptr, we can
now just return a reference instead.
This also changes the UnveilState to Dropped when the path unveil() is
called for already has a node.
This fixes a bug where unveiling "/" would previously keep the
UnveilState as None, which meant that everything was still accessible
until unveil() was called with any non-root path (or nullptr).
When changing the unveil permissions of a preexisting node, we need to
make sure that any intermediate nodes that were created before and
should inherit permissions from the updated node are updated properly.
This fixes the following bug:
unveil("/home/anon/Documents", "r");
unveil("/home", "r");
Now there was a intermediate node for "/home/anon" which still had no
permission, even though it should have inherited the permissions from
"/home".
This fixes a bug where unveiling a subdirectory of an already unveiled
path would sometimes be allowed and sometimes not (depending on what
other unveil calls have been made).
Now, it is always allowed to unveil a subdirectory of an already
unveiled directory, even if it has higher permissions.
This removes the need for the permissions_inherited_from_root flag in
UnveilMetadata, so it has been removed.
There is logic at the end of the constructor that sets m_should_block
to false if we encountered errors. We were missing this step due to the
erroneous early return, the code then ended up waiting and then
asserting on unblock since the WaitBlocker is in a invalid state.
This fix is to not return early, and let normal control flow handle it.
Fixes: #7857
Verified with `stress-ng --yield=10` locally.
After marking a thread for death we might end up finalizing the thread
while it still has code to run, e.g. via:
Thread::block -> Thread::dispatch_one_pending_signal
-> Thread::dispatch_signal -> Process::terminate_due_to_signal
-> Process::die -> Process::kill_all_threads -> Thread::set_should_die
This marks the thread for death. It isn't destroyed at this point
though.
The scheduler then gets invoked via:
Thread::block -> Thread::relock_process
At that point we still have a registered blocker on the stack frame
which belongs to Thread::block. Thread::relock_process drops the
critical section which allows the scheduler to run.
When the thread is then scheduled out the scheduler sets the thread
state to Thread::Dying which allows the finalizer to destroy the Thread
object and its associated resources including the kernel stack.
This probably also affects objects other than blockers which rely
on their destructor to be run, however the problem was most noticible
because blockers are allocated on the stack of the dying thread and
cause an access violation when another thread touches the blocker
which belonged to the now-dead thread.
Fixes#7823.
When attempting to write to a socket that is not connected or - for
connection-less protocols - doesn't have a peer address set we should
return EPIPE instead of blocking the thread.
Previously, we would echo characters back just as they were passed to
us, even in canonical mode. This caused newlines to not work correctly
in some programs.
Fixes#7802
Previously, we converted colors to their RGB values immediately when
they were set. This meant that their semantic meaning was lost, we could
not tell a precise RGB value apart from a named/indexed color.
The new way of storing colors will allow us to retain this information,
so we can change a color scheme on the fly, and previously emitted text
will also be affected.
Previously we'd incur the costs for a function call via the PLT even
for the most trivial ref-count actions like increasing/decreasing the
reference count.
By moving the code to the header file we allow the compiler to inline
this code into the caller's function.
This avoids allocations in the VMObject constructor. The number of
inline elements was determined empirically and covers most common cases
including LibC malloc.
This doesn't change anything because our global operator delete also
calls kfree() - however instead of relying on this implementation
detail this makes this dependency more explicit.
The user is supposed to hold these in an OwnPtr but bad things would
happen if the user takes these out of the OwnPtr so let's make the
class non-copyable and non-movable.
Now that Region::name() has been changed to return a StringView we
can't rely on keeping a copy of the region's name past the region's
destruction just by holding a copy of the StringView.