Interface class for a chunk manager that can be controlled: It will provide updates about chunks, and release chunks on command.
Differential Revision: https://phabricator.services.mozilla.com/D72362
This patch adds a boolean field `mIsDependent` indicating whether a module was
loaded via the executable's Import Directory Table or not.
This patch also partially reverts Bug 1587539, moving a logic to detect Import
Directory tampering to `PEHeaders`'s ctor. With this, we can skip generating
a map of the executable's dependent modules if no tampering is detected.
Differential Revision: https://phabricator.services.mozilla.com/D66274
Same as with `BlocksRingBuffer`: Instead of a potentially-null pointer to a
`ProfileBufferEntryWriter`, we are now providing a
`Maybe<ProfileBufferEntryWriter>`, which is safer.
Differential Revision: https://phabricator.services.mozilla.com/D71287
Instead of a potentially-null pointer to a `ProfileBufferEntryWriter`, we are now providing a `Maybe<ProfileBufferEntryWriter>`, which is safer.
Differential Revision: https://phabricator.services.mozilla.com/D71286
To ensure that a spare chunk is ready to handle data that will eventually
overflow the current chunk, `ProfileChunkedBuffer` uses
`ProfileBufferChunk::RequestChunk()` to queue a request for a new chunk.
This request should be handled off-thread by the buffer user -- but a response
is not guaranteed, so the buffer does not rely on it and can get a new chunk
on the spot if really needed.
Because the request is asynchronous, and because either the buffer or the user
could be destroyed while a request is in flight, a shared
`RequestedChunkRefCountedHolder` object is used:
- When the request is handled, the new chunk (or nullptr) is given to the
holder.
- When the buffer needs a new chunk, it can retrieve the new chunk if the
request was successfully fulfilled.
If the requestee is destroyed first, the request won't be fulfilled and the
buffer will carry on without relying on requests.
If the requester is destroyed first, the holder (with a potential requested
chunk) will just get destroyed after the request is fulfilled or the requestee
is destroyed as well.
Differential Revision: https://phabricator.services.mozilla.com/D69495
--HG--
extra : moz-landing-system : lando
`ProfileChunkedBuffer` can handle zero or one `ProfileBufferChunkManager` at a
time, and can optionally take ownership of the manager.
Differential Revision: https://phabricator.services.mozilla.com/D69494
--HG--
extra : moz-landing-system : lando
ProfileChunkedBuffer simulates a near-infinite buffer over ProfileBufferChunks.
It uses a ProfileBufferChunkManager to get chunks and later release them.
Its use is similar to BlocksRingBuffer:
- It reserves blocks in chunks, adds some structure (just the size of the entry
that follows), and lets a user-provided writer write the entry.
- It allows reading past entries.
- It can be in an "out-of-session" state where APIs are still available but do
nothing.
It is intended to eventually replace BlocksRingBuffer.
This patch starts with the basic structure, following patches will add all
planned features.
Differential Revision: https://phabricator.services.mozilla.com/D69493
--HG--
extra : moz-landing-system : lando
With ASAN, GTest uses the old blocklist implemented in mozglue, where
the new blocklist type `RedirectToNoOpEntryPoint` behaves the same as
`DllBlocklistEntry`. The test needs to expect `LoadLibrary` to fail.
Differential Revision: https://phabricator.services.mozilla.com/D70578
--HG--
extra : moz-landing-system : lando
This patch introduces a new DLL blocklist type `RedirectToNoOpEntryPoint`
which hooks a DLL's entrypoint into a no-op function. With this technique,
we give the injected DLL no chance to run its code though we allow it to be
loaded into the process.
This new blocklist type is intended to block a DLL which is injected by IAT
patching which was planted by a kernel callback routine for LoadImage. It's
because blocking such a DLL makes a new process fail to launch.
Differential Revision: https://phabricator.services.mozilla.com/D68348
--HG--
extra : moz-landing-system : lando
This patch introduces `Kernel32ExportsSolver` which calculates RVAs of
kernel32's functions and transfers them to a target process, where the
transferred RVAs are resolved into function addresses.
Depends on D68346
Differential Revision: https://phabricator.services.mozilla.com/D68347
--HG--
extra : moz-landing-system : lando
`WindowsDllDetourPatcher::CreateTrampoline` does not only create a trampoline
region but also applies a patch on an original function. This patch extracts
the patching part as separate functions.
Differential Revision: https://phabricator.services.mozilla.com/D68344
--HG--
extra : moz-landing-system : lando
This patch introduces `nt::VirtualQuery` which consumes only ntdll's functions
to reduce dependency in `MMPolicy` on kernel32.dll. With this, `MMPolicy` still
depends on kernel32.dll, that will be solved by a coming patch.
Differential Revision: https://phabricator.services.mozilla.com/D68342
--HG--
extra : moz-landing-system : lando
This patch introduces a new DLL blocklist type `RedirectToNoOpEntryPoint`
which hooks a DLL's entrypoint into a no-op function. With this technique,
we give the injected DLL no chance to run its code though we allow it to be
loaded into the process.
This new blocklist type is intended to block a DLL which is injected by IAT
patching which was planted by a kernel callback routine for LoadImage. It's
because blocking such a DLL makes a new process fail to launch.
Differential Revision: https://phabricator.services.mozilla.com/D68348
--HG--
extra : moz-landing-system : lando
This patch introduces `Kernel32ExportsSolver` which calculates RVAs of
kernel32's functions and transfers them to a target process, where the
transferred RVAs are resolved into function addresses.
Depends on D68346
Differential Revision: https://phabricator.services.mozilla.com/D68347
--HG--
extra : moz-landing-system : lando
This patch introduces `nt::VirtualQuery` which consumes only ntdll's functions
to reduce dependency in `MMPolicy` on kernel32.dll. With this, `MMPolicy` still
depends on kernel32.dll, that will be solved by a coming patch.
Differential Revision: https://phabricator.services.mozilla.com/D68342
--HG--
extra : moz-landing-system : lando
When our detour processes instructions, we pass `ReadOnlyTargetFunction` to
`CountPrefixBytes` to determine whether a lock prefix exists or not.
In that case, we don't need to pass both `ReadOnlyTargetFunction` and an offset
as a parameter because `ReadOnlyTargetFunction` has an offset as a member.
Differential Revision: https://phabricator.services.mozilla.com/D69360
--HG--
extra : moz-landing-system : lando
`ProfileBufferChunkManagerWithLocalLimit` is a chunk manager that enforces a
memory limit in each process.
It is meant to mimic the main way `BlocksRingBuffer` works, so that we can more
easily switch to the new buffer storage without introducing the extra complexity
of inter-process memory coordination yet.
`ProfileBufferChunkManagerWithLocalLimit` will still offer a benefit over
`BlocksRingBuffer`, in that it won't allocate the maximum buffer size
immediately -- speeding the initialization, and hopefully even reducing the
total Firefox memory consumption in short-lived processes.
Differential Revision: https://phabricator.services.mozilla.com/D68770
--HG--
extra : moz-landing-system : lando
Also adds missing includes in some files, these were previously only transivitely
included through mozilla/TypeTraits.h.
Differential Revision: https://phabricator.services.mozilla.com/D68561
--HG--
extra : moz-landing-system : lando
A `ProfileBufferChunk` represents a single chunk of memory, with an optional
link to the next chunk.
In the new Fission-compatible profiler storage, chunks will be allocated by a
chunk manager, filled with data by the profiler, and then released back to the
chunk manager.
The chunk manager may decide to destroy or recycle old chunks based on memory
limits (per process, or for the entire Firefox app).
Differential Revision: https://phabricator.services.mozilla.com/D67272
--HG--
extra : moz-landing-system : lando
A `ProfileBufferChunk` represents a single chunk of memory, with an optional
link to the next chunk.
In the new Fission-compatible profiler storage, chunks will be allocated by a
chunk manager, filled with data by the profiler, and then released back to the
chunk manager.
The chunk manager may decide to destroy or recycle old chunks based on memory
limits (per process, or for the entire Firefox app).
Differential Revision: https://phabricator.services.mozilla.com/D67272
--HG--
extra : moz-landing-system : lando
This removes most dependencies on BlocksRingBuffer, to ease the transition to
the upcoming Fission-friendly profile buffer, including:
- Length type,
- SumBytes(),
- Gecko extensions of serialization.
Differential Revision: https://phabricator.services.mozilla.com/D66722
--HG--
rename : tools/profiler/public/BlocksRingBufferGeckoExtensions.h => tools/profiler/public/ProfileBufferEntrySerializationGeckoExtensions.h
extra : moz-landing-system : lando
The new ProfileBufferEntryReader/Writer are now used everywhere, including in
the profilers and tests.
The old EntryReader/Writer have been removed.
Differential Revision: https://phabricator.services.mozilla.com/D65697
--HG--
extra : moz-landing-system : lando
We copy IAT for ntdll.dll into a new process so that our hook code can use
ntdll's functions even in the early stage. However, IAT can be modified and
some entries may point to an address which is not valid in the child process.
In such a case, we should not copy IAT. One example is Windows compat mode
which redirects some ntdll functions into AcLayers.dll via IAT.
With this patch, we verify each IAT entry and if any of them is outside ntdll,
we give up using the launcher process and start the browser process.
Differential Revision: https://phabricator.services.mozilla.com/D62852
--HG--
extra : moz-landing-system : lando
To facilitate the upcoming transition to a new Fission-friendly storage, all
uses of `BlocksRingBuffer::{,Block}Index` are replaced with
`ProfileBuffer{,Block}Index`.
`BlocksRingBuffer::{,Block}Index` are not needed anymore.
Differential Revision: https://phabricator.services.mozilla.com/D64516
--HG--
extra : moz-landing-system : lando
In x86, our detour handles opcode 83 only when the Mod bits is 3.
When working on another project, I hit the instruction `cmp [ebp+0Ch],1`
where the Mod bits is 1, and it can be easily handled by a small fix.
It turned out my project does not need it, but it'd be good to have this.
Differential Revision: https://phabricator.services.mozilla.com/D64196
--HG--
extra : moz-landing-system : lando
Some of the BaseProfile headers are always available, even when BaseProfiler
itself is not built, so we should test these in all cases.
Differential Revision: https://phabricator.services.mozilla.com/D63230
--HG--
extra : moz-landing-system : lando
Some of the BaseProfile headers are always available, even when BaseProfiler
itself is disabled, so we should test these in all cases.
Differential Revision: https://phabricator.services.mozilla.com/D63230
--HG--
extra : moz-landing-system : lando
This patch adds a function to get an exported function in a remote process.
We need this implementation to address Bug 1604008, Bug 1608645, and Bug 1610790.
When `WindowsDllInterceptor` detours a function in a remote process, we used the
native `GetProcAddress` locally, and then detours the returned address in the
target process. The problem is if the caller's export table was modified, the
address returned from `GetProcAddress` might be invalid in the target process,
which is Bug 1604008.
I implemented `GetProcAddress` depending on both local and remote process image,
but it caused two regressions Bug 1608645 and Bug 1610790 because multiple
applications modify firefox's export table in multiple ways, such as replacing
an entry of EAT, replacing an RVA to Export section, or etc.
With this patch, we can use `PEExportSection<MMPolicy>::GetProcAddress` to get
an exported function in a remote process without relying on any local data so
that it's not impacted by modification of the local export table.
Differential Revision: https://phabricator.services.mozilla.com//D62315
Depends on D62314
This patch changes the entrypoint of test programs under mozglue/tests so that
a coming test program can handle a command string easily.
Differential Revision: https://phabricator.services.mozilla.com//D62314
This patch adds a function to get an exported function in a remote process.
We need this implementation to address Bug 1604008, Bug 1608645, and Bug 1610790.
When `WindowsDllInterceptor` detours a function in a remote process, we used the
native `GetProcAddress` locally, and then detours the returned address in the
target process. The problem is if the caller's export table was modified, the
address returned from `GetProcAddress` might be invalid in the target process,
which is Bug 1604008.
I implemented `GetProcAddress` depending on both local and remote process image,
but it caused two regressions Bug 1608645 and Bug 1610790 because multiple
applications modify firefox's export table in multiple ways, such as replacing
an entry of EAT, replacing an RVA to Export section, or etc.
With this patch, we can use `PEExportSection<MMPolicy>::GetProcAddress` to get
an exported function in a remote process without relying on any local data so
that it's not impacted by modification of the local export table.
Differential Revision: https://phabricator.services.mozilla.com/D62315
Depends on D62314
--HG--
extra : rebase_source : 3088f5997a2097ef22ce8567783375e5f7866ab2
This patch changes the entrypoint of test programs under mozglue/tests so that
a coming test program can handle a command string easily.
Differential Revision: https://phabricator.services.mozilla.com/D62314
--HG--
extra : rebase_source : a180de844700bbee60a6491a35da33da84aa12ed