| Age | Commit message (Collapse) | Author |
|
Looking into the implementation of the C++ standard facilities that seem
to be within all modules, it appears that they use 7 as a break reason
to indicate an uncaught C++ exception.
This was primarily found via the third last function called within
Horizon's equivalent of libcxxabi's demangling_terminate_handler(),
which passes the value 0x80000007 to svcBreak.
|
|
Pulse is considered a hack and nothing should be using it. We should completely remove it
|
|
Gets rid of a few unnecessary header dependencies in some source files.
|
|
This is a bounds check to ensure that the thread priority is within the
valid range of 0-64. If it exceeds 64, that doesn't necessarily mean
that an actual priority of 64 was expected (it actually means whoever
called the function screwed up their math).
Instead clarify the message to indicate the allowed range of thread
priorities.
|
|
Now that we handle the kernel capability descriptors we can correct
CreateThread to properly check against the core and priority masks
like the actual kernel does.
|
|
GetAllowedThreadPriorityMask()
Makes them consistent with their kernel capability counterparts.
|
|
Rather than use a switch here, this can be collapsed into a simple range
check, which is a little easier on the eyes.
|
|
kernel/process: Start the main thread using the specified ideal core
|
|
Print backtrace on svcBreak
|
|
This matches kernel behavior in that processes are started using their
specified ideal core, rather than always starting on core 0.
|
|
This makes the naming more closely match its meaning. It's just a
preferred core, not a required default core. This also makes the usages
of this term consistent across the thread and process implementations.
|
|
This function isn't a general purpose function that should be exposed to
everything, given it's specific to initializing the main thread for a
Process instance.
Given that, it's a tad bit more sensible to place this within
process.cpp, which keeps it visible only to the code that actually needs
it.
|
|
In all cases that these functions are needed, the VMManager can just be
retrieved and used instead of providing the same functions in Process'
interface.
This also makes it a little nicer dependency-wise, since it gets rid of
cases where the VMManager interface was being used, and then switched
over to using the interface for a Process instance. Instead, it makes
all accesses uniform and uses the VMManager instance for all necessary
tasks.
All the basic memory mapping functions did was forward to the Process'
VMManager instance anyways.
|
|
kernel: Handle kernel capability descriptors
|
|
Like the other members related to memory regions, the attributes need to
be reset back to their defaults as well.
|
|
svc: Implement SetThreadActivity (thread suspension)
|
|
Fixed uninitialized memory due to missing returns in canary
|
|
kernel/{process, thread}: Amend behavior related to IDs
|
|
While we're at it, we can also toss out the leftover capability parsing
from Citra.
|
|
|
|
This just specifies the handle table size. There's also a section of
reserved bits that are checked against.
|
|
|
|
|
|
Similar to the service capability flags, however, we currently don't
emulate the GIC, so this currently handles all interrupts as being valid
for the time being.
|
|
|
|
Handles the priority mask and core mask flags to allow building up the
masks to determine the usable thread priorities and cores for a kernel
process instance.
|
|
We've had the old kernel capability parser from Citra, however, this is
unused code and doesn't actually map to how the kernel on the Switch
does it. This introduces the basic functional skeleton for parsing
process capabilities.
|
|
If a thread handle is passed to svcGetProcessId, the kernel attempts to
access the process ID via the thread's instance's owning process.
Technically, this function should also be handling the kernel debug
objects as well, however we currently don't handle those kernel objects
yet, so I've left a note via a comment about it to remind myself when
implementing it in the future.
|
|
kernel/svc: Implement svcSetMemoryAttribute
|
|
With all the basic backing functionality implemented, we can now unstub
svcSetMemoryAttribute.
|
|
address range
This puts the backing functionality for svcSetMemoryAttribute in place,
which will be utilized in a following change.
|
|
certain attributes, permissions and states
|
|
Starts the process ID counter off at 81, which is what the kernel itself
checks against internally when creating processes. It's actually
supposed to panic if the PID is less than 81 for a userland process.
|
|
The service call uses a 64-bit value, just like svcGetProcessId. This
amends the function signature accordingly.
|
|
The kernel uses a 64-bit value for the thread ID, so we shouldn't be
using a 32-bit value.
|
|
svcGetProcessId's out parameter is a pointer to a 64-bit value, not a
32-bit one.
|
|
In the actual kernel, this is a 64-bit value, so we shouldn't be using a
32-bit type to handle it.
|
|
|
|
Functions which are suppose to crash on non canary builds usually don't return anything which lead to uninitialized memory being used.
|
|
|
|
This is shorter and more concise. This also removes the now-innaccurate
comment, as it's not returned wholesale to svcQueryMemory anymore.
|
|
Adds the barebones enumeration constants and functions in place to
handle memory attributes, while also essentially leaving the attribute
itself non-functional.
|
|
svc: Implement yield types 0 and -1
|
|
vm_manager/svc: Modify MemoryState enum, and correct error handling for svcQueryMemory
|
|
svc_wrap: Correct register index for a wrapper specialization
|
|
svcQueryProcessMemory is trivial to implement, given all the behavior
necessary for it is present, it just needs a handler for it.
|
|
In the previous change, the memory writing was moved into the service
function itself, however it still had a problem, in that the entire
MemoryInfo structure wasn't being written out, only the first 32 bytes
of it were being written out. We still need to write out the trailing
two reference count members and zero out the padding bits.
Not doing this can result in wrong behavior in userland code in the following
scenario:
MemoryInfo info; // Put on the stack, not quaranteed to be zeroed out.
svcQueryMemory(&info, ...);
if (info.device_refcount == ...) // Whoops, uninitialized read.
This can also cause the wrong thing to happen if the user code uses
std::memcmp to compare the struct, with another one (questionable, but
allowed), as the padding bits are not guaranteed to be a deterministic
value. Note that the kernel itself also fully zeroes out the structure
before writing it out including the padding bits.
|
|
Moves the memory writes directly into QueryProcessMemory instead of
letting the wrapper function do it. It would be inaccurate to allow the
handler to do it because there's cases where memory shouldn't even be
written to. For example, if the given process handle is invalid.
HOWEVER, if the memory writing is within the wrapper, then we have no
control over if these memory writes occur, meaning in an error case, 68
bytes of memory randomly get trashed with zeroes, 64 of those being
written to wherever the memory info address points to, and the remaining
4 being written wherever the page info address points to.
One solution in this case would be to just conditionally check within
the handler itself, but this is kind of smelly, given the handler
shouldn't be performing conditional behavior itself, it's a behavior of
the managed function. In other words, if you remove the handler from the
equation entirely, does the function still retain its proper behavior?
In this case, no.
Now, we don't potentially trash memory from this function if an invalid
query is performed.
|
|
These should be swapped.
|
|
This would result in svcSetMemoryAttribute getting the wrong value for
its third parameter. This is currently fine, given the service function
is stubbed, however this will be unstubbed in a future change, so this
needs to change.
|