[lld] r243535 - COFF: Fix SECREL and SECTION relocations.

Rui Ueyama ruiu at google.com
Wed Jul 29 09:30:46 PDT 2015


Author: ruiu
Date: Wed Jul 29 11:30:45 2015
New Revision: 243535

URL: http://llvm.org/viewvc/llvm-project?rev=243535&view=rev
Log:
COFF: Fix SECREL and SECTION relocations.

SECREL should sets the 32-bit offset of the target from the beginning
of *target's* output section. Previously, the offset from the beginning
of source's output section was used instead.

SECTION means the target section's index, and not the source section's
index. This patch fixes that issue too.

Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/Symbols.h
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/reloc-x64.test
    lld/trunk/test/COFF/reloc-x86.test

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=243535&r1=243534&r2=243535&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Wed Jul 29 11:30:45 2015
@@ -50,8 +50,9 @@ static void add32(uint8_t *P, int32_t V)
 static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
 static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
 
-void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S,
+void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym,
                                uint64_t P) {
+  uint64_t S = Sym->getRVA();
   switch (Type) {
   case IMAGE_REL_AMD64_ADDR32:   add32(Off, S + Config->ImageBase); break;
   case IMAGE_REL_AMD64_ADDR64:   add64(Off, S + Config->ImageBase); break;
@@ -62,22 +63,23 @@ void SectionChunk::applyRelX64(uint8_t *
   case IMAGE_REL_AMD64_REL32_3:  add32(Off, S - P - 7); break;
   case IMAGE_REL_AMD64_REL32_4:  add32(Off, S - P - 8); break;
   case IMAGE_REL_AMD64_REL32_5:  add32(Off, S - P - 9); break;
-  case IMAGE_REL_AMD64_SECTION:  add16(Off, Out->SectionIndex); break;
-  case IMAGE_REL_AMD64_SECREL:   add32(Off, S - Out->getRVA()); break;
+  case IMAGE_REL_AMD64_SECTION:  add16(Off, Sym->getSectionIndex()); break;
+  case IMAGE_REL_AMD64_SECREL:   add32(Off, Sym->getSecrel()); break;
   default:
     llvm::report_fatal_error("Unsupported relocation type");
   }
 }
 
-void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, uint64_t S,
+void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym,
                                uint64_t P) {
+  uint64_t S = Sym->getRVA();
   switch (Type) {
   case IMAGE_REL_I386_ABSOLUTE: break;
   case IMAGE_REL_I386_DIR32:    add32(Off, S + Config->ImageBase); break;
   case IMAGE_REL_I386_DIR32NB:  add32(Off, S); break;
   case IMAGE_REL_I386_REL32:    add32(Off, S - P - 4); break;
-  case IMAGE_REL_I386_SECTION:  add16(Off, Out->SectionIndex); break;
-  case IMAGE_REL_I386_SECREL:   add32(Off, S - Out->getRVA()); break;
+  case IMAGE_REL_I386_SECTION:  add16(Off, Sym->getSectionIndex()); break;
+  case IMAGE_REL_I386_SECREL:   add32(Off, Sym->getSecrel()); break;
   default:
     llvm::report_fatal_error("Unsupported relocation type");
   }
@@ -100,8 +102,9 @@ static void applyBranchImm(uint8_t *Off,
   or16(Off + 2, ((V >> 1) & 0x7ff) | (J2 << 11) | (J1 << 13));
 }
 
-void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, uint64_t S,
+void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym,
                                uint64_t P) {
+  uint64_t S = Sym->getRVA();
   switch (Type) {
   case IMAGE_REL_ARM_ADDR32:    add32(Off, S + Config->ImageBase); break;
   case IMAGE_REL_ARM_ADDR32NB:  add32(Off, S); break;
@@ -124,17 +127,17 @@ void SectionChunk::writeTo(uint8_t *Buf)
   for (const coff_relocation &Rel : Relocs) {
     uint8_t *Off = Buf + FileOff + Rel.VirtualAddress;
     SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex)->repl();
-    uint64_t S = cast<Defined>(Body)->getRVA();
+    Defined *Sym = cast<Defined>(Body);
     uint64_t P = RVA + Rel.VirtualAddress;
     switch (Config->Machine) {
     case AMD64:
-      applyRelX64(Off, Rel.Type, S, P);
+      applyRelX64(Off, Rel.Type, Sym, P);
       break;
     case I386:
-      applyRelX86(Off, Rel.Type, S, P);
+      applyRelX86(Off, Rel.Type, Sym, P);
       break;
     case ARMNT:
-      applyRelARM(Off, Rel.Type, S, P);
+      applyRelARM(Off, Rel.Type, Sym, P);
       break;
     default:
       llvm_unreachable("unknown machine type");

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=243535&r1=243534&r2=243535&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Wed Jul 29 11:30:45 2015
@@ -137,9 +137,9 @@ public:
   StringRef getSectionName() const override { return SectionName; }
   void getBaserels(std::vector<Baserel> *Res) override;
   bool isCOMDAT() const;
-  void applyRelX64(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P);
-  void applyRelX86(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P);
-  void applyRelARM(uint8_t *Off, uint16_t Type, uint64_t S, uint64_t P);
+  void applyRelX64(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P);
+  void applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P);
+  void applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, uint64_t P);
 
   // Called if the garbage collector decides to not include this chunk
   // in a final output. It's supposed to print out a log message to stdout.

Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=243535&r1=243534&r2=243535&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Wed Jul 29 11:30:45 2015
@@ -130,6 +130,14 @@ public:
   // Returns the file offset of this symbol in the final executable.
   // The writer uses this information to apply relocations.
   uint64_t getFileOff();
+
+  // Returns the RVA relative to the beginning of the output section.
+  // Used to implement SECREL relocation type.
+  uint64_t getSecrel();
+
+  // Returns the output section index.
+  // Used to implement SECTION relocation type.
+  uint64_t getSectionIndex();
 };
 
 // Symbols defined via a COFF object file.

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=243535&r1=243534&r2=243535&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Jul 29 11:30:45 2015
@@ -678,5 +678,17 @@ void Writer::addBaserelBlocks(OutputSect
   Dest->addChunk(new (Buf) BaserelChunk(Page, &V[I], &V[0] + J));
 }
 
