amd64: fix GOT-indirect addressing bug in dictionary fast-path lookup
vm_find_word() and dict_find_word_heat_aware() reference the same extern globals (sf_fc_list/sf_fc_count/sf_fc_cap) but GCC compiled cross-TU references to them with GOT-indirect addressing (R_X86_64_REX_GOTPCRELX) under -fPIC. This freestanding, statically-linked UEFI PE image has no dynamic linker to populate a GOT, so those reads silently returned NULL instead of the array's real address -- amd64-only, and exquisitely sensitive to unrelated code-size changes since the choice between direct and GOT-indirect addressing is a per-call-site GCC heuristic. Fix: -fno-pic -fno-pie for amd64 only (ARCH_CFLAGS, overriding COMMON_CFLAGS's -fPIC, which riscv64's -shared loader link still needs). Also removes -DPLATFORM_TIME_NO_INLINE, a prior one-off workaround for the identical bug applied to sf_monotonic_ns() specifically, now redundant. Adds R_X86_64_PC32/R_X86_64_PLT32 handling to elf_apply_relocations() as a robustness fix for the non-monolithic split-build path (dead code for the current monolithic boot, where OVMF's own PE loader relocates the image, not this loader). Verified: all three architectures boot clean and pass the full item-4.2 Hermes self-test, including MSG-DELIVER-ALL, which previously triggered the corruption on amd64 only. Write-up in FABRIC.md under item 4.2. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
56ad128e2e
commit
0a7f144367
@@ -226,6 +226,10 @@ static int elf_load_segments(const uint8_t *elf_data, Elf64_Addr load_base)
|
||||
* - @c R_X86_64_RELATIVE — absolute address = @c load_base + @c r_addend.
|
||||
* - @c R_X86_64_64 — @c load_base + symbol value + @c r_addend (64-bit).
|
||||
* - @c R_X86_64_32 / @c R_X86_64_32S — same, truncated to 32 bits.
|
||||
* - @c R_X86_64_PC32 / @c R_X86_64_PLT32 — @c symbol + @c r_addend - P
|
||||
* (PC-relative, 32 bits), where P is the relocation's own runtime
|
||||
* address; PLT32 has no real PLT indirection in this static, non-PIE
|
||||
* link, so it resolves the same as PC32.
|
||||
*
|
||||
* - **aarch64 (@c ARCH_AARCH64)**:
|
||||
* - @c R_AARCH64_NONE — no-op.
|
||||
@@ -301,6 +305,19 @@ static int elf_apply_relocations(const uint8_t *elf_data, Elf64_Addr load_base)
|
||||
*target32 = (uint32_t)value;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32: {
|
||||
/* value = S + A - P, where P is the address of the relocation
|
||||
* itself (reloc_addr already includes load_base). PLT32 is
|
||||
* treated identically to PC32: this is a static, non-PIE
|
||||
* link with every symbol resolved in-image, so there is no
|
||||
* real PLT indirection to apply. */
|
||||
uint32_t *target32 = (uint32_t *)reloc_addr;
|
||||
int64_t value = (int64_t)(load_base + sym_value + rela[j].r_addend) -
|
||||
(int64_t)reloc_addr;
|
||||
*target32 = (uint32_t)value;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user