[RuntimeDyld][COFF] Apply addend for IMAGE_REL_AMD64_SECREL (#211015)

`IMAGE_REL_AMD64_SECREL` currently falls through the default case. Its
`Addend` is built using the target symbol's section offset. This is
incorrect: for a SECREL against a section symbol (offset 0), the real
value is stored as the addend in the relocated field. This results in
the SECREL writer always writing 0, which is wrong.

This patch reads the 4-byte field addend for SECREL, as `REL32` and
`ADDR64` already do. It also adds a test which fails without this.

Source: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
This commit is contained in:
Charles Zablit 2026-07-22 17:28:05 +02:00 committed by GitHub
parent da26ba882a
commit 9ca28bddf6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 31 additions and 0 deletions

View file

@ -266,6 +266,12 @@ public:
break;
}
case COFF::IMAGE_REL_AMD64_SECREL: {
uint8_t *Displacement = (uint8_t *)ObjTarget;
Addend = readBytesUnaligned(Displacement, 4);
break;
}
default:
break;
}

View file

@ -0,0 +1,25 @@
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -triple=x86_64-pc-win32 -filetype=obj -o %t/COFF_x86_64_SECREL.o %s
# RUN: llvm-rtdyld -triple=x86_64-pc-win32 -verify -check=%s %t/COFF_x86_64_SECREL.o
.section .rdata,"dr"
sec_base: # section-relative offset 0
.zero 0x10
target: # section-relative offset 0x10
.long 0
.data
.globl relocations
relocations:
sr_symoff:
.secrel32 target
# rtdyld-check: *{4}sr_symoff = 0x10
sr_addend:
.secrel32 sec_base+0x2a
# rtdyld-check: *{4}sr_addend = 0x2a
sr_both:
.secrel32 target+0x2a
# rtdyld-check: *{4}sr_both = 0x3a