[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