[lld] r196262 - [PECOFF] Implement IMAGE_REL_I386_{SECTION, SECREL} relocations.

Rui Ueyama ruiu at google.com
Tue Dec 3 01:18:31 PST 2013


Author: ruiu
Date: Tue Dec  3 03:18:31 2013
New Revision: 196262

URL: http://llvm.org/viewvc/llvm-project?rev=196262&view=rev
Log:
[PECOFF] Implement IMAGE_REL_I386_{SECTION,SECREL} relocations.

These relocations are used in .debug section.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
    lld/trunk/test/pecoff/Inputs/reloc.obj.yaml
    lld/trunk/test/pecoff/reloc.test

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Dec  3 03:18:31 2013
@@ -180,6 +180,8 @@ PECOFFLinkingContext::relocKindFromStrin
         LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
         LLD_CASE(IMAGE_REL_I386_DIR32)
         LLD_CASE(IMAGE_REL_I386_DIR32NB)
+        LLD_CASE(IMAGE_REL_I386_SECTION)
+        LLD_CASE(IMAGE_REL_I386_SECREL)
         LLD_CASE(IMAGE_REL_I386_REL32)
         .Default(-1);
 #undef LLD_CASE
@@ -198,6 +200,8 @@ PECOFFLinkingContext::stringFromRelocKin
     LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
     LLD_CASE(IMAGE_REL_I386_DIR32)
     LLD_CASE(IMAGE_REL_I386_DIR32NB)
+    LLD_CASE(IMAGE_REL_I386_SECTION)
+    LLD_CASE(IMAGE_REL_I386_SECREL)
     LLD_CASE(IMAGE_REL_I386_REL32)
 #undef LLD_CASE
   }

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Tue Dec  3 03:18:31 2013
@@ -195,6 +195,7 @@ public:
 
   void applyRelocations(uint8_t *fileBuffer,
                         std::map<const Atom *, uint64_t> &atomRva,
+                        std::vector<uint64_t> &sectionRva,
                         uint64_t imageBaseAddress);
   void printAtomAddresses(uint64_t baseAddr);
   void addBaseRelocations(std::vector<uint64_t> &relocSites);
