[all-commits] [llvm/llvm-project] 45d988: [lldb] Add "memory tag write" command

David Spickett via All-commits all-commits at lists.llvm.org
Tue Aug 3 06:52:52 PDT 2021


  Branch: refs/heads/release/13.x
  Home:   https://github.com/llvm/llvm-project
  Commit: 45d98857f8f979552d7e1e7e781d6ca92a5e9a48
      https://github.com/llvm/llvm-project/commit/45d98857f8f979552d7e1e7e781d6ca92a5e9a48
  Author: David Spickett <david.spickett at linaro.org>
  Date:   2021-08-03 (Tue, 03 Aug 2021)

  Changed paths:
    M lldb/source/Commands/CommandObjectMemoryTag.cpp
    M lldb/test/API/functionalities/memory/tag/TestMemoryTag.py
    A lldb/test/API/linux/aarch64/mte_tag_access/Makefile
    A lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py
    A lldb/test/API/linux/aarch64/mte_tag_access/main.c
    R lldb/test/API/linux/aarch64/mte_tag_read/Makefile
    R lldb/test/API/linux/aarch64/mte_tag_read/TestAArch64LinuxMTEMemoryTagRead.py
    R lldb/test/API/linux/aarch64/mte_tag_read/main.c

  Log Message:
  -----------
  [lldb] Add "memory tag write" command

This adds a new command for writing memory tags.
It is based on the existing "memory write" command.

Syntax: memory tag write <address-expression> <value> [<value> [...]]
(where "value" is a tag value)

(lldb) memory tag write mte_buf 1 2
(lldb) memory tag read mte_buf mte_buf+32
Logical tag: 0x0
Allocation tags:
[0xfffff7ff9000, 0xfffff7ff9010): 0x1
[0xfffff7ff9010, 0xfffff7ff9020): 0x2

The range you are writing to will be calculated by
aligning the address down to a granule boundary then
adding as many granules as there are tags.

(a repeating mode with an end address will be in a follow
up patch)

This is why "memory tag write" uses MakeTaggedRange but has
some extra steps to get this specific behaviour.

The command does all the usual argument validation:
* Address must evaluate
* You must supply at least one tag value
  (though lldb-server would just treat that as a nop anyway)
* Those tag values must be valid for your tagging scheme
  (e.g. for MTE the value must be > 0 and < 0xf)
* The calculated range must be memory tagged

That last error will show you the final range, not just
the start address you gave the command.

(lldb) memory tag write mte_buf_2+page_size-16 6
(lldb) memory tag write mte_buf_2+page_size-16 6 7
error: Address range 0xfffff7ffaff0:0xfffff7ffb010 is not in a memory tagged region

(note that we do not check if the region is writeable
since lldb can write to it anyway)

The read and write tag tests have been merged into
a single set of "tag access" tests as their test programs would
have been almost identical.
(also I have renamed some of the buffers to better
show what each one is used for)

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D105182

(cherry picked from commit 6a7a2ee8161da84d9a58a88b497b0b47c8df99f3)


  Commit: dc00e1915e66533de4b9c778528e8dd7b4922a22
      https://github.com/llvm/llvm-project/commit/dc00e1915e66533de4b9c778528e8dd7b4922a22
  Author: David Spickett <david.spickett at linaro.org>
  Date:   2021-08-03 (Tue, 03 Aug 2021)

  Changed paths:
    M lldb/source/Commands/CommandObjectMemoryTag.cpp
    M lldb/source/Commands/Options.td
    M lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py

  Log Message:
  -----------
  [lldb] Add "memory tag write" --end-addr option

The default mode of "memory tag write" is to calculate the
range from the start address and the number of tags given.
(just like "memory write" does)

(lldb) memory tag write mte_buf 1 2
(lldb) memory tag read mte_buf mte_buf+48
Logical tag: 0x0
Allocation tags:
[0xfffff7ff9000, 0xfffff7ff9010): 0x1
[0xfffff7ff9010, 0xfffff7ff9020): 0x2
[0xfffff7ff9020, 0xfffff7ff9030): 0x0

This new option allows you to set an end address and have
the tags repeat until that point.

(lldb) memory tag write mte_buf 1 2 --end-addr mte_buf+64
(lldb) memory tag read mte_buf mte_buf+80
Logical tag: 0x0
Allocation tags:
[0xfffff7ff9000, 0xfffff7ff9010): 0x1
[0xfffff7ff9010, 0xfffff7ff9020): 0x2
[0xfffff7ff9020, 0xfffff7ff9030): 0x1
[0xfffff7ff9030, 0xfffff7ff9040): 0x2
[0xfffff7ff9040, 0xfffff7ff9050): 0x0

This is implemented using the QMemTags packet previously
added. We skip validating the number of tags in lldb and send
them on to lldb-server, which repeats them as needed.

Apart from the number of tags, all the other client side checks
remain. Tag values, memory range must be tagged, etc.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D105183

