[llvm] [CAS] Add MappedFileRegionArena (PR #114099)

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 16 03:46:21 PDT 2025


DavidSpickett wrote:

I've reproduced it. Getting a debug build on 32-bit is nigh on impossible these days so this is a bit of guess work.

```
   0x0047390c <+1556>:	b	0x473b08 <_ZN4llvm3cas21MappedFileRegionArena6createERKNS_5TwineEyyNS_12function_refIFNS_5ErrorERS1_EEE+2064>
   0x00473910 <+1560>:	ldr	r0, [sp, #536]	@ 0x218
   0x00473914 <+1564>:	add	r5, r0, #24
=> 0x00473918 <+1568>:	ldrexd	r2, [r5]
```
This is where some thread crashes. I think it crashing then causes the assert failure in the main thread.

This is doing:
> LDREXD (Load Registers Doubleword Exclusive) loads a doubleword from memory, and either:
> ...
> This instruction has a doubleword alignment requirement, and generates alignment faults if it is not met if (A, U) == (0, 1), (1, 0) or (1, 1) in CP15 register 1.

We load from `r5`, which is:
```
(gdb) p/x $r5
$1 = 0xfffee43c
```
C = 12 so we are not 8 byte aligned here.

https://developer.arm.com/documentation/ddi0360/e/programmer-s-model/additional-instructions/ldrexd

I think this is generated from:
```
  // Initialize the header.
  Result.initializeHeader(HeaderOffset);
  if (FileSize->Size < MinCapacity) {
    assert(MainFile->Locked == sys::fs::LockKind::Exclusive);
    // If we need to fully initialize the file, call NewFileConstructor.
    if (Error E = NewFileConstructor(Result))
      return std::move(E);

    Result.H->HeaderOffset.exchange(HeaderOffset);
    Result.H->Capacity.exchange(Capacity);
  }
```
And I suspect it's the HeaderOffset member of:
```
  /// Header for MappedFileRegionArena. It can be configured to be located
  /// at any location within the file and the allocation will be appended after
  /// the header.
  struct Header {
    // BumpPtr for new allocation.
    std::atomic<uint64_t> BumpPtr;
    // Allocated size on disk.
    std::atomic<uint64_t> AllocatedSize;
    // Capacity of the file.
    std::atomic<uint64_t> Capacity;
    // Offset from the beginning of the file to this header (for verification).
    std::atomic<uint64_t> HeaderOffset;
  };
```
If we assume that `r0` is the base address of the header, `#24` on from that is HeaderOffset.

So:
```
It can be configured to be located at any location within the file and the allocation will be appended after...
```
Cannot be totally true, it must be at the correct alignment for these types. Maybe you intended it to be, and there's an ABI difference on Arm 32-bit that breaks this assumption. E.g. a size_t next to a uint64_t.

I'll try a few things but I need to look at this header offset math first.

https://github.com/llvm/llvm-project/pull/114099


More information about the llvm-commits mailing list