@@ -505,16 +506,18 @@ void AtomChunk::write(uint8_t *fileBuffe
 
 void AtomChunk::applyRelocations(uint8_t *fileBuffer,
                                  std::map<const Atom *, uint64_t> &atomRva,
+                                 std::vector<uint64_t> &sectionRva,
                                  uint64_t imageBaseAddress) {
   for (const auto *layout : _atomLayouts) {
     const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
     for (const Reference *ref : *atom) {
-      auto relocSite = reinterpret_cast<ulittle32_t *>(
+      auto relocSite32 = reinterpret_cast<ulittle32_t *>(
           fileBuffer + layout->_fileOffset + ref->offsetInAtom());
+      auto relocSite16 = reinterpret_cast<ulittle16_t *>(relocSite32);
       uint64_t targetAddr = atomRva[ref->target()];
       // Also account for whatever offset is already stored at the relocation
       // site.
-      targetAddr += *relocSite;
+      targetAddr += *relocSite32;
 
       // Skip if this reference is not for relocation.
       if (ref->kind() < lld::Reference::kindTargetLow)
@@ -526,19 +529,42 @@ void AtomChunk::applyRelocations(uint8_t
         break;
       case llvm::COFF::IMAGE_REL_I386_DIR32:
         // Set target's 32-bit VA.
-        *relocSite = targetAddr + imageBaseAddress;
+        *relocSite32 = targetAddr + imageBaseAddress;
         break;
       case llvm::COFF::IMAGE_REL_I386_DIR32NB:
         // Set target's 32-bit RVA.
-        *relocSite = targetAddr;
+        *relocSite32 = targetAddr;
         break;
       case llvm::COFF::IMAGE_REL_I386_REL32: {
         // Set 32-bit relative address of the target. This relocation is
         // usually used for relative branch or call instruction.
         uint32_t disp = atomRva[atom] + ref->offsetInAtom() + 4;
-        *relocSite = targetAddr - disp;
+        *relocSite32 = targetAddr - disp;
         break;
       }
+      case llvm::COFF::IMAGE_REL_I386_SECTION: {
+        // The 16-bit section index that contains the target symbol.
+        uint16_t i = 1;
+        for (uint64_t rva : sectionRva) {
+          if (targetAddr < rva) {
+            *relocSite16 = i;
+            break;
+          }
+          ++i;
+        }
+        break;
+      }
+      case llvm::COFF::IMAGE_REL_I386_SECREL:
+        // The 32-bit relative address from the beginning of the section that
+        // contains the target symbol.
+        for (int i = 0, e = sectionRva.size(); i < e; ++i) {
+          if (i == e - 1 ||
+              (sectionRva[i] <= targetAddr && targetAddr <= sectionRva[i + 1])) {
+            *relocSite32 = targetAddr - sectionRva[i];
+            break;
+          }
+        }
+        break;
       default:
         llvm_unreachable("Unsupported relocation kind");
       }
@@ -860,6 +886,9 @@ private:
 
   // The map from defined atoms to its RVAs. Will be used for relocation.
   std::map<const Atom *, uint64_t> atomRva;
+
+  // List of section RVAs. Will be used for relocation.
+  std::vector<uint64_t> sectionRva;
 };
 
 StringRef customSectionName(const DefinedAtom *atom) {
@@ -930,11 +959,13 @@ void ExecutableWriter::build(const File
 
   SectionChunk *text = nullptr;
   SectionChunk *data = nullptr;
+  std::vector<SectionChunk *> sectionChunks;
   for (auto i : atoms) {
     StringRef sectionName = i.first;
     std::vector<const DefinedAtom *> &contents = i.second;
     auto *section = new GenericSectionChunk(_PECOFFLinkingContext, sectionName,
                                             contents);
+    sectionChunks.push_back(section);
     addSectionChunk(section, sectionTable);
 
     if (!text && sectionName == ".text")
@@ -961,6 +992,9 @@ void ExecutableWriter::build(const File
 
   setImageSizeOnDisk();
 
+  for (SectionChunk *p : sectionChunks)
+    sectionRva.push_back(p->getVirtualAddress());
+
   // Now that we know the size and file offset of sections. Set the file
   // header accordingly.
   peHeader->setSizeOfCode(calcSizeOfCode());
@@ -1005,7 +1039,7 @@ error_code ExecutableWriter::writeFile(c
 void ExecutableWriter::applyAllRelocations(uint8_t *bufferStart) {
   for (auto &cp : _chunks)
     if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
-      chunk->applyRelocations(bufferStart, atomRva,
+      chunk->applyRelocations(bufferStart, atomRva, sectionRva,
                               _PECOFFLinkingContext.getBaseAddress());
 }
 

Modified: lld/trunk/test/pecoff/Inputs/reloc.obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc.obj.yaml?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/test/pecoff/Inputs/reloc.obj.yaml (original)
+++ lld/trunk/test/pecoff/Inputs/reloc.obj.yaml Tue Dec  3 03:18:31 2013
@@ -6,15 +6,21 @@ sections:
   - Name:            .text
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       16
-    SectionData:     5589E583EC14C745FC00000000C744240C00000000C744240807000000C744240400000000C7042400000000FF150000000083EC1031C083C4145DC3
+    SectionData:     68000000006800000000680000000068000000006800000000
     Relocations:
-      - VirtualAddress:  25
+      - VirtualAddress:  1
+        SymbolName:      _message
+        Type:            IMAGE_REL_I386_SECTION
+      - VirtualAddress:  6
+        SymbolName:      _message
+        Type:            IMAGE_REL_I386_SECREL
+      - VirtualAddress:  11
         SymbolName:      .data
         Type:            IMAGE_REL_I386_DIR32
-      - VirtualAddress:  33
+      - VirtualAddress:  16
         SymbolName:      .data
         Type:            IMAGE_REL_I386_DIR32
-      - VirtualAddress:  46
+      - VirtualAddress:  21
         SymbolName:      __imp__MessageBoxA at 16
         Type:            IMAGE_REL_I386_DIR32
   - Name:            .data
@@ -44,6 +50,12 @@ symbols:
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _message
+    Value:           5
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
   - Name:            __imp__MessageBoxA at 16
     Value:           0
     SectionNumber:   0

Modified: lld/trunk/test/pecoff/reloc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/reloc.test?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/test/pecoff/reloc.test (original)
+++ lld/trunk/test/pecoff/reloc.test Tue Dec  3 03:18:31 2013
@@ -1,40 +1,11 @@
 # RUN: yaml2obj %p/Inputs/reloc.obj.yaml > %t.obj
 #
-# RUN: llvm-objdump -d %t.obj | FileCheck -check-prefix=BEFORE %s
-#
 # RUN: lld -flavor link /out:%t1 /subsystem:console /force /opt:noref \
-# RUN:   -- %t.obj && llvm-objdump -d %t1 | FileCheck -check-prefix=AFTER %s
-
-BEFORE: Disassembly of section .text:
-BEFORE: _main:
-BEFORE:       0:        55
-BEFORE:       1:        89 e5
-BEFORE:       3:        83 ec 14
-BEFORE:       6:        c7 45 fc 00 00 00 00
-BEFORE:       d:        c7 44 24 0c 00 00 00 00
-BEFORE:      15:        c7 44 24 08 07 00 00 00
-BEFORE:      1d:        c7 44 24 04 00 00 00 00
-BEFORE:      25:        c7 04 24 00 00 00 00
-BEFORE:      2c:        ff 15 00 00 00 00
-BEFORE:      32:        83 ec 10
-BEFORE:      35:        31 c0
-BEFORE:      37:        83 c4 14
-BEFORE:      3a:        5d
-BEFORE:      3b:        c3
+# RUN:   -- %t.obj && llvm-objdump -d %t1 | FileCheck %s
 
-AFTER: Disassembly of section .text:
-AFTER: .text:
-AFTER:    pushl  %ebp
-AFTER:    movl   %esp, %ebp
-AFTER:    subl   $20, %esp
-AFTER:    movl   $0, -4(%ebp)
-AFTER:    movl   $0, 12(%esp)
-AFTER:    movl   $4198407, 8(%esp)
-AFTER:    movl   $4198400, 4(%esp)
-AFTER:    movl   $0, (%esp)
-AFTER:    calll  *4194304
-AFTER:    subl   $16, %esp
-AFTER:    xorl   %eax, %eax
-AFTER:    addl   $20, %esp
-AFTER:    popl   %ebp
-AFTER:    ret
+CHECK: .text:
+CHECK:    2000: 68 02 00 00 00
+CHECK:    2005: 68 05 00 00 00
+CHECK:    200a: 68 00 10 40 00
+CHECK:    200f: 68 00 10 40 00
+CHECK:    2014: 68 00 00 40 00





More information about the llvm-commits mailing list