(cherry picked from commit 6eded00e0c6b4e06225df74292c078030556b8ce)


  Commit: bc0cc109dfa744090f7ba35fe91d5967f0ed4fc7
      https://github.com/llvm/llvm-project/commit/bc0cc109dfa744090f7ba35fe91d5967f0ed4fc7
  Author: David Spickett <david.spickett at linaro.org>
  Date:   2021-08-03 (Tue, 03 Aug 2021)

  Changed paths:
    M lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
    M lldb/source/Plugins/Process/Linux/NativeThreadLinux.h
    A lldb/test/API/linux/aarch64/mte_tag_faults/Makefile
    A lldb/test/API/linux/aarch64/mte_tag_faults/TestAArch64LinuxMTEMemoryTagFaults.py
    A lldb/test/API/linux/aarch64/mte_tag_faults/main.c

  Log Message:
  -----------
  [lldb][AArch64] Annotate synchronous tag faults

In the latest Linux kernels synchronous tag faults
include the tag bits in their address.
This change adds logical and allocation tags to the
description of synchronous tag faults.
(asynchronous faults have no address)

Process 1626 stopped
* thread #1, name = 'a.out', stop reason = signal SIGSEGV: sync tag check fault (fault address: 0x900fffff7ff9010 logical tag: 0x9 allocation tag: 0x0)

This extends the existing description and will
show as much as it can on the rare occasion something
fails.

This change supports AArch64 MTE only but other
architectures could be added by extending the
switch at the start of AnnotateSyncTagCheckFault.
The rest of the function is generic code.

Tests have been added for synchronous and asynchronous
MTE faults.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D105178

(cherry picked from commit d510b5f199d6e7a3062b5a6ea43181c4cc00a605)


  Commit: c47d79b3b7a7cab21020ec69b66b5f48823f513f
      https://github.com/llvm/llvm-project/commit/c47d79b3b7a7cab21020ec69b66b5f48823f513f
  Author: David Spickett <david.spickett at linaro.org>
  Date:   2021-08-03 (Tue, 03 Aug 2021)

  Changed paths:
    M lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    M lldb/test/API/tools/lldb-server/memory-tagging/TestGdbRemoteMemoryTagging.py
    M lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp

  Log Message:
  -----------
  [lldb] Correct format of qMemTags type field

The type field is a signed integer.
(https://sourceware.org/gdb/current/onlinedocs/gdb/General-Query-Packets.html)

However it's not packed in the packet in the way
you might think. For example the type -1 should be:
qMemTags:<addr>,<len>:ffffffff
Instead of:
qMemTags:<addr>,<len>:-1

This change makes lldb-server's parsing more strict
and adds more tests to check that we handle negative types
correctly in lldb and lldb-server.

We only support one tag type value at this point,
for AArch64 MTE, which is positive. So this doesn't change
any of those interactions. It just brings us in line with GDB.

Also check that the test target has MTE. Previously
we just checked that we were AArch64 with a toolchain
that supports MTE.

Finally, update the tag type check for QMemTags to use
the same conversion steps that qMemTags now does.
Using static_cast can invoke UB and though we do do a limit
check to avoid this, I think it's clearer with the new method.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D104914

(cherry picked from commit 555cd03193c9c098d787bec93eadfe43b179db9c)


  Commit: 0b8dc914e1bd02ed34b4b50d3de81f2162c4402f
      https://github.com/llvm/llvm-project/commit/0b8dc914e1bd02ed34b4b50d3de81f2162c4402f
  Author: David Spickett <david.spickett at linaro.org>
  Date:   2021-08-03 (Tue, 03 Aug 2021)

  Changed paths:
    M lldb/source/Commands/CommandObjectMemoryTag.cpp
    M lldb/test/API/linux/aarch64/mte_tag_access/TestAArch64LinuxMTEMemoryTagAccess.py

  Log Message:
  -----------
  [lldb][AArch64] Mark mismatched tags in tag read output

The "memory tag read" command will now tell you
when the allocation tag read does not match the logical
tag.

(lldb) memory tag read mte_buf+(8*16) mte_buf+(8*16)+48
Logical tag: 0x9
Allocation tags:
[0xfffff7ff7080, 0xfffff7ff7090): 0x8 (mismatch)
[0xfffff7ff7090, 0xfffff7ff70a0): 0x9
[0xfffff7ff70a0, 0xfffff7ff70b0): 0xa (mismatch)

The logical tag will be taken from the start address
so the end could have a different tag. You could for example
read from ptr_to_array_1 to ptr_to_array_2. Where the latter
is tagged differently to prevent buffer overflow.

The existing command will read 1 granule if you leave
off the end address. So you can also use it as a quick way
to check a single location.

(lldb) memory tag read mte_buf
Logical tag: 0x9
Allocation tags:
[0xfffff7ff7000, 0xfffff7ff7010): 0x0 (mismatch)

This avoids the need for a seperate "memory tag check" command.

Reviewed By: omjavaid

Differential Revision: https://reviews.llvm.org/D106880

(cherry picked from commit 98b5659b53ff93f3b68e48ea28ec54081196ae3b)


  Commit: 11a0a68f2eb8f419f2faab380c8af73dbea4035c
      https://github.com/llvm/llvm-project/commit/11a0a68f2eb8f419f2faab380c8af73dbea4035c
  Author: David Spickett <david.spickett at linaro.org>
  Date:   2021-08-03 (Tue, 03 Aug 2021)

  Changed paths:
    M llvm/docs/ReleaseNotes.rst

  Log Message:
  -----------
  [llvm][Release notes] Add memory tagging support to lldb changes


Compare: https://github.com/llvm/llvm-project/compare/4ae33534bd8c...11a0a68f2eb8


More information about the All-commits mailing list