<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/lldb/test/API/linux, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[LLDB][AArch64] Make TPIDR a generic tp register (#154444)</title>
<updated>2025-09-04T17:37:52+00:00</updated>
<author>
<name>Jacob Lalonde</name>
<email>jalalonde@fb.com</email>
</author>
<published>2025-09-04T17:37:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6505bc3db02913a44b630c60ed6068ed84100e60'/>
<id>6505bc3db02913a44b630c60ed6068ed84100e60</id>
<content type='text'>
Unlike x86, ARM doesn't support a generic thread pointer for TLS data,
so things like
```
reg read tp
...
memory read tp
```

Don't work, and you need to specify tpidr. This works, especially
because that's the name GDB uses. But for ease of use, and at the
request of @aperez I've made it so we can reference it via `tp`.

I personally don't have an aarch machine, and all the arm examples in
`Shell/Register/Core` are freebsd and don't contain tpidr, so I was
unable to add a shell test for this. I added a test to the AARCH
register tests, but without an Aarch machine I'm hoping these work.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Unlike x86, ARM doesn't support a generic thread pointer for TLS data,
so things like
```
reg read tp
...
memory read tp
```

Don't work, and you need to specify tpidr. This works, especially
because that's the name GDB uses. But for ease of use, and at the
request of @aperez I've made it so we can reference it via `tp`.

I personally don't have an aarch machine, and all the arm examples in
`Shell/Register/Core` are freebsd and don't contain tpidr, so I was
unable to add a shell test for this. I added a test to the AARCH
register tests, but without an Aarch machine I'm hoping these work.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64][Linux] Show MTE store only setting in mte_ctrl (#145033)</title>
<updated>2025-07-28T15:40:00+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-07-28T15:40:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=0209e76fe6440bc45a9ed61b9671d9593db10957'/>
<id>0209e76fe6440bc45a9ed61b9671d9593db10957</id>
<content type='text'>
This controls whether tag checking is performed for loads and 
stores, or stores only.

It requires a specific architecture feature which we detect
with a HWCAP3 and cpuinfo feature.

Live process tests look for this and adjust expectations
accordingly, core file tests are using an updated file with
this feature enabled.

The size of the core file has increased and there's nothing
I can do about that. Could be the presence of new architecure
features or kernel changes since I last generated them.

I can generate a smaller file that has the tag segment,
but that segment does not actually contain tag data. So
that's no use.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This controls whether tag checking is performed for loads and 
stores, or stores only.

It requires a specific architecture feature which we detect
with a HWCAP3 and cpuinfo feature.

Live process tests look for this and adjust expectations
accordingly, core file tests are using an updated file with
this feature enabled.

The size of the core file has increased and there's nothing
I can do about that. Could be the presence of new architecure
features or kernel changes since I last generated them.

I can generate a smaller file that has the tag segment,
but that segment does not actually contain tag data. So
that's no use.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64] Handle core file tag segments missing tag data (#145338)</title>
<updated>2025-06-25T09:31:38+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-06-25T09:31:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=3a3d1bf4a39bbbe1cfdc56ab9eeeb13cb438348a'/>
<id>3a3d1bf4a39bbbe1cfdc56ab9eeeb13cb438348a</id>
<content type='text'>
In the same way that memory regions may be known from a core file but
not readable, tag segments can also have no content. For example:
```
$ readelf --segments core
&lt;...&gt;
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
&lt;...&gt;
  LOAD           0x0000000000002000 0x0000ffff93899000 0x0000000000000000
                 0x0000000000000000 0x0000000000001000  RW     0x1000
&lt;...&gt;
  LOPROC+0x2     0x0000000000008000 0x0000ffff93899000 0x0000000000000000
                 0x0000000000000000 0x0000000000001000         0x0
```
This happens if you have a restricted coredump filter or size limit.

The area of virtual memory this segment covers is 0x1000, or 4096 bytes
aka one tagged page. It's FileSiz would normally be 0x80. Tags are
packed 2 per byte and granules are 16 bytes. 4096 / 16 / 2 = 128 or
0x80.

But here it has no data, and in theory a corrupt file might have some
data but not all. This triggered an assert in
UnpackTagsFromCoreFileSegment and crashed lldb.

To fix this I have made UnpackTagsFromCoreFileSegment return an expected
and returned an error in this case instead of asserting. This will be
seen by the user, as shown in the added API test.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In the same way that memory regions may be known from a core file but
not readable, tag segments can also have no content. For example:
```
$ readelf --segments core
&lt;...&gt;
Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
&lt;...&gt;
  LOAD           0x0000000000002000 0x0000ffff93899000 0x0000000000000000
                 0x0000000000000000 0x0000000000001000  RW     0x1000
&lt;...&gt;
  LOPROC+0x2     0x0000000000008000 0x0000ffff93899000 0x0000000000000000
                 0x0000000000000000 0x0000000000001000         0x0
```
This happens if you have a restricted coredump filter or size limit.

The area of virtual memory this segment covers is 0x1000, or 4096 bytes
aka one tagged page. It's FileSiz would normally be 0x80. Tags are
packed 2 per byte and granules are 16 bytes. 4096 / 16 / 2 = 128 or
0x80.

But here it has no data, and in theory a corrupt file might have some
data but not all. This triggered an assert in
UnpackTagsFromCoreFileSegment and crashed lldb.

To fix this I have made UnpackTagsFromCoreFileSegment return an expected
and returned an error in this case instead of asserting. This will be
seen by the user, as shown in the added API test.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][NFC] update API tests which skip/expect-fail arm</title>
<updated>2025-05-28T01:41:16+00:00</updated>
<author>
<name>Jason Molenda</name>
<email>jmolenda@apple.com</email>
</author>
<published>2025-05-28T01:37:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6d6feaf7e3ce559f69477b8d682cffb63336ca53'/>
<id>6d6feaf7e3ce559f69477b8d682cffb63336ca53</id>
<content type='text'>
The architectures provided to skipIf / expectedFail are regular
expressions (v. _match_decorator_property() in decorators.py
so on Darwin systems "arm64" would match the skips for "arm" (32-bit
Linux).  Update these to "arm$" to prevent this, and also update
three tests (TestBuiltinFormats.py, TestCrossDSOTailCalls.py,
TestCrossObjectTailCalls.py) that were skipped for arm64 via this
behavior, and need to be skipped or they will fail.

This was moviated by the new TestDynamicValue.py test which has
an expected-fail for arm, but the test was passing on arm64 Darwin
resulting in failure for the CIs.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The architectures provided to skipIf / expectedFail are regular
expressions (v. _match_decorator_property() in decorators.py
so on Darwin systems "arm64" would match the skips for "arm" (32-bit
Linux).  Update these to "arm$" to prevent this, and also update
three tests (TestBuiltinFormats.py, TestCrossDSOTailCalls.py,
TestCrossObjectTailCalls.py) that were skipped for arm64 via this
behavior, and need to be skipped or they will fail.

This was moviated by the new TestDynamicValue.py test which has
an expected-fail for arm, but the test was passing on arm64 Darwin
resulting in failure for the CIs.
</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] fix(lldb/**.py): fix invalid escape sequences (#94034)</title>
<updated>2025-02-28T14:59:35+00:00</updated>
<author>
<name>Eisuke Kawashima</name>
<email>e.kawaschima+github@gmail.com</email>
</author>
<published>2025-02-28T14:59:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=24abf2c7285df7b5c1b442df10cd0b090a841358'/>
<id>24abf2c7285df7b5c1b442df10cd0b090a841358</id>
<content type='text'>
Co-authored-by: Eisuke Kawashima &lt;e-kwsm@users.noreply.github.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Co-authored-by: Eisuke Kawashima &lt;e-kwsm@users.noreply.github.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64] Add register fields for Guarded Control Stack registers (#124295)</title>
<updated>2025-01-28T12:05:24+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-01-28T12:05:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=c5840cc609a3674cf7453a45946f7e4a2a73590b'/>
<id>c5840cc609a3674cf7453a45946f7e4a2a73590b</id>
<content type='text'>
The features and locked registers hold the same bits, the latter
is a lock for the former. Tested with core files and live processes.

I thought about setting a non-zero lock register in the core file,
however:
* We can be pretty sure it's reading correctly because its between
  the 2 other GCS registers in the same core file note.
* I can't make the test case modify lock bits because userspace
can't clear them (without using ptrace) and we don't know what the libc
has locked
  (probably all feature bits).</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The features and locked registers hold the same bits, the latter
is a lock for the former. Tested with core files and live processes.

I thought about setting a non-zero lock register in the core file,
however:
* We can be pretty sure it's reading correctly because its between
  the 2 other GCS registers in the same core file note.
* I can't make the test case modify lock bits because userspace
can't clear them (without using ptrace) and we don't know what the libc
has locked
  (probably all feature bits).</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64] Add Guarded Control Stack support for Linux core files (#124293)</title>
<updated>2025-01-28T11:32:24+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-01-28T11:32:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=75aa5a35568b9e0b3eabd1e7f991a6a0f5525e0c'/>
<id>75aa5a35568b9e0b3eabd1e7f991a6a0f5525e0c</id>
<content type='text'>
This allows you to read the same registers as you would for a live
process.

As the content of proc/pid/smaps is not included in the core file, we
don't get the "ss" marker that tell us that it is shadow stack. The GCS
region is still in the list though.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This allows you to read the same registers as you would for a live
process.

As the content of proc/pid/smaps is not included in the core file, we
don't get the "ss" marker that tell us that it is shadow stack. The GCS
region is still in the list though.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64][NFC] Move a comment in GCS tests</title>
<updated>2025-01-27T13:27:31+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-01-27T13:27:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=e9e06bea8661ddd474557a0db2cdc8770a55b66f'/>
<id>e9e06bea8661ddd474557a0db2cdc8770a55b66f</id>
<content type='text'>
Got put in the wrong place during a rebase.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Got put in the wrong place during a rebase.
</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64] Fix expression evaluation with Guarded Control Stacks (#123918)</title>
<updated>2025-01-27T13:06:33+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-01-27T13:06:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=b31e9747d0866ff97a1cd4a608b7eade31c0aa0b'/>
<id>b31e9747d0866ff97a1cd4a608b7eade31c0aa0b</id>
<content type='text'>
When the Guarded Control Stack (GCS) is enabled, returns cause the
processor to validate that the address at the location pointed to by
gcspr_el0 matches the one in the link register.

```
ret (lr=A) &lt;&lt; pc

| GCS |
+=====+
|  A  |
|  B  | &lt;&lt; gcspr_el0

Fault: tried to return to A when you should have returned to B.
```

Therefore when an expression wrapper function tries to return to the
expression return address (usually `_start` if there is a libc), it
would fault.

```
ret (lr=_start) &lt;&lt; pc

| GCS        |
+============+
| user_func1 |
| user_func2 | &lt;&lt; gcspr_el0

Fault: tried to return to _start when you should have returned to user_func2.
```

To fix this we must push that return address to the GCS in
PrepareTrivialCall. This value is then consumed by the final return and
the expression completes as expected.

If for some reason that fails, we will manually restore the value of
gcspr_el0, because it turns out that PrepareTrivialCall
does not restore registers if it fails at all. So for now I am handling
gcspr_el0 specifically, but I have filed
https://github.com/llvm/llvm-project/issues/124269 to address the
general problem.

(the other things PrepareTrivialCall does are exceedingly likely to not
fail, so we have never noticed this)

```
ret (lr=_start) &lt;&lt; pc

| GCS        |
+============+
| user_func1 |
| user_func2 |
| _start     | &lt;&lt; gcspr_el0

No fault, we return to _start as normal.
```

The gcspr_el0 register will be restored after expression evaluation so
that the program can continue correctly.

However, due to restrictions in the Linux GCS ABI, we will not restore
the enable bit of gcs_features_enabled. Re-enabling GCS via ptrace is
not supported because it requires memory to be allocated by the kernel.

We could disable GCS if the expression enabled GCS, however this would
use up that state transition that the program might later rely on. And
generally it is cleaner to ignore the enable bit, rather than one state
transition of it.

We will also not restore the GCS entry that was overwritten with the
expression's return address. On the grounds that:
* This entry will never be used by the program. If the program branches,
the entry will be overwritten. If the program returns, gcspr_el0 will
point to the entry before the expression return address and that entry
will instead be validated.
* Any expression that calls functions will overwrite even more entries,
so the user needs to be aware of that anyway if they want to preserve
the contents of the GCS for inspection.
* An expression could leave the program in a state where restoring the
value makes the situation worse. Especially if we ever support this in
bare metal debugging.

I will later document all this on
https://lldb.llvm.org/use/aarch64-linux.html.

Tests have been added for:
* A function call that does not interact with GCS.
* A call that does, and disables it (we do not re-enable it).
* A call that does, and enables it (we do not disable it again).
* Failure to push an entry to the GCS stack.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When the Guarded Control Stack (GCS) is enabled, returns cause the
processor to validate that the address at the location pointed to by
gcspr_el0 matches the one in the link register.

```
ret (lr=A) &lt;&lt; pc

| GCS |
+=====+
|  A  |
|  B  | &lt;&lt; gcspr_el0

Fault: tried to return to A when you should have returned to B.
```

Therefore when an expression wrapper function tries to return to the
expression return address (usually `_start` if there is a libc), it
would fault.

```
ret (lr=_start) &lt;&lt; pc

| GCS        |
+============+
| user_func1 |
| user_func2 | &lt;&lt; gcspr_el0

Fault: tried to return to _start when you should have returned to user_func2.
```

To fix this we must push that return address to the GCS in
PrepareTrivialCall. This value is then consumed by the final return and
the expression completes as expected.

If for some reason that fails, we will manually restore the value of
gcspr_el0, because it turns out that PrepareTrivialCall
does not restore registers if it fails at all. So for now I am handling
gcspr_el0 specifically, but I have filed
https://github.com/llvm/llvm-project/issues/124269 to address the
general problem.

(the other things PrepareTrivialCall does are exceedingly likely to not
fail, so we have never noticed this)

```
ret (lr=_start) &lt;&lt; pc

| GCS        |
+============+
| user_func1 |
| user_func2 |
| _start     | &lt;&lt; gcspr_el0

No fault, we return to _start as normal.
```

The gcspr_el0 register will be restored after expression evaluation so
that the program can continue correctly.

However, due to restrictions in the Linux GCS ABI, we will not restore
the enable bit of gcs_features_enabled. Re-enabling GCS via ptrace is
not supported because it requires memory to be allocated by the kernel.

We could disable GCS if the expression enabled GCS, however this would
use up that state transition that the program might later rely on. And
generally it is cleaner to ignore the enable bit, rather than one state
transition of it.

We will also not restore the GCS entry that was overwritten with the
expression's return address. On the grounds that:
* This entry will never be used by the program. If the program branches,
the entry will be overwritten. If the program returns, gcspr_el0 will
point to the entry before the expression return address and that entry
will instead be validated.
* Any expression that calls functions will overwrite even more entries,
so the user needs to be aware of that anyway if they want to preserve
the contents of the GCS for inspection.
* An expression could leave the program in a state where restoring the
value makes the situation worse. Especially if we ever support this in
bare metal debugging.

I will later document all this on
https://lldb.llvm.org/use/aarch64-linux.html.

Tests have been added for:
* A function call that does not interact with GCS.
* A call that does, and disables it (we do not re-enable it).
* A call that does, and enables it (we do not disable it again).
* Failure to push an entry to the GCS stack.</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb][AArch64] Add Guarded Control Stack registers (#123720)</title>
<updated>2025-01-24T13:42:06+00:00</updated>
<author>
<name>David Spickett</name>
<email>david.spickett@linaro.org</email>
</author>
<published>2025-01-24T13:42:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=02c6002d1cd2dabe4b98368f91e7b4395e5ab11d'/>
<id>02c6002d1cd2dabe4b98368f91e7b4395e5ab11d</id>
<content type='text'>
The Guarded Control Stack extension implements a shadow stack and the
Linux kernel provides access to 3 registers for it via ptrace.

struct user_gcs {
	__u64 features_enabled;
	__u64 features_locked;
	__u64 gcspr_el0;
};

This commit adds support for reading those from a live process.

The first 2 are pseudo registers based on the real control register and
the 3rd is a real register. This is the stack pointer for the guarded
stack.

I have added a "gcs_" prefix to the "features" registers so that they
have a clear name when shown individually. Also this means they will tab
complete from "gcs", and be next to gcspr_el0 in any sorted lists of
registers.

Guarded Control Stack Registers:
  gcs_features_enabled = 0x0000000000000000
  gcs_features_locked = 0x0000000000000000
  gcspr_el0 = 0x0000000000000000

Testing is more of the usual, where possible I'm writing a register then
doing something in the program to confirm the value was actually sent to
ptrace.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The Guarded Control Stack extension implements a shadow stack and the
Linux kernel provides access to 3 registers for it via ptrace.

struct user_gcs {
	__u64 features_enabled;
	__u64 features_locked;
	__u64 gcspr_el0;
};

This commit adds support for reading those from a live process.

The first 2 are pseudo registers based on the real control register and
the 3rd is a real register. This is the stack pointer for the guarded
stack.

I have added a "gcs_" prefix to the "features" registers so that they
have a clear name when shown individually. Also this means they will tab
complete from "gcs", and be next to gcspr_el0 in any sorted lists of
registers.

Guarded Control Stack Registers:
  gcs_features_enabled = 0x0000000000000000
  gcs_features_locked = 0x0000000000000000
  gcspr_el0 = 0x0000000000000000

Testing is more of the usual, where possible I'm writing a register then
doing something in the program to confirm the value was actually sent to
ptrace.</pre>
</div>
</content>
</entry>
</feed>
