[LLD][COFF] Fix absolute & synthetic symbols in COFF symbol table

Absolute symbol should contain its absolute value, but LLD had been
writing its RVA instead. Write its VA instead.

DefinedSynthetic were being skipped before with the reasoning "Relative
symbols are unrepresentable in a COFF symbol table", which is only true
if the RVA points to outside of a section. LLD does create synthetic
symbols which points to actual data chunks (typical for symbols embedded
into the load config directory). Write these symbols to the COFF symbol
table too.

Reviewed By: mstorsjo

Differential Revision: https://reviews.llvm.org/D134462
This commit is contained in:
Alvin Wong 2022-09-26 10:40:51 +03:00 committed by Martin Storsjö
parent a096164134
commit 37bd099daf
5 changed files with 71 additions and 14 deletions

View File

@ -1140,16 +1140,20 @@ size_t Writer::addEntryToStringTable(StringRef str) {
Optional<coff_symbol16> Writer::createSymbol(Defined *def) {
coff_symbol16 sym;
switch (def->kind()) {
case Symbol::DefinedAbsoluteKind:
sym.Value = def->getRVA();
case Symbol::DefinedAbsoluteKind: {
auto *da = dyn_cast<DefinedAbsolute>(def);
// Note: COFF symbol can only store 32-bit values, so 64-bit absolute
// values will be truncated.
sym.Value = da->getVA();
sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
break;
case Symbol::DefinedSyntheticKind:
// Relative symbols are unrepresentable in a COFF symbol table.
return None;
}
default: {
// Don't write symbols that won't be written to the output to the symbol
// table.
// We also try to write DefinedSynthetic as a normal symbol. Some of these
// symbols do point to an actual chunk, like __safe_se_handler_table. Others
// like __ImageBase are outside of sections and thus cannot be represented.
Chunk *c = def->getChunk();
if (!c)
return None;

View File

@ -0,0 +1,53 @@
# REQUIRES: x86
# The __guard_fids_table is a DefinedSynthetic when control flow guard is
# enabled and there are entries to be added to the fids table. This test uses
# this to check that DefinedSynthetic symbols are being written to the COFF
# symbol table.
# RUN: llvm-mc -triple x86_64-windows-msvc %s -filetype=obj -o %t.obj
# RUN: lld-link %t.obj -guard:cf -out:%t.exe -entry:main -debug:symtab
# RUN: llvm-readobj --symbols %t.exe | FileCheck --check-prefix=CHECK %s
# CHECK: Name: __guard_fids_table
# CHECK-NEXT: Value:
# CHECK-NEXT: Section: .rdata (2)
# We need @feat.00 to have 0x800 to indicate /guard:cf.
.def @feat.00;
.scl 3;
.type 0;
.endef
.globl @feat.00
@feat.00 = 0x800
.def main; .scl 2; .type 32; .endef
.globl main # -- Begin function main
.p2align 4, 0x90
main:
retq
# -- End function
.section .gfids$y,"dr"
.symidx main
.section .giats$y,"dr"
.section .gljmp$y,"dr"
.addrsig_sym main
.section .rdata,"dr"
.globl _load_config_used
.p2align 3
_load_config_used:
.long 312
.fill 124, 1, 0
.quad __guard_fids_table
.quad __guard_fids_count
.long __guard_flags
.fill 12, 1, 0
.quad __guard_iat_table
.quad __guard_iat_count
.quad __guard_longjmp_table
.quad __guard_longjmp_count
.fill 72, 1, 0
.quad __guard_eh_cont_table
.quad __guard_eh_cont_count
.fill 32, 1, 0

View File

@ -75,7 +75,7 @@
# CHECK-NEXT: }
# CHECK-NEXT: Symbol {
# CHECK-NEXT: Name: abs_symbol
# CHECK-NEXT: Value: 2662186735
# CHECK-NEXT: Value: 3735928559
# CHECK-NEXT: Section: IMAGE_SYM_ABSOLUTE (-1)
# CHECK-NEXT: BaseType: Null (0x0)
# CHECK-NEXT: ComplexType: Null (0x0)

View File

@ -16,16 +16,16 @@
// RUN: FileCheck --check-prefix=SYM2 %s < %t.dump
// RUN: FileCheck --check-prefix=SYM3 %s < %t.dump
// _foo = 0xffc11000 = 4290842624
// ___wrap_foo = ffc11010 = 4290842640
// _foo = 0x00011000 = 69632
// ___wrap_foo = 0x00011010 = 69648
// SYM1: Name: _foo
// SYM1-NEXT: Value: 4290842624
// SYM1-NEXT: Value: 69632
// SYM1-NEXT: Section: IMAGE_SYM_ABSOLUTE
// SYM1-NEXT: BaseType: Null
// SYM1-NEXT: ComplexType: Null
// SYM1-NEXT: StorageClass: External
// SYM2: Name: ___wrap_foo
// SYM2-NEXT: Value: 4290842640
// SYM2-NEXT: Value: 69648
// SYM2-NEXT: Section: IMAGE_SYM_ABSOLUTE
// SYM2-NEXT: BaseType: Null
// SYM2-NEXT: ComplexType: Null

View File

@ -18,16 +18,16 @@
// RUN: FileCheck --check-prefix=SYM2 %s < %t.dump
// RUN: FileCheck --check-prefix=SYM3 %s < %t.dump
// foo = 0xC0011000 = 3221295104
// __wrap_foo = 0xC0011010 = 3221295120
// foo = 0x00011000 = 69632
// __wrap_foo = 0x00011010 = 69648
// SYM1: Name: foo
// SYM1-NEXT: Value: 3221295104
// SYM1-NEXT: Value: 69632
// SYM1-NEXT: Section: IMAGE_SYM_ABSOLUTE
// SYM1-NEXT: BaseType: Null
// SYM1-NEXT: ComplexType: Null
// SYM1-NEXT: StorageClass: External
// SYM2: Name: __wrap_foo
// SYM2-NEXT: Value: 3221295120
// SYM2-NEXT: Value: 69648
// SYM2-NEXT: Section: IMAGE_SYM_ABSOLUTE
// SYM2-NEXT: BaseType: Null
// SYM2-NEXT: ComplexType: Null