This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.
I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
We need to generate events when finalizing, or we won't know that we
succeeded in stopping the process to detach/kill. Instead, we stall and
then after our 20 interrupt timeout, we kill the process (even if we
were supposed to detach) and exit.
OTOH, we have to not generate events when the Process is being
destructed because shared_from_this has already been torn down, and
using it will cause crashes.
The contents of which are mostly SPSR_EL1 as shown in the Arm manual,
with a few adjustments for things Linux says userspace shouldn't concern
itself with.
```
(lldb) register read cpsr
cpsr = 0x80001000
= (N = 1, Z = 0, C = 0, V = 0, SS = 0, IL = 0, ...
```
Some fields are always present, some depend on extensions. I've checked
for those extensions using HWCAP and HWCAP2.
To provide this for core files and live processes I've added a new class
LinuxArm64RegisterFlags. This is a container for all the registers we'll
want to have fields and handles detecting fields and updating register
info.
This is used by the native process as follows:
* There is a global LinuxArm64RegisterFlags object.
* The first thread takes a mutex on it, and updates the fields.
* Subsequent threads see that detection is already done, and skip it.
* All threads then update their own copy of the register information
with pointers to the field information contained in the global object.
This means that even though every thread will have the same fields, we
only detect them once and have one copy of the information.
Core files instead have a LinuxArm64RegisterFlags as a member, because
each core file could have different saved capabilities. The logic from
there is the same but we get HWACP values from the corefile note.
This handler class is Linux specific right now, but it can easily be
made more generic if needed. For example by using LLVM's FeatureBitset
instead of HWCAPs.
Updating register info is done with string comparison, which isn't
ideal. For CPSR, we do know the register number ahead of time but we do
not for other registers in dynamic register sets. So in the interest of
consistency, I'm going to use string comparison for all registers
including cpsr.
I've added tests with a core file and live process. Only checking for
fields that are always present to account for CPU variance.
The ZT0 register is always 64 bytes in size so it is a lot easier to
handle than ZA which is scalable. In addition, reading an inactive ZT0
via ptrace returns all 0s, unlike ZA which returns no register data.
This means that a corefile from a process where ZA and ZT0 were inactive
still contains an NT_ARM_ZT note and we can simply say that if it's
there, then we should be able to read from it.
Along the way I removed a redundant check on the size of the ZA note. If
that note's size is < the ZA header size, we do not have SME, and
therefore could not have SME2 either.
I have added ZT0 to the existing SME core files tests. This means that
you need an SME2 system to generate them (Arm's FVP at this point). I
think this is a fair tradeoff given that this is all running in
simulation anyway and seperate ZT0 tests would be 99% identical copies
of the ZA only tests.
SME2 is documented as part of the main SME supplement:
https://developer.arm.com/documentation/ddi0616/latest/
The one change for debug is this new ZT0 register. This register
contains data to be used with new table lookup instructions.
It's size is always 512 bits (not scalable) and can be
interpreted in many different ways depending on the instructions
that use it.
The kernel has implemented this as a new register set containing
this single register. It always returns register data (with no header,
unlike ZA which does have a header).
https://docs.kernel.org/arch/arm64/sme.html
ZT0 is only active when ZA is active (when SVCR.ZA is 1). In the
inactive state the kernel returns 0s for its contents. Therefore
lldb doesn't need to create 0s like it does for ZA.
However, we will skip restoring the value of ZT0 if we know that
ZA is inactive. As writing to an inactive ZT0 sets SVCR.ZA to 1,
which is not desireable as it would activate ZA also. Whether
SVCR.ZA is set will be determined only by the ZA data we restore.
Due to this, I've added a new save/restore kind SME2. This is easier
than accounting for the variable length ZA in the SME data. We'll only
save an SME2 data block if ZA is active. If it's not we can get fresh
0s back from the kernel for ZT0 anyway so there's nothing for us to
restore.
This new register will only show up if the system has SME2 therefore
the SME set presented to the user may change, and I've had to account
for that in in a few places.
I've referred to it internally as simply "ZT" as the kernel does in
NT_ARM_ZT, but the architecture refers to the specific register as "ZT0"
so that's what you'll see in lldb.
```
(lldb) register read -s 6
Scalable Matrix Extension Registers:
svcr = 0x0000000000000000
svg = 0x0000000000000004
za = {0x00 <...> 0x00}
zt0 = {0x00 <...> 0x00}
```
For most register sets, if it was enabled this meant you could use it,
it was present in the process. There was no present but turned off
state. So "enabled" made sense.
Then ZA came along (and soon to be ZT0) where ZA can be present in the
hardware when you have SME, but ZA itself can be made inactive. This
means that "IsZAEnabled()" doesn't mean is it active, it means do you
have SME. Which is very confusing when we actually want to know if ZA is
active.
So instead say "IsZAPresent", to make these checks more specific. For
things that can't be made inactive, present will imply "active" as
they're never inactive.
This register reports the configuration of the AArch64 Linux tagged
address ABI, part of which is the memory tagging (MTE) settings.
It will always be present in core files because even without MTE, there
are parts of the tagged address ABI that can be configured (these parts
use the Top Byte Ignore feature).
I missed adding this when I previously worked on MTE support. Until now
you could read memory tags from a core file but not this register.
As ReadRegister always read into a uint64_t, when it called operator=
with uint64_t it was setting the RegisterValue's type to eTypeUInt64
regardless of its size.
This mostly works because most registers are 64 bit, and very few bits
of code rely on the type being correct. However, cpsr, fpsr and fpcr are
in fact 32 bit, and my upcoming register fields code relies on this type
being correct.
Which is how I found this bug and unfortunately is the only way to test
it. As RegisterValue::Type never makes it out via the API anywhere. So
this change will be tested once I start adding register field
information.
This reverts commit 3fa5035823.
m_sve_state was not initialised which (I'm guessing) meant that
it could potentially be a value that matched a real SVE state.
Then we'd be acting as if we're streaming mode, for example,
without ever having the data required to back that up.
By sheer luck this only turn up on x86, AArch64 and ARM were fine.
It is UB regardless.
This adds the ability to read streaming SVE registers,
ZA, SVCR and SVG from core files.
Streaming SVE is in a new note NT_ARM_SSVE but otherwise
has the same format as SVE. So I've done the same as I
did for live processes and reused the existing SVE state
with an extra state for the mode variable.
ZA is in a note NT_ARM_ZA and again the handling matches
live processes. Except that it gets setup only once. A
disabled ZA reads as 0s as usual.
SVCR and SVG are pseudo registers, generated from the notes.
An important detail is that the notes represent what
you would have got if you read from ptrace at the time of
the crash.
This means that for a corefile in non-streaming mode,
there is still an NT_ARM_SSVE note and we check the header
flags to tell if it is active. We cannot just say if you
have the note you're in streaming mode.
The kernel does not provide register values for the inactive
mode and even if it did, they would be undefined, so if we find
streaming state, we ignore the non-streaming state.
Same for ZA, a disabled ZA still has the header in the note.
The tests do not cover all combinations but enough different
vector lengths, modes and ZA states to be confident.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D158500
Note: This requires later commits for ZA to function properly,
it is split for ease of review. Testing is also in a later patch.
The "Matrix" part of the Scalable Matrix Extension is a new register
"ZA". You can think of this as a square matrix made up of scalable rows,
where each row is one scalable vector long. However it is not made
of the existing scalable vector registers, it is its own register.
Meaning that the size of ZA is the vector length in bytes * the vector
length in bytes.
https://developer.arm.com/documentation/ddi0616/latest/
It uses the streaming vector length, even when streaming mode itself
is not active. For this reason, it's register data header always
includes the streaming vector length.
Due to it's size I've changed kMaxRegisterByteSize to the maximum
possible ZA size and kTypicalRegisterByteSize will be the maximum
possible scalable vector size. Therefore ZA transactions will cause heap
allocations, and non ZA registers will perform exactly as before.
ZA can be enabled and disabled independently of streaming mode. The way
this works in ptrace is different to SVE versus streaming SVE. Writing
NT_ARM_ZA without register data disables ZA, writing NT_ARM_ZA with
register data enables ZA (LLDB will only support the latter, and only
because it's convenient for us to do so).
https://kernel.org/doc/html/v6.2/arm64/sme.html
LLDB does not handle registers that can appear and dissappear at
runtime. Rather than add complexity to implement that, LLDB will
show a block of 0s when ZA is disabled.
The alternative is not only updating the vector lengths every stop,
but every register definition. It's possible but I'm not sure it's worth
pursuing.
Users should refer to the SVCR register (added in later patches)
for the final word on whether ZA is active or not.
Writing to "VG" during streaming mode will change the size of the
streaming sve registers and ZA. LLDB will not attempt to preserve
register values in this case, we'll just read back the undefined
content the kernel shows. This is in line with, as stated, the
kernel ABIs and the prospective software ABIs look like.
ZA is defined as a vector of size SVL*SVL, so the display in lldb
is very basic. A giant block of values. This is no worse than SVE,
just larger. There is scope to improve this but that can wait
until we see some use cases.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D159502
7e229217f4 did live processes, this does
core files. Pretty simple, there is an NT_ARM_TLS note that contains
at least tpidr, and on systems with the Scalable Matrix Extension (SME), tpidr2
as well.
tpidr2 will be handled in future patches for SME support.
This NT_ARM_TLS note has always been present but it seems convenient to
handle it as "optional" inside of LLDB. We'll probably want the flexibility
when supporting tpidr2.
Normally the C library would set tpidr but all our test sources build
without it. So I've updated the neon test program to write to tpidr
and regenerated the corefile.
I've removed the LLDB_PTRACE_NT_ARM_TLS that was unused, we get
what we need from llvm's defs instead.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D156118
Summary:
[lldb][x86_64] This patch adds fs_base/gs_base support for Linux x86_64.
Originally, I plan to split the diff into two parts, one to refactoring lldb_xxx_x86_64 => x86_64::lldb_xxx across code base and the other one for adding fs_base/gs_base, but it turns out to be a non-trivial effort to split and very error prone so I decided to keep a single diff to get feedback.
GDB supports fs_base/gs_base registers while LLDB does not. Since both linux coredump note section and ptrace
supports them it is a missing feature.
For context, this is a required feature to support getting pthread pointer on linux from both live and dump debugging.
See thread below for details:
https://discourse.llvm.org/t/how-to-get-pthread-pointer-from-lldb/70542/2?u=jeffreytan81
Implementation wise, we have initially tried `#ifdef` approach to reuse the code but it is introducing very tricky bugs and proves
hard to maintain. Instead the diff completely separates the registers between x86_64 and x86_64_with_base so that non-linux related
implementations can use x86_64 registers while linux uses x86_64_with_base.
Here are the list of changes done in the patch:
* Registers in lldb-x86-register-enums.h are separated into two: x86_64 and x86_64_with_base
* fs_base/gs_base are added into x86_64_with_base
* All linux files are change to use x86_64::lldb_xxx => x86_64_with_base::lldb_xxx
* Support linux elf-core:
* A new RegisterContextLinuxCore_x86_64 class is added for ThreadElfCore
* RegisterContextLinuxCore_x86_64 overrides and uses its own register set supports fs_base/gs_base
* RegisterInfos_x86_64_with_base/RegisterInfos_x86_64_with_base_shared ared added to provide g_contained_XXX/g_invalidate_XXX and RegInfo related code sharing.
* `RegisterContextPOSIX_x86 ::m_gpr_x86_64` seems to be unused so I removed it.
* `NativeRegisterContextDBReg_x86::GetDR()` is overridden in `NativeRegisterContextLinux_x86_64` to make watchpoint work.
Reviewers:clayborg,labath,jingham,jdoerfert,JDevlieghere,kusmour,GeorgeHuyubo
Subscribers:
Tasks:
Tags:
Differential Revision: https://reviews.llvm.org/D155256
I'm not convinced that it makes sense for the paths to be ConstStrings. We're
going to be putting them into FileSpecs (which are backed by
ConstStrings, for now) but otherwise there's no need to store them as
ConstStrings upfront.
Differential Revision: https://reviews.llvm.org/D153827
Previously we only looked at the si_signo field, so you got:
```
(lldb) bt
* thread #1, name = 'a.out.mte', stop reason = signal SIGSEGV
* frame #0: 0x00000000004007f4
```
This patch adds si_code so we can show:
```
(lldb) bt
* thread #1, name = 'a.out.mte', stop reason = signal SIGSEGV: sync tag check fault
* frame #0: 0x00000000004007f4
```
The order of errno and code was incorrect in ElfLinuxSigInfo::Parse.
It was the order that a "swapped" siginfo arch would use, which for Linux,
is only MIPS. We removed MIPS Linux support some time ago.
See:
fe15c26ee2/include/uapi/asm-generic/siginfo.h (L121)
A test is added using memory tagging faults. Which were the original
motivation for the changes.
Reviewed By: JDevlieghere
Differential Revision: https://reviews.llvm.org/D146045
The high level goal of this change is to remove lldbTarget's dependency
on lldbPluginProcessUtility. The reason for this existing dependency is
so that we can create the appropriate UnixSignals object based on an
ArchSpec. Instead of using the ArchSpec, we can instead take advantage
of the Platform associated with the current Target.
This is accomplished by adding a new method to Platform,
CreateUnixSignals, which will create the correct UnixSignals object for
us. We then can use `Platform::GetUnixSignals` and rely on that to give
us the correct signals as needed.
Differential Revision: https://reviews.llvm.org/D146263
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
All callers were either assuming their pointer was not null before calling
this, or checking beforehand.
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D135668
This teaches ProcessElfCore to recognise the MTE tag segments.
https://www.kernel.org/doc/html/latest/arm64/memory-tagging-extension.html#core-dump-support
These segments contain all the tags for a matching memory segment
which will have the same size in virtual address terms. In real terms
it's 2 tags per byte so the data in the segment is much smaller.
Since MTE is the only tag type supported I have hardcoded some
things to those values. We could and should support more formats
as they appear but doing so now would leave code untested until that
happens.
A few things to note:
* /proc/pid/smaps is not in the core file, only the details you have
in "maps". Meaning we mark a region tagged only if it has a tag segment.
* A core file supports memory tagging if it has at least 1 memory
tag segment, there is no other flag we can check to tell if memory
tagging was enabled. (unlike a live process that can support memory
tagging even if there are currently no tagged memory regions)
Tests have been added at the commands level for a core file with
mte and without.
There is a lot of overlap between the "memory tag read" tests here and the unit tests for
MemoryTagManagerAArch64MTE::UnpackTagsFromCoreFileSegment, but I think it's
worth keeping to check ProcessElfCore doesn't cause an assert.
Depends on D129487
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D129489
Previously if you read a code/data mask before there was a valid thread
you would get the top byte mask. This meant the value was "valid" as in,
don't read it again.
When using a corefile we ask for the data mask very early on and this
meant that later once you did have a thread it wouldn't read the
register to get the rest of the mask.
This fixes that and adds a corefile test generated from the same program
as in my previous change on this theme.
Depends on D118794
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D122411
Currently, all data buffers are assumed to be writable. This is a
problem on macOS where it's not allowed to load unsigned binaries in
memory as writable. To be more precise, MAP_RESILIENT_CODESIGN and
MAP_RESILIENT_MEDIA need to be set for mapped (unsigned) binaries on our
platform.
Binaries are mapped through FileSystem::CreateDataBuffer which returns a
DataBufferLLVM. The latter is backed by a llvm::WritableMemoryBuffer
because every DataBuffer in LLDB is considered to be writable. In order
to use a read-only llvm::MemoryBuffer I had to split our abstraction
around it.
This patch distinguishes between a DataBuffer (read-only) and
WritableDataBuffer (read-write) and updates LLDB to use the appropriate
one.
rdar://74890607
Differential revision: https://reviews.llvm.org/D122856
This reverts commit 0df522969a.
Additional checks are added to fix the detection of the last memory region
in GetMemoryRegions or repeating the "memory region" command when the
target has non-address bits.
Normally you keep reading from address 0, looking up each region's end
address until you get LLDB_INVALID_ADDR as the region end address.
(0xffffffffffffffff)
This is what the remote will return once you go beyond the last mapped region:
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
[0x0001000000000000-0xffffffffffffffff) ---
Problem is that when we "fix" the lookup address, we remove some bits
from it. On an AArch64 system we have 48 bit virtual addresses, so when
we fix the end address of the [stack] region the result is 0.
So we loop back to the start.
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
[0x0000000000000000-0x0000000000400000) ---
To fix this I added an additional check for the last range.
If the end address of the region is different once you apply
FixDataAddress, we are at the last region.
Since the end of the last region will be the last valid mappable
address, plus 1. That 1 will be removed by the ABI plugin.
The only side effect is that on systems with non-address bits, you
won't get that last catch all unmapped region from the max virtual
address up to 0xf...f.
[0x0000fffff8000000-0x0000fffffffdf000) ---
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
<ends here>
Though in some way this is more correct because that region is not
just unmapped, it's not mappable at all.
No extra testing is needed because this is already covered by
TestMemoryRegion.py, I simply forgot to run it on system that had
both top byte ignore and pointer authentication.
This change has been tested on a qemu VM with top byte ignore,
memory tagging and pointer authentication enabled.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D115508
Most of our code was including Log.h even though that is not where the
"lldb" log channel is defined (Log.h defines the generic logging
infrastructure). This worked because Log.h included Logging.h, even
though it should.
After the recent refactor, it became impossible the two files include
each other in this direction (the opposite inclusion is needed), so this
patch removes the workaround that was put in place and cleans up all
files to include the right thing. It also renames the file to LLDBLog to
better reflect its purpose.
Recognize FreeBSD vmcores (kernel core dumps) through OS ABI = 0xFF
+ ELF version = 0, and do not process them via the elf-core plugin.
While these files use ELF as a container format, they contain raw memory
dump rather than proper VM segments and therefore are not usable
to the elf-core plugin.
Differential Revision: https://reviews.llvm.org/D114967
This reverts commit fac3f20de5.
I found this has broken how we detect the last memory region in
GetMemoryRegions/"memory region" command.
When you're debugging an AArch64 system with pointer authentication,
the ABI plugin will remove the top bit from the end address of the last
user mapped area.
(lldb)
[0x0000fffffffdf000-0x0001000000000000) rw- [stack]
ABI plugin removes anything above the 48th bit (48 bit virtual addresses
by default on AArch64, leaving an address of 0.
(lldb)
[0x0000000000000000-0x0000000000400000) ---
You get back a mapping for 0 and get into an infinite loop.
This reverts commit 5fbcf67734.
ProcessDebugger is used in ProcessWindows and NativeProcessWindows.
I thought I was simplifying things by renaming to DoGetMemoryRegionInfo
in ProcessDebugger but the Native process side expects "GetMemoryRegionInfo".
Follow the pattern that WriteMemory uses. So:
* ProcessWindows::DoGetMemoryRegioninfo calls ProcessDebugger::GetMemoryRegionInfo
* NativeProcessWindows::GetMemoryRegionInfo does the same
On AArch64 we have various things using the non address bits
of pointers. This means when you lookup their containing region
you won't find it if you don't remove them.
This changes Process GetMemoryRegionInfo to a non virtual method
that uses the current ABI plugin to remove those bits. Then it
calls DoGetMemoryRegionInfo.
That function does the actual work and is virtual to be overriden
by Process implementations.
A test case is added that runs on AArch64 Linux using the top
byte ignore feature.
Reviewed By: omjavaid
Differential Revision: https://reviews.llvm.org/D102757
There is no reason why this function should be returning a ConstString.
While modifying these files, I also fixed several instances where
GetPluginName and GetPluginNameStatic were returning different strings.
I am not changing the return type of GetPluginNameStatic in this patch, as that
would necessitate additional changes, and this patch is big enough as it is.
Differential Revision: https://reviews.llvm.org/D111877
In all these years, we haven't found a use for this function (it has
zero callers). Lets just remove the boilerplate.
Differential Revision: https://reviews.llvm.org/D109600
lldb_private::DataExtractor contains DataBufferSP m_data_sp which is
relatively expensive to copy (due to multi-threading locking).
llvm::DataExtractor does not have this problem as it uses StringRef
instead.
The copy constructor is explicit as otherwise it is easy to make
unintended modification of a local copy instead of a caller's instance
(D107470 but that is llvm::DataExtractor).
Reviewed By: clayborg
Differential Revision: https://reviews.llvm.org/D107485
Add support for extracting basic data from NetBSD/i386 core dumps.
FPU registers are not supported at the moment.
Differential Revision: https://reviews.llvm.org/D101091
The C headers are deprecated so as requested in D102845, this is replacing them
all with their (not deprecated) C++ equivalent.
Reviewed By: shafik
Differential Revision: https://reviews.llvm.org/D103084
Add a function to read NT_PRPSINFO note from FreeBSD core dumps. This
is necessary to get the process ID (NT_PRSTATUS has only thread ID).
Move the lp64 check from NT_PRSTATUS parsing to the parseFreeBSDNotes()
to avoid repeating it.
Differential Revision: https://reviews.llvm.org/D101893
The FreeBSD coredumps from i386 systems contain only FSAVE-style
NT_FPREGSET. Since we do not really support reading that kind of data
anymore, just use NT_X86_XSTATE to get FXSAVE-style data when available.
Differential Revision: https://reviews.llvm.org/D101086
This adds support for reading AArch64 Pointer Authentication regset
from elf-core file. Also includes a test-case for the same. Furthermore
there is also a slight refactoring of RegisterContextPOSIXCore_arm64
members and constructor. linux-aarch64-pac.core file is generated using
lldb/test/API/functionalities/postmortem/elf-core/main.c with following
clang arguments:
-march=armv8.5-a -mbranch-protection=pac-ret+leaf -nostdlib -static -g
Reviewed By: DavidSpickett
Differential Revision: https://reviews.llvm.org/D99941
This is patch adds support for adding dynamic register sets for
AArch64 dynamic features in LLDB. AArch64 has optional features like
SVE, Pointer Authentication and MTE which means LLDB needs to decide
at run time which registers it needs to pull in for the current
executable based on underlying support for a certain feature.
This patch makes necessary adjustments to make way for dynamic
register infos and dynamic register sets.
Reviewed By: labath
Differential Revision: https://reviews.llvm.org/D96458