[llvm] faf6ba4 - [llvm-readobj][COFF] Implement --coff-pseudoreloc in llvm-readobj to dump runtime pseudo-relocation records (#151816)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 27 13:16:46 PDT 2025


Author: Tomohiro Kashiwada
Date: 2025-08-27T23:16:42+03:00
New Revision: faf6ba47bf90be1a2c3dbcf02927f1e262c69c32

URL: https://github.com/llvm/llvm-project/commit/faf6ba47bf90be1a2c3dbcf02927f1e262c69c32
DIFF: https://github.com/llvm/llvm-project/commit/faf6ba47bf90be1a2c3dbcf02927f1e262c69c32.diff

LOG: [llvm-readobj][COFF] Implement --coff-pseudoreloc in llvm-readobj to dump runtime pseudo-relocation records (#151816)

MinGW toolchain uses "runtime pseudo-relocation" mechanism to support
auto-importing symbols from DLLs.
There is no commonly used tools for dump the pseudo-relocation records,
so we implement that functionality in llvm-readobj.

Added: 
    llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.i386.yaml
    llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.x86_64.yaml
    llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test

Modified: 
    llvm/tools/llvm-readobj/COFFDumper.cpp
    llvm/tools/llvm-readobj/ObjDumper.h
    llvm/tools/llvm-readobj/Opts.td
    llvm/tools/llvm-readobj/llvm-readobj.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.i386.yaml b/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.i386.yaml
new file mode 100644
index 0000000000000..9eb56dd7f9794
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.i386.yaml
@@ -0,0 +1,123 @@
+--- !COFF
+OptionalHeader:
+  AddressOfEntryPoint: 4096
+  ImageBase:       4194304
+  SectionAlignment: 4096
+  FileAlignment:   512
+  MajorOperatingSystemVersion: 6
+  MinorOperatingSystemVersion: 0
+  MajorImageVersion: 0
+  MinorImageVersion: 0
+  MajorSubsystemVersion: 6
+  MinorSubsystemVersion: 0
+  Subsystem:       IMAGE_SUBSYSTEM_WINDOWS_CUI
+  DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
+  SizeOfStackReserve: 1048576
+  SizeOfStackCommit: 4096
+  SizeOfHeapReserve: 1048576
+  SizeOfHeapCommit: 4096
+  ExportTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ImportTable:
+    RelativeVirtualAddress: 8288
+    Size:            60
+  ResourceTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ExceptionTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  CertificateTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  BaseRelocationTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  Debug:
+    RelativeVirtualAddress: 0
+    Size:            0
+  Architecture:
+    RelativeVirtualAddress: 0
+    Size:            0
+  GlobalPtr:
+    RelativeVirtualAddress: 0
+    Size:            0
+  TlsTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  LoadConfigTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  BoundImport:
+    RelativeVirtualAddress: 0
+    Size:            0
+  IAT:
+    RelativeVirtualAddress: 8368
+    Size:            20
+  DelayImportDescriptor:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ClrRuntimeHeader:
+    RelativeVirtualAddress: 0
+    Size:            0
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [ IMAGE_FILE_RELOCS_STRIPPED, IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_32BIT_MACHINE ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  4096
+    VirtualSize:     60
+    SectionData:     A1003040000FBE008B0D043040000FBE0901C1A1083040000FBE10A1103040000FBE0001D001C8C39090909090909090A1502040002B0508204000C3
+    SizeOfRawData:   512
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  8192
+    VirtualSize:     254
+    SectionData:     3377115566228844000000000000000001000000[[SYMBOL0=B0200000]]0030000020000000[[SYMBOL1=B4200000]]0430000020000000[[SYMBOL2=BC200000]]0830000020000000BC2000000C30000020000000B02000001030000020000000FFFFFFFF00000000FFFFFFFF000000009C2000000000000000000000DC200000B0200000A82000000000000000000000ED200000BC2000000000000000000000000000000000000000000000C4200000CC20000000000000D420000000000000C4200000CC20000000000000D420000000000000000073796D310000000073796D320000000073796D3300006578706F7274312E693338362E646C6C006578706F7274322E693338362E646C6C00
+    SizeOfRawData:   512
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    VirtualAddress:  12288
+    VirtualSize:     20
+    SectionData:     B1204000B6204000BD204000BD204000B2204000
+    SizeOfRawData:   512
+symbols:
+  - Name:            _start
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _local2a
+    Value:           4
+    SectionNumber:   [[SECTION_OF_LOCAL2A=3]]
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _local3a
+    Value:           8
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            __pei386_runtime_relocator
+    Value:           48
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            ___RUNTIME_PSEUDO_RELOC_LIST_END__
+    Value:           [[END=80]]
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            ___RUNTIME_PSEUDO_RELOC_LIST__
+    Value:           [[BEGIN=8]]
+    SectionNumber:   [[SECTION_OF_BEGIN=2]]
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

diff  --git a/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.x86_64.yaml b/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.x86_64.yaml
new file mode 100644
index 0000000000000..e31f61c17fd3d
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/Inputs/pseudoreloc.x86_64.yaml
@@ -0,0 +1,123 @@
+--- !COFF
+OptionalHeader:
+  AddressOfEntryPoint: 4096
+  ImageBase:       5368709120
+  SectionAlignment: 4096
+  FileAlignment:   512
+  MajorOperatingSystemVersion: 6
+  MinorOperatingSystemVersion: 0
+  MajorImageVersion: 0
+  MinorImageVersion: 0
+  MajorSubsystemVersion: 6
+  MinorSubsystemVersion: 0
+  Subsystem:       IMAGE_SUBSYSTEM_WINDOWS_CUI
+  DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
+  SizeOfStackReserve: 1048576
+  SizeOfStackCommit: 4096
+  SizeOfHeapReserve: 1048576
+  SizeOfHeapCommit: 4096
+  ExportTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ImportTable:
+    RelativeVirtualAddress: 8304
+    Size:            60
+  ResourceTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ExceptionTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  CertificateTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  BaseRelocationTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  Debug:
+    RelativeVirtualAddress: 0
+    Size:            0
+  Architecture:
+    RelativeVirtualAddress: 0
+    Size:            0
+  GlobalPtr:
+    RelativeVirtualAddress: 0
+    Size:            0
+  TlsTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  LoadConfigTable:
+    RelativeVirtualAddress: 0
+    Size:            0
+  BoundImport:
+    RelativeVirtualAddress: 0
+    Size:            0
+  IAT:
+    RelativeVirtualAddress: 8408
+    Size:            40
+  DelayImportDescriptor:
+    RelativeVirtualAddress: 0
+    Size:            0
+  ClrRuntimeHeader:
+    RelativeVirtualAddress: 0
+    Size:            0
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [ IMAGE_FILE_RELOCS_STRIPPED, IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  4096
+    VirtualSize:     61
+    SectionData:     488B05F91F00000FBE00488B0DF71F00000FBE0901C1488B05F31F00000FBE10488B05F91F00000FBE0001D001C8C3908B051A1000002B05CC0F0000C3
+    SizeOfRawData:   512
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    VirtualAddress:  8192
+    VirtualSize:     318
+    SectionData:     3377115566228844000000000000000001000000[[SYMBOL0=E8200000]]0030000040000000[[SYMBOL1=F0200000]]0830000040000000[[SYMBOL2=D8200000]]1030000040000000D82000001830000040000000E82000002030000040000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000B0200000000000000000000018210000D8200000C020000000000000000000002B210000E82000000000000000000000000000000000000000000000000000000021000000000000000000000000000008210000000000001021000000000000000000000000000000210000000000000000000000000000082100000000000010210000000000000000000000000000000073796D330000000073796D310000000073796D3200006578706F7274322E7838365F36342E646C6C006578706F7274312E7838365F36342E646C6C00
+    SizeOfRawData:   512
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    VirtualAddress:  12288
+    VirtualSize:     40
+    SectionData:     E920004001000000F220004001000000D920004001000000D920004001000000EA20004001000000
+    SizeOfRawData:   512
+symbols:
+  - Name:            start
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            local2a
+    Value:           8
+    SectionNumber:   [[SECTION_OF_LOCAL2A=3]]
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            local3a
+    Value:           16
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _pei386_runtime_relocator
+    Value:           48
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            __RUNTIME_PSEUDO_RELOC_LIST_END__
+    Value:           [[END=80]]
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            __RUNTIME_PSEUDO_RELOC_LIST__
+    Value:           [[BEGIN=8]]
+    SectionNumber:   [[SECTION_OF_BEGIN=2]]
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

diff  --git a/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
new file mode 100644
index 0000000000000..1c5c3cce21cdc
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/pseudoreloc.test
@@ -0,0 +1,274 @@
+DEFINE: %{local1a_386} = 0x3000
+DEFINE: %{sym1_386} = 0x20B0
+DEFINE: %{sym3_386} = 0x20BC
+DEFINE: %{local1a_x64} = 0x3000
+DEFINE: %{sym1_x64} = 0x20E8
+DEFINE: %{sym3_x64} = 0x20D8
+DEFINE: %{relocbegin} = 8
+DEFINE: %{relocend} = 80
+DEFINE: %{rdatasize} = 254
+
+RUN: yaml2obj  -o %t.exe-x86_64 %p/Inputs/pseudoreloc.x86_64.yaml
+RUN: llvm-readobj %t.exe-x86_64 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=CHECK,CHECK-X64 --match-full-lines --implicit-check-not=warning \
+RUN:     -D#WORD=8 -D#SYM1=%{sym1_x64} -D#SYM3=%{sym3_x64} -D#LOCAL1A=%{local1a_x64} -DPREFIX=
+
+RUN: yaml2obj   -o %t.exe-i386  %p/Inputs/pseudoreloc.i386.yaml
+RUN: llvm-readobj  %t.exe-i386  --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=CHECK,CHECK-386 --match-full-lines --implicit-check-not=warning \
+RUN:     -D#WORD=4 -D#SYM1=%{sym1_386} -D#SYM3=%{sym3_386} -D#LOCAL1A=%{local1a_386} -DPREFIX=_
+
+CHECK-X64:      Format: COFF-x86-64
+CHECK-X64-NEXT: Arch: x86_64
+CHECK-386:      Format: COFF-i386
+CHECK-386-NEXT: Arch: i386
+CHECK-NEXT: AddressSize: [[#%u,BW:mul(WORD,8)]]bit
+CHECK-NEXT: PseudoReloc [
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x[[#%X,SYM1]]
+CHECK-NEXT:   SymbolName: sym1
+CHECK-NEXT:   Target: 0x[[#%X,LOCAL1A]]
+CHECK-NEXT:   TargetSymbol: .data+0x0
+CHECK-NEXT:   BitWidth: [[#BW]]
+CHECK-NEXT:  }
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x[[#%X,SYM1+mul(1,WORD)]]
+CHECK-NEXT:   SymbolName: sym2
+CHECK-NEXT:   Target: 0x[[#%X,LOCAL1A+mul(1,WORD)]]
+CHECK-NEXT:   TargetSymbol: [[PREFIX]]local2a
+CHECK-NEXT:   BitWidth: [[#BW]]
+CHECK-NEXT:  }
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x[[#%X,SYM3]]
+CHECK-NEXT:   SymbolName: sym3
+CHECK-NEXT:   Target: 0x[[#%X,LOCAL1A+mul(2,WORD)]]
+CHECK-NEXT:   TargetSymbol: [[PREFIX]]local3a
+CHECK-NEXT:   BitWidth: [[#BW]]
+CHECK-NEXT:  }
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x[[#%X,SYM3]]
+CHECK-NEXT:   SymbolName: sym3
+CHECK-NEXT:   Target: 0x[[#%X,LOCAL1A+mul(3,WORD)]]
+CHECK-NEXT:   TargetSymbol: [[PREFIX]]local3a+0x[[#%X,mul(1,WORD)]]
+CHECK-NEXT:   BitWidth: [[#BW]]
+CHECK-NEXT:  }
+CHECK-NEXT:  Entry {
+CHECK-NEXT:   Symbol: 0x[[#%X,SYM1]]
+CHECK-NEXT:   SymbolName: sym1
+CHECK-NEXT:   Target: 0x[[#%X,LOCAL1A+mul(4,WORD)]]
+CHECK-NEXT:   TargetSymbol: [[PREFIX]]local3a+0x[[#%X,mul(2,WORD)]]
+CHECK-NEXT:   BitWidth: [[#BW]]
+CHECK-NEXT:  }
+CHECK-NEXT: ]
+
+; Test that llvm-readobj warns about missing imported symbol names.
+RUN: yaml2obj  -o %t.corrupted-iat.exe-i386 %p/Inputs/pseudoreloc.i386.yaml \
+RUN:   -DSYMBOL0=30000000 -DSYMBOL1=B2200000 -DSYMBOL2=00FFFF00
+RUN: llvm-readobj %t.corrupted-iat.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefix=INVALIDSYMBOL --match-full-lines -D#LOCAL1A=%{local1a_386} --implicit-check-not=warning
+
+INVALIDSYMBOL:      Symbol: 0x[[#%X,ADDR:0x0030]]
+INVALIDSYMBOL-NEXT: {{.*}}warning: {{.*}}: the address referenced by pseudo-relocation is not a valid import entry: 0x[[#%x,ADDR]]
+INVALIDSYMBOL-NEXT: SymbolName: (missing)
+INVALIDSYMBOL-NEXT: Target: 0x[[#%X,LOCAL1A]]
+INVALIDSYMBOL:      Symbol: 0x[[#%X,ADDR:0x20B2]]
+INVALIDSYMBOL-NEXT: {{.*}}warning: {{.*}}: the address referenced by pseudo-relocation is not a valid import entry: 0x[[#%x,ADDR]]
+INVALIDSYMBOL-NEXT: SymbolName: (missing)
+INVALIDSYMBOL-NEXT: Target: 0x[[#%X,LOCAL1A+4]]
+INVALIDSYMBOL:      Symbol: 0x[[#%X,ADDR:0xFFFF00]]
+INVALIDSYMBOL-NEXT: {{.*}}warning: {{.*}}: the address referenced by pseudo-relocation is not a valid import entry: 0x[[#%x,ADDR]]
+INVALIDSYMBOL-NEXT: SymbolName: (missing)
+INVALIDSYMBOL-NEXT: Target: 0x[[#%X,LOCAL1A+8]]
+
+; Assume the position of the section and the relocation list for further tests.
+RUN: FileCheck --input-file=%p/Inputs/pseudoreloc.i386.yaml %s --check-prefix=RELOCPOS --match-full-lines \
+RUN:   -D#RDATASIZE=%{rdatasize} -DTHEBEGIN=%{relocbegin} -DTHEEND=%{relocend}
+
+RELOCPOS:     sections:
+RELOCPOS-NOT:   - Name:
+RELOCPOS:       - Name:            .text
+RELOCPOS-NOT:   - Name:
+RELOCPOS:       - Name:            .rdata
+RELOCPOS-NEXT:    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+RELOCPOS-NEXT:    VirtualAddress:  8192
+RELOCPOS-NEXT:    VirtualSize:     [[#%d,RDATASIZE]]
+RELOCPOS:       - Name:            .data
+RELOCPOS-NEXT:    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+RELOCPOS-NEXT:    VirtualAddress:  12288
+RELOCPOS:       - Name: ___RUNTIME_PSEUDO_RELOC_LIST_END__
+RELOCPOS-NEXT:    Value: [{{\[}}END=[[THEEND]]{{]}}]
+RELOCPOS:       - Name: ___RUNTIME_PSEUDO_RELOC_LIST__
+RELOCPOS-NEXT:    Value: [{{\[}}BEGIN=[[THEBEGIN]]{{]}}]
+RELOCPOS-NEXT:    SectionNumber: {{\[\[SECTION_OF_BEGIN=2\]\]}}
+
+; Test that llvm-readobj warns if a symbol belongs to a nonexistent section.
+RUN: yaml2obj  -o %t.nosection.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DSECTION_OF_LOCAL2A=999
+RUN: llvm-readobj %t.nosection.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=WARN-NOSECTION --match-full-lines
+
+WARN-NOSECTION: {{.*}} warning:{{.*}}: section index out of bounds
+
+; Test that llvm-readobj shows an empty list if the relocation list has no contents.
+RUN: yaml2obj  -o %t.empty-list.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DEND=20
+RUN: llvm-readobj %t.empty-list.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefix=EMPTY --match-full-lines --implicit-check-not=warning
+
+; Test that llvm-readobj shows an empty list if the relocation list has no header.
+RUN: yaml2obj  -o %t.no-header.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DEND=%{relocbegin}
+RUN: llvm-readobj %t.no-header.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefix=EMPTY --match-full-lines --implicit-check-not=warning
+
+; Test that llvm-readobj shows an empty list if the image is stripped.
+RUN: llvm-readobj --coff-pseudoreloc %p/Inputs/imports.exe.coff-i386 2>&1 | \
+RUN:   FileCheck %s --check-prefix=EMPTY --match-full-lines --implicit-check-not=warning
+
+; Test that llvm-readobj warns if the marker symbol of the relocation list is absent from the symbol table.
+RUN: sed -e 's/__RUNTIME//' %p/Inputs/pseudoreloc.i386.yaml | \
+RUN:   yaml2obj -o %t.nosymbol.exe-i386
+RUN: llvm-readobj  %t.nosymbol.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=EMPTY,WARN-MISSINGMARKER --match-full-lines
+
+; Test that llvm-readobj shows an empty list if a .obj is specified.
+RUN: llvm-readobj --coff-pseudoreloc %p/Inputs/trivial.obj.coff-i386 2>&1 | \
+RUN:   FileCheck %s --check-prefix=EMPTY --match-full-lines --implicit-check-not=warning
+
+; Test that llvm-readobj warns if the header of the relocation list is broken.
+RUN: yaml2obj  -o %t.broken-header.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DBEGIN=1%{relocbegin}
+RUN: llvm-readobj %t.broken-header.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=EMPTY,WARN-INVALIDHEADER --match-full-lines
+
+; Test that llvm-readobj warns if end < start.
+RUN: yaml2obj  -o %t.negative-size.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DBEGIN=%{relocend} -DEND=%{relocbegin}
+RUN: llvm-readobj %t.negative-size.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=EMPTY,WARN-LOWEREND -D#BEGIN=%{relocend} -D#END=%{relocbegin} --match-full-lines
+
+; Test that llvm-readobj warns if the marker symbol points out of the section space.
+RUN: yaml2obj  -o %t.outofrange-both.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DBEGIN=8888 -DEND=9999
+RUN: llvm-readobj %t.outofrange-both.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=EMPTY,WARN-OUTOFRANGE --match-full-lines -D#RDATASIZE=%{rdatasize}
+
+RUN: yaml2obj  -o %t.outofrange-end.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DEND=8888
+RUN: llvm-readobj %t.outofrange-end.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=EMPTY,WARN-OUTOFRANGE --match-full-lines -D#RDATASIZE=%{rdatasize}
+
+; Test that llvm-readobj warns if the marker symbols point 
diff erent sections.
+RUN: yaml2obj  -o %t.section-
diff ers.exe-i386 %p/Inputs/pseudoreloc.i386.yaml -DSECTION_OF_BEGIN=1
+RUN: llvm-readobj %t.section-
diff ers.exe-i386 --coff-pseudoreloc 2>&1 | \
+RUN:   FileCheck %s --check-prefixes=EMPTY,WARN-SECTIONDIFFERS --match-full-lines
+
+EMPTY:      Format: COFF-i386
+EMPTY-NEXT: Arch: i386
+EMPTY-NEXT: AddressSize: 32bit
+EMPTY-NEXT: PseudoReloc [
+WARN-MISSINGMARKER-NEXT:  {{.*}}warning: {{.*}}: the marker symbols for runtime pseudo-relocation were not found
+WARN-INVALIDHEADER-NEXT:  {{.*}}warning: {{.*}}: invalid runtime pseudo-relocation records
+WARN-LOWEREND-NEXT:       {{.*}}warning: {{.*}}: the end marker symbol for runtime pseudo-relocation must point to a higher address than where the begin marker points to: expected >=0x[[#%x,BEGIN]], but got 0x[[#%x,END]]
+WARN-OUTOFRANGE-NEXT:     {{.*}}warning: {{.*}}: the marker symbol of runtime pseudo-relocation points past the end of the section 0x[[#%x,RDATASIZE]]: got 0x[[#%x,8888]]
+WARN-SECTIONDIFFERS-NEXT: {{.*}}warning: {{.*}}: the end marker symbol for runtime pseudo-relocation must point to the same section where the begin marker points to: expected 1, but got {{[2-9]}}
+EMPTY-NEXT: ]
+
+;;
+;; To regenerate Inputs/pseudoreloc.*.yaml, run following one-liner and review actual address map:
+;;
+;; $ split-file pseudoreloc.test /tmp/pseudoreloc && bash /tmp/pseudoreloc/generate.sh && cp /tmp/pseudoreloc/*.yaml Inputs/
+;;
+
+#--- generate.sh
+cd "$(dirname $0)"
+set -e
+
+generate() {
+  LANG=C
+  local arch=$1
+  local emul=$2
+
+  llc -mtriple $arch-mingw32 -filetype obj export1.ll -o export1.$arch.o
+  ld.lld -m $emul --dll export1.$arch.o -o export1.$arch.dll -entry=
+  llc -mtriple $arch-mingw32 -filetype obj export2.ll -o export2.$arch.o
+  ld.lld -m $emul --dll export2.$arch.o -o export2.$arch.dll -entry=
+  llc -mtriple $arch-mingw32 -filetype obj import.ll -o import.$arch.o
+  ld.lld -m $emul -S import.$arch.o export1.$arch.dll export2.$arch.dll -o pseudoreloc.$arch.exe -entry=start \
+    --disable-dynamicbase --disable-reloc-section
+
+  obj2yaml pseudoreloc.$arch.exe -o pseudoreloc.$arch.yaml.orig
+
+  llvm-readobj --coff-imports --syms --section-headers pseudoreloc.$arch.exe > dump.$arch.txt
+  local begin=$(sed -n -e '/__RUNTIME_PSEUDO_RELOC_LIST__/,/Value:/{/Value:/{s/ *Value: *//p;q}}' dump.$arch.txt)
+
+  # Make these parameterizable:
+  #  - the referenced symbol in 1st, 2nd, and 3rd relocation entry
+  #  - the marker symbols' value
+  #  - a section which the marker symbol belongs to
+  #  - a section which the symbol of the relocation target belongs to
+  sed -E -f - pseudoreloc.$arch.yaml.orig <<EOT > pseudoreloc.$arch.yaml
+/- Name: *\\.rdata/,/SectionData:/{
+  s/( *SectionData: *[0-9A-F]{$(($begin * 2 + 24))})(.{8})(.{16})(.{8})(.{16})(.{8})/\\1[[SYMBOL0=\\2]]\\3[[SYMBOL1=\\4]]\\5[[SYMBOL2=\\6]]/
+}
+/__RUNTIME_PSEUDO_RELOC_LIST_END__/,/Value:/{
+  /Value:/s/([0-9]+)/[[END=\1]]/
+}
+/__RUNTIME_PSEUDO_RELOC_LIST__/,/Value:/{
+  /Value:/s/([0-9]+)/[[BEGIN=\1]]/
+}
+/__RUNTIME_PSEUDO_RELOC_LIST__/,/SectionNumber:/{
+  /SectionNumber:/s/([0-9]+)/[[SECTION_OF_BEGIN=\1]]/
+}
+/local2a/,/SectionNumber:/{
+  /SectionNumber:/s/([0-9]+)/[[SECTION_OF_LOCAL2A=\1]]/
+}
+EOT
+
+  # Ensure the binaries generated from the parameterized yaml and original one are exactly the same.
+  
diff  <(yaml2obj pseudoreloc.$arch.yaml.orig -o -) <(yaml2obj pseudoreloc.$arch.yaml -o -)
+}
+
+generate i386 i386pe
+generate x86_64 i386pep
+
+#--- export1.ll
+ at sym1 = dso_local dllexport global [4 x i8] c"\11\22\33\44"
+ at sym2 = dso_local dllexport global [4 x i8] c"\55\66\77\88"
+
+#--- export2.ll
+ at sym3 = dso_local dllexport global [4 x i8] c"\AA\BB\CC\DD"
+
+#--- import.ll
+ at __RUNTIME_PSEUDO_RELOC_LIST__ = external dso_local constant ptr
+ at __RUNTIME_PSEUDO_RELOC_LIST_END__ = external dso_local constant ptr
+ at sym1 = external dso_local global [4 x i8]
+ at sym2 = external dso_local global [4 x i8]
+ at sym3 = external dso_local global [4 x i8]
+ at dummy_to_bump_address = private constant i64 u0x4488226655117733
+ at local1a = private global ptr getelementptr (i8, ptr @sym1, i32 1)
+ at local2a = dso_local global ptr getelementptr (i8, ptr @sym2, i32 2)
+ at local3a = dso_local global [2 x ptr] [ptr getelementptr (i8, ptr @sym3, i32 1), ptr getelementptr (i8, ptr @sym3, i32 1)]
+ at local1b = private global ptr getelementptr (i8, ptr @sym1, i32 2)
+
+define dso_local i32 @start() noinline nounwind {
+  %p1a = load ptr, ptr @local1a
+  %v1a = load i8, ptr %p1a
+  %x1a = sext i8 %v1a to i32
+  %p2a = load ptr, ptr @local2a
+  %v2a = load i8, ptr %p2a
+  %x2a = sext i8 %v2a to i32
+  %p3a = load ptr, ptr @local3a
+  %v3a = load i8, ptr %p3a
+  %x3a = sext i8 %v3a to i32
+  %p1b = load ptr, ptr @local1b
+  %v1b = load i8, ptr %p1b
+  %x1b = sext i8 %v1b to i32
+  %1 = add nsw i32 %x1a, %x2a
+  %2 = add nsw i32 %x3a, %x1b
+  %3 = add nsw i32 %1, %2
+  ret i32 %3
+}
+
+define dso_local i32 @_pei386_runtime_relocator() noinline nounwind {
+  %1 = load ptr, ptr @__RUNTIME_PSEUDO_RELOC_LIST_END__
+  %2 = load ptr, ptr @__RUNTIME_PSEUDO_RELOC_LIST__
+  %3 = ptrtoint ptr %1 to i64
+  %4 = ptrtoint ptr %2 to i64
+  %5 = sub i64 %3, %4
+  %6 = trunc i64 %5 to i32
+  ret i32 %6
+}

diff  --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index 96e0a634648e4..73115fbb7e55e 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -95,6 +95,7 @@ class COFFDumper : public ObjDumper {
   void printCOFFExports() override;
   void printCOFFDirectives() override;
   void printCOFFBaseReloc() override;
+  void printCOFFPseudoReloc() override;
   void printCOFFDebugDirectory() override;
   void printCOFFTLSDirectory() override;
   void printCOFFResources() override;
@@ -2000,6 +2001,264 @@ void COFFDumper::printCOFFBaseReloc() {
   }
 }
 
+void COFFDumper::printCOFFPseudoReloc() {
+  ListScope D(W, "PseudoReloc");
+
+  // Pseudo-relocations are only meaningful with PE image files.
+  if (!Obj->getDOSHeader())
+    return;
+
+  const StringRef RelocBeginName = Obj->getArch() == Triple::x86
+                                       ? "___RUNTIME_PSEUDO_RELOC_LIST__"
+                                       : "__RUNTIME_PSEUDO_RELOC_LIST__";
+  const StringRef RelocEndName = Obj->getArch() == Triple::x86
+                                     ? "___RUNTIME_PSEUDO_RELOC_LIST_END__"
+                                     : "__RUNTIME_PSEUDO_RELOC_LIST_END__";
+
+  const uint32_t Count = Obj->getNumberOfSymbols();
+  // Skip if no symbol was found (maybe stripped).
+  if (Count == 0)
+    return;
+
+  struct SymbolEntry {
+    uint32_t RVA;
+    COFFSymbolRef Symbol;
+    const coff_section *Section;
+    StringRef SymbolName;
+  };
+  SmallVector<SymbolEntry> RVASymbolMap;
+  COFFSymbolRef RelocBegin, RelocEnd;
+  for (uint32_t i = 0; i < Count; ++i) {
+    COFFSymbolRef Sym;
+    if (Expected<COFFSymbolRef> SymOrErr = Obj->getSymbol(i)) {
+      Sym = *SymOrErr;
+    } else {
+      reportUniqueWarning(SymOrErr.takeError());
+      continue;
+    }
+
+    i += Sym.getNumberOfAuxSymbols();
+
+    if (Sym.getSectionNumber() <= 0)
+      continue;
+
+    StringRef Name;
+    if (Expected<StringRef> NameOrErr = Obj->getSymbolName(Sym)) {
+      Name = *NameOrErr;
+    } else {
+      reportUniqueWarning(NameOrErr.takeError());
+      continue;
+    }
+
+    if (Name == RelocBeginName)
+      RelocBegin = Sym;
+    else if (Name == RelocEndName)
+      RelocEnd = Sym;
+
+    const coff_section *Sec = nullptr;
+    if (Expected<const coff_section *> SecOrErr =
+            Obj->getSection(Sym.getSectionNumber())) {
+      Sec = *SecOrErr;
+    } else {
+      reportUniqueWarning(SecOrErr.takeError());
+      continue;
+    }
+
+    RVASymbolMap.push_back(
+        {Sec->VirtualAddress + Sym.getValue(), Sym, Sec, Name});
+  }
+
+  if (!RelocBegin.getRawPtr() || !RelocEnd.getRawPtr()) {
+    reportUniqueWarning(createStringError(
+        "the marker symbols for runtime pseudo-relocation were not found"));
+    return;
+  }
+
+  const coff_section *Section = nullptr;
+  if (Expected<const coff_section *> SecOrErr =
+          Obj->getSection(RelocBegin.getSectionNumber())) {
+    Section = *SecOrErr;
+  } else {
+    reportUniqueWarning(SecOrErr.takeError());
+    return;
+  }
+
+  if (RelocBegin.getSectionNumber() != RelocEnd.getSectionNumber()) {
+    reportUniqueWarning(createStringError(
+        "the end marker symbol for runtime pseudo-relocation must "
+        "point to the same section where the begin marker points to: "
+        "expected %d, but got %d",
+        RelocBegin.getSectionNumber(), RelocEnd.getSectionNumber()));
+    return;
+  }
+
+  // Skip if the relocation list is empty.
+  if (RelocBegin.getValue() == RelocEnd.getValue())
+    return;
+
+  if (RelocEnd.getValue() < RelocBegin.getValue()) {
+    reportUniqueWarning(createStringError(
+        "the end marker symbol for runtime pseudo-relocation must point "
+        "to a higher address than where the begin marker points to: "
+        "expected >=0x%x, but got 0x%x",
+        RelocBegin.getValue(), RelocEnd.getValue()));
+    return;
+  }
+
+  ArrayRef<uint8_t> Data;
+  if (auto E = Obj->getSectionContents(Section, Data)) {
+    reportUniqueWarning(std::move(E));
+    return;
+  }
+
+  if (const uint32_t Begin = RelocBegin.getValue(), End = RelocEnd.getValue();
+      Begin >= Data.size() || End > Data.size()) {
+    reportUniqueWarning(
+        createStringError("the marker symbol of runtime pseudo-relocation "
+                          "points past the end of the section 0x%x: got 0x%x",
+                          Data.size(), Begin >= Data.size() ? Begin : End));
+    return;
+  }
+
+  const ArrayRef<uint8_t> RawRelocs =
+      Data.take_front(RelocEnd.getValue()).drop_front(RelocBegin.getValue());
+  struct alignas(4) PseudoRelocationHeader {
+    PseudoRelocationHeader(uint32_t Signature)
+        : Zero1(0), Zero2(0), Signature(Signature) {}
+    support::ulittle32_t Zero1;
+    support::ulittle32_t Zero2;
+    support::ulittle32_t Signature;
+  };
+  const PseudoRelocationHeader HeaderV2(1);
+  if (RawRelocs.size() < sizeof(HeaderV2) ||
+      (memcmp(RawRelocs.data(), &HeaderV2, sizeof(HeaderV2)) != 0)) {
+    reportUniqueWarning(
+        createStringError("invalid runtime pseudo-relocation records"));
+    return;
+  }
+
+  struct alignas(4) PseudoRelocationRecord {
+    support::ulittle32_t Symbol;
+    support::ulittle32_t Target;
+    support::ulittle32_t BitSize;
+  };
+  ArrayRef<PseudoRelocationRecord> RelocRecords(
+      reinterpret_cast<const PseudoRelocationRecord *>(
+          RawRelocs.data() + sizeof(PseudoRelocationHeader)),
+      (RawRelocs.size() - sizeof(PseudoRelocationHeader)) /
+          sizeof(PseudoRelocationRecord));
+
+  struct CachingImportedSymbolLookup {
+    struct SizedImportDirectoryEntry {
+      uint32_t StartRVA;
+      uint32_t EndRVA;
+      ImportDirectoryEntryRef EntryRef;
+    };
+
+    CachingImportedSymbolLookup(const COFFObjectFile *Obj) : Obj(Obj) {
+      for (auto D : Obj->import_directories()) {
+        auto &Entry = ImportDirectories.emplace_back();
+        Entry.EntryRef = D;
+        Entry.EndRVA = 0;
+        if (auto E = D.getImportAddressTableRVA(Entry.StartRVA))
+          reportError(std::move(E), Obj->getFileName());
+      }
+      if (ImportDirectories.empty())
+        return;
+      llvm::sort(ImportDirectories, [](const auto &x, const auto &y) {
+        return x.StartRVA < y.StartRVA;
+      });
+    }
+
+    Expected<StringRef> find(COFFDumper *Self, uint32_t EntryRVA) {
+      static constexpr char Msg[] =
+          "the address referenced by pseudo-relocation is not a valid import "
+          "entry: 0x%x";
+      if (auto Ite = ImportedSymbols.find(EntryRVA);
+          Ite != ImportedSymbols.end())
+        return Ite->second;
+
+      auto Ite = llvm::upper_bound(
+          ImportDirectories, EntryRVA,
+          [](uint32_t RVA, const auto &D) { return RVA < D.StartRVA; });
+      if (Ite == ImportDirectories.begin())
+        return createStringError(Msg, EntryRVA);
+
+      --Ite;
+      uint32_t RVA = Ite->StartRVA;
+      if (Ite->EndRVA != 0 && Ite->EndRVA <= RVA)
+        return createStringError(Msg, EntryRVA);
+      // Search with linear iteration to care if padding or garbage exist
+      // between ImportDirectoryEntry.
+      for (auto S : Ite->EntryRef.imported_symbols()) {
+        if (RVA == EntryRVA) {
+          StringRef &NameDst = ImportedSymbols[RVA];
+          if (auto E = S.getSymbolName(NameDst)) {
+            Self->reportUniqueWarning(std::move(E));
+            NameDst = "(no symbol)";
+          }
+          return NameDst;
+        }
+        RVA += Obj->is64() ? 8 : 4;
+        if (EntryRVA < RVA)
+          return createStringError(Msg, EntryRVA);
+      }
+      Ite->EndRVA = RVA;
+
+      return createStringError(Msg, EntryRVA);
+    }
+
+  private:
+    const COFFObjectFile *Obj;
+    SmallVector<SizedImportDirectoryEntry> ImportDirectories;
+    DenseMap<uint32_t, StringRef> ImportedSymbols;
+  };
+  CachingImportedSymbolLookup ImportedSymbols(Obj);
+  llvm::stable_sort(RVASymbolMap,
+                    [](const auto &x, const auto &y) { return x.RVA < y.RVA; });
+  RVASymbolMap.erase(
+      llvm::unique(RVASymbolMap,
+                   [](const auto &x, const auto &y) { return x.RVA == y.RVA; }),
+      RVASymbolMap.end());
+
+  for (const auto &Reloc : RelocRecords) {
+    DictScope Entry(W, "Entry");
+
+    W.printHex("Symbol", Reloc.Symbol);
+    if (Expected<StringRef> SymOrErr =
+            ImportedSymbols.find(this, Reloc.Symbol)) {
+      W.printString("SymbolName", *SymOrErr);
+    } else {
+      reportUniqueWarning(SymOrErr.takeError());
+      W.printString("SymbolName", "(missing)");
+    }
+
+    W.printHex("Target", Reloc.Target);
+    if (auto Ite = llvm::upper_bound(
+            RVASymbolMap, Reloc.Target.value(),
+            [](uint32_t RVA, const auto &Sym) { return RVA < Sym.RVA; });
+        Ite == RVASymbolMap.begin()) {
+      W.printSymbolOffset("TargetSymbol", "(base)", Reloc.Target);
+    } else if (const uint32_t Offset = Reloc.Target.value() - (--Ite)->RVA;
+               Offset == 0) {
+      W.printString("TargetSymbol", Ite->SymbolName);
+    } else if (Offset < Ite->Section->VirtualSize) {
+      W.printSymbolOffset("TargetSymbol", Ite->SymbolName, Offset);
+    } else if (++Ite == RVASymbolMap.end()) {
+      W.printSymbolOffset("TargetSymbol", "(base)", Reloc.Target);
+    } else if (Expected<StringRef> NameOrErr =
+                   Obj->getSectionName(Ite->Section)) {
+      W.printSymbolOffset("TargetSymbol", *NameOrErr,
+                          Reloc.Target - Ite->Section->VirtualAddress);
+    } else {
+      reportUniqueWarning(NameOrErr.takeError());
+      W.printSymbolOffset("TargetSymbol", "(base)", Reloc.Target);
+    }
+
+    W.printNumber("BitWidth", Reloc.BitSize);
+  }
+}
+
 void COFFDumper::printCOFFResources() {
   ListScope ResourcesD(W, "Resources");
   for (const SectionRef &S : Obj->sections()) {

diff  --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 1dc29661f7178..a654078a770ff 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -146,6 +146,7 @@ class ObjDumper {
   virtual void printCOFFExports() { }
   virtual void printCOFFDirectives() { }
   virtual void printCOFFBaseReloc() { }
+  virtual void printCOFFPseudoReloc() {}
   virtual void printCOFFDebugDirectory() { }
   virtual void printCOFFTLSDirectory() {}
   virtual void printCOFFResources() {}

diff  --git a/llvm/tools/llvm-readobj/Opts.td b/llvm/tools/llvm-readobj/Opts.td
index 48d43cc635a4f..711522c4acb14 100644
--- a/llvm/tools/llvm-readobj/Opts.td
+++ b/llvm/tools/llvm-readobj/Opts.td
@@ -87,6 +87,10 @@ def coff_directives : FF<"coff-directives", "Display .drectve section">, Group<g
 def coff_exports : FF<"coff-exports", "Display export table">, Group<grp_coff>;
 def coff_imports : FF<"coff-imports", "Display import table">, Group<grp_coff>;
 def coff_load_config : FF<"coff-load-config", "Display load config">, Group<grp_coff>;
+def coff_pseudoreloc
+    : FF<"coff-pseudoreloc",
+         "Display runtime pseudo-relocations (Cygwin/MinGW specific)">,
+      Group<grp_coff>;
 def coff_resources : FF<"coff-resources", "Display .rsrc section">, Group<grp_coff>;
 def coff_tls_directory : FF<"coff-tls-directory", "Display TLS directory">, Group<grp_coff>;
 

diff  --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 4c84ed701bb9a..2b34761b2cc6c 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -154,6 +154,7 @@ static bool CodeViewEnableGHash;
 static bool CodeViewMergedTypes;
 bool CodeViewSubsectionBytes;
 static bool COFFBaseRelocs;
+static bool COFFPseudoRelocs;
 static bool COFFDebugDirectory;
 static bool COFFDirectives;
 static bool COFFExports;
@@ -305,6 +306,7 @@ static void parseOptions(const opt::InputArgList &Args) {
   opts::CodeViewMergedTypes = Args.hasArg(OPT_codeview_merged_types);
   opts::CodeViewSubsectionBytes = Args.hasArg(OPT_codeview_subsection_bytes);
   opts::COFFBaseRelocs = Args.hasArg(OPT_coff_basereloc);
+  opts::COFFPseudoRelocs = Args.hasArg(OPT_coff_pseudoreloc);
   opts::COFFDebugDirectory = Args.hasArg(OPT_coff_debug_directory);
   opts::COFFDirectives = Args.hasArg(OPT_coff_directives);
   opts::COFFExports = Args.hasArg(OPT_coff_exports);
@@ -492,6 +494,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer,
       Dumper->printCOFFDirectives();
     if (opts::COFFBaseRelocs)
       Dumper->printCOFFBaseReloc();
+    if (opts::COFFPseudoRelocs)
+      Dumper->printCOFFPseudoReloc();
     if (opts::COFFDebugDirectory)
       Dumper->printCOFFDebugDirectory();
     if (opts::COFFTLSDirectory)


        


More information about the llvm-commits mailing list