+uint64_t Defined::getSecrel() {
+  if (auto *D = dyn_cast<DefinedRegular>(this))
+    return getRVA() - D->getChunk()->getOutputSection()->getRVA();
+  llvm::report_fatal_error("SECREL relocation points to a non-regular symbol");
+}
+
+uint64_t Defined::getSectionIndex() {
+  if (auto *D = dyn_cast<DefinedRegular>(this))
+    return D->getChunk()->getOutputSection()->SectionIndex;
+  llvm::report_fatal_error("SECTION relocation points to a non-regular symbol");
+}
+
 } // namespace coff
 } // namespace lld

Modified: lld/trunk/test/COFF/reloc-x64.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/reloc-x64.test?rev=243535&r1=243534&r2=243535&view=diff
==============================================================================
--- lld/trunk/test/COFF/reloc-x64.test (original)
+++ lld/trunk/test/COFF/reloc-x64.test Wed Jul 29 11:30:45 2015
@@ -3,16 +3,17 @@
 # RUN: llvm-objdump -d %t.exe | FileCheck %s
 
 # CHECK: .text:
-# CHECK: 1000: a1 00 10 00 40 00 00 00 00
-# CHECK: 1009: a1 00 10 00 40 01 00 00 00
-# CHECK: 1012: a1 00 10 00 00 00 00 00 00
-# CHECK: 101b: a1 e0 ff ff ff 00 00 00 00
-# CHECK: 1024: a1 d6 ff ff ff 00 00 00 00
-# CHECK: 102d: a1 cc ff ff ff 00 00 00 00
-# CHECK: 1036: a1 c2 ff ff ff 00 00 00 00
-# CHECK: 103f: a1 b8 ff ff ff 00 00 00 00
-# CHECK: 1048: a1 ae ff ff ff 00 00 00 00
-# CHECK: 1051: a1 01 00 00 00 00 00 00 00
+# CHECK: 1000: a1 03 20 00 40 00 00 00 00
+# CHECK: 1009: a1 03 20 00 40 01 00 00 00
+# CHECK: 1012: a1 03 20 00 00 00 00 00 00
+# CHECK: 101b: a1 e3 0f 00 00 00 00 00 00
+# CHECK: 1024: a1 d9 0f 00 00 00 00 00 00
+# CHECK: 102d: a1 cf 0f 00 00 00 00 00 00
+# CHECK: 1036: a1 c5 0f 00 00 00 00 00 00
+# CHECK: 103f: a1 bb 0f 00 00 00 00 00 00
+# CHECK: 1048: a1 b1 0f 00 00 00 00 00 00
+# CHECK: 1051: a1 02 00 00 00 00 00 00 00
+# CHECK: 105a: a1 03 00 00 00 00 00 00 00
 
 ---
 header:
