This came up in @jonathandturner's video walking through the system
and playing with things: https://www.youtube.com/watch?v=TtV86uL5oD4
At one point, he tried profiling his Terminal app, and since the
Terminal was completely idle while profiling, no samples were captured
and there was no profile to show.
Make sure we propagate any error when loading the profile, and show it
in a GUI message box instead of stderr. :^)
Problem:
- C functions with no arguments require a single `void` in the argument list.
Solution:
- Put the `void` in the argument list of functions in C header files.
We were using ring 0 selectors everywhere (the bottom 3 bits of a
selector determines the ring.) This doesn't really make any practical
difference since UE doesn't run code in other rings anyway, but let's
have correct-looking segment selectors. :^)
Make it possible to bail out of ELF::Image::for_each_program_header()
and then do exactly that if something goes wrong during executable
loading in the kernel.
Also make the errors we return slightly more nuanced than just ENOEXEC.
This commit gets rid of ELF::Loader entirely since its very ambiguous
purpose was actually to load executables for the kernel, and that is
now handled by the kernel itself.
This patch includes some drive-by cleanup in LibDebug and CrashDaemon
enabled by the fact that we no longer need to keep the ref-counted
ELF::Loader around.
New serenity_app() targets can be defined which allows application
icons to be emedded directly into the executable. The embedded
icons will then be used when creating an icon for that file in
LibGUI.
Problem:
- `(void)` simply casts the expression to void. This is understood to
indicate that it is ignored, but this is really a compiler trick to
get the compiler to not generate a warning.
Solution:
- Use the `[[maybe_unused]]` attribute to indicate the value is unused.
Note:
- Functions taking a `(void)` argument list have also been changed to
`()` because this is not needed and shows up in the same grep
command.
Keep the debug symbols for shared libraries in memory after we opened
them the first time. This dramatically speeds up symbolication of
backtraces when running dynamically linked programs in UE.
When loading dynamic objects, the emulator loads the interpreter,
generates an auxiliary vector and starts executing the loader.
Additionally, this commits also makes the MallocTracer and backtrace
symbolication work for dynamically loaded programs.
Instead of having .hsp files that determine which files are members
of a project, a project is now an entire directory tree instead.
This feels a lot less cumbersome to work with, and removes a fair
amount of busywork that would otherwise be expected from the user.
This patch refactors large parts of HackStudio to implement the new
way of thinking. I've probably missed some details here and there,
but generally I think it's pretty OK.
If the percentage is 100, we were trying to get the heat gradient pixel
at (100, 0), which was one pixel past the end. Fix this by making the
heat gradient 101 pixels wide :^)
Language servers will now receive an open file instead of just its path. This
means the language servers no longer need to access the filesystem to open the
file themselves.
The C++ language server now has no filesystem access whatsoever (although we
might need to relax this in the future if it learns to complete #include paths),
while the Shell language server can read /etc/passwd (it wants that in order to
get the user's home directory) and browse (but not read!) the whole file system
tree for completing paths.
It is now possible to use the special IPC::File type in message arguments. In
C++, the type is nothing more than a wrapper over a file descriptor. But when
serializing/deserializing IPC::File arguments, LibIPC will use the sendfd/recvfd
kernel APIs instead of sending the integer inline.
This makes it quite convenient to pass files over IPC, and will allow us to
significantly tighten sandboxes in the future :^)
Closes https://github.com/SerenityOS/serenity/issues/3643
Instead of caching a raw pointer to the next instruction, cache the
region we're fetching instructions from, and a pointer to its base.
This way we don't need to keep invalidating and reloading the cache
whenever the CPU jumps.
By passing the Region& to the auditing functions, we know exactly which
block we are hitting. This allows us to track big mallocations the same
way we already do chunked ones.
This gets rid of the O(n) scan in find_mallocation() for allocations
larger than the maximum malloc chunk size. :^)
These are getting quite hot (~4% of general emulation profile combined)
so let's just devirtualize them and turn the function calls into simple
boolean checks.
Instead of tracking known malloc blocks in a separate hash table,
add an optional malloc metadata pointer to MmapRegion.
This makes finding the malloc metadata for a given pointer extremely
fast since it can piggyback on the page table array. :^)
Not motivated by anything in particular, they just looked easy to fill
in. With this, all arithmetic FI* FPU instructions are implemented.
Switch to the mXXint style in a few more functions, this part is no-op.
This is used by memset() so we get a lot of mileage out of optimizing
this instruction.
Note that we currently audit every individual byte accessed separately.
This could be greatly improved by adding a range auditing mechanism to
MallocTracer.
To make SoftMMU::find_region() O(1), this patch invests 3MiB into a
lookup table where we track each possible page base address and map
them to the SoftMMU::Region corresponding to that address.
This is another large improvement to general emulation performance. :^)
We don't want the next_address pointer losing its alignment somehow.
This whole thing should be replaced at some point, since UE hosted
programs won't be able to run forever with this allocation strategy.