summaryrefslogtreecommitdiff
path: root/lldb/source/Target/RegisterFlags.cpp
AgeCommit message (Collapse)Author
2024-07-01Reland "[lldb] Parse and display register field enums" (#97258)" (#97270)David Spickett
This reverts commit d9e659c538516036e40330b6a98160cbda4ff100. I could not reproduce the Mac OS ASAN failure locally but I narrowed it down to the test `test_many_fields_same_enum`. This test shares an enum between x0, which is 64 bit, and cpsr, which is 32 bit. My theory is that when it does `register read x0`, an enum type is created where the undlerying enumerators are 64 bit, matching the register size. Then it does `register read cpsr` which used the cached enum type, but this register is 32 bit. This caused lldb to try to read an 8 byte value out of a 4 byte allocation: READ of size 8 at 0x60200014b874 thread T0 <...> =>0x60200014b800: fa fa fd fa fa fa fd fa fa fa fd fa fa fa[04]fa To fix this I've added the register's size in bytes to the constructed enum type's name. This means that x0 uses: __lldb_register_fields_enum_some_enum_8 And cpsr uses: __lldb_register_fields_enum_some_enum_4 If any other registers use this enum and are read, they will use the cached type as long as their size matches, otherwise we make a new type.
2024-07-01Revert "[lldb] Parse and display register field enums" (#97258)David Spickett
Reverts llvm/llvm-project#95768 due to a test failure on macOS with ASAN: https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/lldb-cmake-sanitized/425/console
2024-06-27[lldb] Parse and display register field enums (#95768)David Spickett
This teaches lldb to parse the enum XML elements sent by lldb-server, and make use of the information in `register read` and `register info`. The format is described in https://sourceware.org/gdb/current/onlinedocs/gdb.html/Enum-Target-Types.html. The target XML parser will drop any invalid enum or evalue. If we find multiple evalue for the same value, we will use the last one we find. The order of evalues from the XML is preserved as there may be good reason they are not in numerical order.
2024-06-27[lldb] Do not produce field information for registers known not to exist ↵David Spickett
(#95125) Currently the logic is generate field information for all registers in LinuxArm64RegisterFlags and then as we walk the existing register info, only those that are in that existing info will get the new fields patched in. This works fine but on a review for FreeBSD support it was pointed out that this is not obvious from the source code. So instead I've allowed the construction of empty lists of fields, and field detection methods can return an empty field list if they think that the register will never exist. Then the pre-existing code will see the empty field list, and never look for that register in the register info. I think removing the assert is ok because the GDB classes filter out empty field lists at runtime, and anyone updating the built in field information would presumably notice if none of the fields they intended to add were displayed. mte_ctrl and svcr are the only registers that need this so far. There is no extra testing here as the behaviour is the same, it doesn't add field information to regiters that don't exist. The mechanism is just clearer now.
2024-06-21[lldb] More descriptive name for register flags logging functionsDavid Spickett
This was requested on a review for enum code that added new log functions.
2024-06-17[lldb] Add register field enum class (#90063)David Spickett
This represents the enum type that can be assigned to a field using the `<enum>` element in the target XML. https://sourceware.org/gdb/current/onlinedocs/gdb.html/Enum-Target-Types.html Each enumerator has: * A non-empty name * A value that is within the range of the field it's applied to The XML includes a "size" but we don't need that for anything and it's a pain to verify so I've left it out of our internal structures. When emitting XML we'll set size to the size of the register using the enum. An Enumerator class is added to RegisterFlags and hooked up to the existing ToXML so lldb-server can use it to emit enums as well. As enums are elements on the same level as flags, when emitting XML we'll do so via the registers. Before emitting a flags element we look at all the fields and see what enums they reference. Then print all of those if we haven't already done so. Functions are added to dump enum information for `register info` to use to show the enum information.
2024-05-29[lldb][NFC] Pass Stream& to ToXML methods in RegisterFlagsDavid Spickett
As suggested in a review of some new code for this file, Stream is more general. The code does not need to know that it's backed by a string.
2023-11-08[lldb][AArch64][Linux] Add field information for the CPSR register (#70300)David Spickett
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.
2023-10-26[lldb][lldb-server] Enable sending RegisterFlags as XML (#69951)David Spickett
This adds ToXML methods to encode RegisterFlags and its fields into XML according to GDB's target XML format: https://sourceware.org/gdb/onlinedocs/gdb/Target-Description-Format.html#Target-Description-Format lldb-server does not use libXML to build XML, so this follows the existing code that uses strings. Indentation is used so the result is still human readable. ``` <flags id=\"Foo\" size=\"4\"> <field name=\"abc\" start=\"0\" end=\"0\"/> </flags> ``` This is used by lldb-server when building target XML, though no one sets any fields yet. That'll come in a later commit.
2023-06-21[lldb] Correct spelling in RegisterFlags commentsDavid Spickett
I missed these review comments on https://reviews.llvm.org/D152917 before landing it.
2023-06-21[LLDB] Add table formatting for register fieldsDavid Spickett
This will be used by the "register info" command to show the layout of register contents. For example if we have these fields coming in from XML: ``` <field name="D" start="0" end="7"/> <field name="C" start="8" end="15"/> <field name="B" start="16" end="23"/> <field name="A" start="24" end="31"/> ``` We get: ``` | 31-24 | 23-16 | 15-8 | 7-0 | |-------|-------|------|-----| | A | B | C | D | ``` Note that this is only the layout, not the values. For values, use "register read". The tables' columns are center padded (left bias if there's an odd padding) and will wrap if the terminal width is too low. ``` | 31-24 | 23-16 | |-------|-------| | A | B | | 15-8 | 7-0 | |------|-----| | C | D | ``` This means we match the horizontal format seen in many architecture manuals but don't spam the user with lots of misaligned text when the output gets very long. Reviewed By: jasonmolenda Differential Revision: https://reviews.llvm.org/D152917
2023-04-13[lldb] Add RegisterFlags classDavid Spickett
This models the "flags" node from GDB's target XML: https://sourceware.org/gdb/onlinedocs/gdb/Target-Description-Format.html This node is used to describe the fields of registers like cpsr on AArch64. RegisterFlags is a class that contains a list of register fields. These fields will be extracted from the XML sent by the remote. We assume that there is at least one field, that the fields are sorted in descending order and do not overlap. That will be enforced by the XML processor (the GDB client code in our case). The fields may not cover the whole register. To account for this RegisterFields will add anonymous padding fields so that sizeof(all fields) == sizeof(register). This will save a lot of hasssle later. Reviewed By: jasonmolenda, JDevlieghere Differential Revision: https://reviews.llvm.org/D145566