@@ -22,41 +23,45 @@ sections:
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       4096
-    SectionData:     A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000
+    SectionData:     A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000
     Relocations:
       - VirtualAddress:  1
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_ADDR32
       - VirtualAddress:  10
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_ADDR64
       - VirtualAddress:  19
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_ADDR32NB
       - VirtualAddress:  28
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_REL32
       - VirtualAddress:  37
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_REL32_1
       - VirtualAddress:  46
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_REL32_2
       - VirtualAddress:  55
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_REL32_3
       - VirtualAddress:  64
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_REL32_4
       - VirtualAddress:  73
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_REL32_5
       - VirtualAddress:  82
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_SECTION
       - VirtualAddress:  91
-        SymbolName:      main
+        SymbolName:      foo
         Type:            IMAGE_REL_AMD64_SECREL
+  - Name:            .zzz
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4096
+    SectionData:     0000000000000000
 symbols:
   - Name:            .text
     Value:           0
@@ -70,10 +75,28 @@ symbols:
       NumberOfLinenumbers: 0
       CheckSum:        0
       Number:          0
+  - Name:            .zzz
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
   - Name:            main
     Value:           0
     SectionNumber:   1
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            foo
+    Value:           3
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
 ...

Modified: lld/trunk/test/COFF/reloc-x86.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/reloc-x86.test?rev=243535&r1=243534&r2=243535&view=diff
==============================================================================
--- lld/trunk/test/COFF/reloc-x86.test (original)
+++ lld/trunk/test/COFF/reloc-x86.test Wed Jul 29 11:30:45 2015
@@ -3,12 +3,12 @@
 # RUN: llvm-objdump -d %t.exe | FileCheck %s
 
 # CHECK: .text:
-# CHECK:     1000:       a1 00 00 00 00
-# CHECK:     1005:       a1 00 10 40 00
-# CHECK:     100a:       a1 00 10 00 00
-# CHECK:     100f:       a1 ec ff ff ff
-# CHECK:     1014:       a1 00 00 01 00
-# CHECK:     1019:       a1 00 00 00 00
+# CHECK: 1000: a1 00 00 00 00
+# CHECK: 1005: a1 03 20 40 00
+# CHECK: 100a: a1 03 20 00 00
+# CHECK: 100f: a1 ef 0f 00 00
+# CHECK: 1014: a1 00 00 02 00
+# CHECK: 1019: a1 03 00 00 00
 
 ---
 header:
@@ -21,23 +21,27 @@ sections:
     SectionData:     A100000000A100000000A100000000A100000000A100000000A100000000
     Relocations:
       - VirtualAddress:  1
-        SymbolName:      _main
+        SymbolName:      _foo
         Type:            IMAGE_REL_I386_ABSOLUTE
       - VirtualAddress:  6
-        SymbolName:      _main
+        SymbolName:      _foo
         Type:            IMAGE_REL_I386_DIR32
       - VirtualAddress:  11
-        SymbolName:      _main
+        SymbolName:      _foo
         Type:            IMAGE_REL_I386_DIR32NB
       - VirtualAddress:  16
-        SymbolName:      _main
+        SymbolName:      _foo
         Type:            IMAGE_REL_I386_REL32
       - VirtualAddress:  23
-        SymbolName:      _main
+        SymbolName:      _foo
         Type:            IMAGE_REL_I386_SECTION
       - VirtualAddress:  26
-        SymbolName:      _main
+        SymbolName:      _foo
         Type:            IMAGE_REL_I386_SECREL
+  - Name:            .zzz
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4096
+    SectionData:     0000000000000000
 symbols:
   - Name:            .text
     Value:           0
@@ -51,10 +55,28 @@ symbols:
       NumberOfLinenumbers: 0
       CheckSum:        0
       Number:          0
+  - Name:            .zzz
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
   - Name:            _main
     Value:           0
     SectionNumber:   1
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _foo
+    Value:           3
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
 ...





More information about the llvm-commits mailing list