[llvm] 4d02263 - [yaml2obj][COFF] Add support for extended relocation tables

Sergey Dmitriev via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 14 12:47:07 PST 2019


Author: Sergey Dmitriev
Date: 2019-11-14T12:39:28-08:00
New Revision: 4d02263af0d504593e6312b44dfa7749181a21e4

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

LOG: [yaml2obj][COFF] Add support for extended relocation tables

Summary:
The tool does not correctly handle COFF sections with extended relocation tables (with IMAGE_SCN_LNK_NRELOC_OVFL bit set), this patch fixes this problem.

But I have cheated a bit in the test (to make it smaller) because extended relocation table is supposed to be used when the number of relocations exceeds 65534. Otherwise the test size would be pretty big.

Reviewers: jhenderson, MaskRay, mstorsjo

Reviewed By: mstorsjo

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D70251

Added: 
    llvm/test/tools/yaml2obj/coff-xrelocs.yaml

Modified: 
    llvm/lib/ObjectYAML/COFFEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/lib/ObjectYAML/COFFEmitter.cpp
index efcdc51e1670..ec3ec55011f9 100644
--- a/llvm/lib/ObjectYAML/COFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/COFFEmitter.cpp
@@ -260,9 +260,12 @@ static bool layoutCOFF(COFFParser &CP) {
       CurrentSectionDataOffset += S.Header.SizeOfRawData;
       if (!S.Relocations.empty()) {
         S.Header.PointerToRelocations = CurrentSectionDataOffset;
-        S.Header.NumberOfRelocations = S.Relocations.size();
-        CurrentSectionDataOffset +=
-            S.Header.NumberOfRelocations * COFF::RelocationSize;
+        if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) {
+          S.Header.NumberOfRelocations = 0xffff;
+          CurrentSectionDataOffset += COFF::RelocationSize;
+        } else
+          S.Header.NumberOfRelocations = S.Relocations.size();
+        CurrentSectionDataOffset += S.Relocations.size() * COFF::RelocationSize;
       }
     } else {
       // Leave SizeOfRawData unaltered. For .bss sections in object files, it
@@ -506,6 +509,10 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
     S.SectionData.writeAsBinary(OS);
     assert(S.Header.SizeOfRawData >= S.SectionData.binary_size());
     OS.write_zeros(S.Header.SizeOfRawData - S.SectionData.binary_size());
+    if (S.Header.Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL)
+      OS << binary_le<uint32_t>(/*VirtualAddress=*/ S.Relocations.size() + 1)
+         << binary_le<uint32_t>(/*SymbolTableIndex=*/ 0)
+         << binary_le<uint16_t>(/*Type=*/ 0);
     for (const COFFYAML::Relocation &R : S.Relocations) {
       uint32_t SymbolTableIndex;
       if (R.SymbolTableIndex) {

diff  --git a/llvm/test/tools/yaml2obj/coff-xrelocs.yaml b/llvm/test/tools/yaml2obj/coff-xrelocs.yaml
new file mode 100644
index 000000000000..fbc22a1e99ca
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/coff-xrelocs.yaml
@@ -0,0 +1,71 @@
+## This test checks that yaml2obj correctly handles COFF sections with
+## extended relocation tables (IMAGE_SCN_LNK_NRELOC_OVFL).
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj --sections --relocations %t | FileCheck %s --check-prefix=CHECK-OBJ
+# RUN: obj2yaml %t | FileCheck %s --check-prefix=CHECK-YAML
+
+# CHECK-OBJ:      Sections [
+# CHECK-OBJ-NEXT:   Section {
+# CHECK-OBJ-NEXT:     Number: 1
+# CHECK-OBJ-NEXT:     Name: .data
+# CHECK-OBJ:          RawDataSize: 16
+# CHECK-OBJ:          RelocationCount: 65535
+# CHECK-OBJ:          Characteristics [
+# CHECK-OBJ-NEXT:       IMAGE_SCN_ALIGN_16BYTES
+# CHECK-OBJ-NEXT:       IMAGE_SCN_CNT_INITIALIZED_DATA
+# CHECK-OBJ-NEXT:       IMAGE_SCN_LNK_NRELOC_OVFL
+# CHECK-OBJ-NEXT:       IMAGE_SCN_MEM_READ
+# CHECK-OBJ-NEXT:     ]
+# CHECK-OBJ-NEXT:   }
+# CHECK-OBJ-NEXT: ]
+# CHECK-OBJ-NEXT: Relocations [
+# CHECK-OBJ-NEXT:   Section (1) .data {
+# CHECK-OBJ-NEXT:     0x0 IMAGE_REL_AMD64_ADDR64 foo (0)
+# CHECK-OBJ-NEXT:     0x8 IMAGE_REL_AMD64_ADDR64 bar (1)
+# CHECK-OBJ-NEXT:   }
+# CHECK-OBJ-NEXT: ]
+
+# CHECK-YAML:      sections:
+# CHECK-YAML-NEXT:   - Name:            .data
+# CHECK-YAML-NEXT:     Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_MEM_READ ]
+# CHECK-YAML-NEXT:     Alignment:       16
+# CHECK-YAML-NEXT:     SectionData:     '00000000000000000000000000000000'
+# CHECK-YAML-NEXT:     Relocations:
+# CHECK-YAML-NEXT:       - VirtualAddress:  0
+# CHECK-YAML-NEXT:         SymbolName:      foo
+# CHECK-YAML-NEXT:         Type:            IMAGE_REL_AMD64_ADDR64
+# CHECK-YAML-NEXT:       - VirtualAddress:  8
+# CHECK-YAML-NEXT:         SymbolName:      bar
+# CHECK-YAML-NEXT:         Type:            IMAGE_REL_AMD64_ADDR64
+# CHECK-YAML-NEXT: symbols:
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_NRELOC_OVFL, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     '00000000000000000000000000000000'
+    Relocations:
+      - VirtualAddress:  0
+        SymbolName:      foo
+        Type:            IMAGE_REL_AMD64_ADDR64
+      - VirtualAddress:  8
+        SymbolName:      bar
+        Type:            IMAGE_REL_AMD64_ADDR64
+symbols:
+  - Name:            foo
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            bar
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...


        


More information about the llvm-commits mailing list