Write relocations in yaml2obj.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 23 Apr 2013 15:53:02 +0000 (15:53 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 23 Apr 2013 15:53:02 +0000 (15:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180115 91177308-0d34-0410-b5e6-96231b3b80d8

test/Object/yaml2obj-readobj.test
tools/yaml2obj/yaml2obj.cpp

index 545ccc48aa4cfc75899c5e5d1474ab3aa350b743..3031f5ed31bc37ea2b7fdef57529abd92fd27992 100644 (file)
@@ -1,5 +1,25 @@
-RUN: yaml2obj %p/Inputs/COFF/i386.yaml | llvm-readobj -file-headers - | FileCheck %s --check-prefix COFF-I386
+RUN: yaml2obj %p/Inputs/COFF/i386.yaml | llvm-readobj -file-headers -relocations -expand-relocs - | FileCheck %s --check-prefix COFF-I386
 
 // COFF-I386:  Characteristics [ (0x200)
 // COFF-I386-NEXT:    IMAGE_FILE_DEBUG_STRIPPED (0x200)
 // COFF-I386-NEXT:  ]
+
+// COFF-I386:      Relocations [
+// COFF-I386-NEXT:   Section (1) .text {
+// COFF-I386-NEXT:     Relocation {
+// COFF-I386-NEXT:       Offset: 0xE
+// COFF-I386-NEXT:       Type: IMAGE_REL_I386_DIR32 (6)
+// COFF-I386-NEXT:       Symbol: L_.str
+// COFF-I386-NEXT:     }
+// COFF-I386-NEXT:     Relocation {
+// COFF-I386-NEXT:       Offset: 0x13
+// COFF-I386-NEXT:       Type: IMAGE_REL_I386_REL32 (20)
+// COFF-I386-NEXT:       Symbol: _puts
+// COFF-I386-NEXT:     }
+// COFF-I386-NEXT:     Relocation {
+// COFF-I386-NEXT:       Offset: 0x18
+// COFF-I386-NEXT:       Type: IMAGE_REL_I386_REL32 (20)
+// COFF-I386-NEXT:       Symbol: _SomeOtherFunction
+// COFF-I386-NEXT:     }
+// COFF-I386-NEXT:   }
+// COFF-I386-NEXT: ]
index 5741d95c54225141716b817a0b16fc60e81bc8fc..7f8663b8243d9440605b40225c75b761b8e50b96 100644 (file)
@@ -186,6 +186,7 @@ struct COFFParser {
         errs() << "SectionData must be a collection of pairs of hex bytes";
         return false;
       }
+      Sec.Relocations = YamlSection.Relocations;
       Sections.push_back(Sec);
     }
     return true;
@@ -289,6 +290,12 @@ static bool layoutCOFF(COFFParser &CP) {
       i->Header.SizeOfRawData = i->Data.size();
       i->Header.PointerToRawData = CurrentSectionDataOffset;
       CurrentSectionDataOffset += i->Header.SizeOfRawData;
+      if (!i->Relocations.empty()) {
+        i->Header.PointerToRelocations = CurrentSectionDataOffset;
+        i->Header.NumberOfRelocations = i->Relocations.size();
+        CurrentSectionDataOffset += i->Header.NumberOfRelocations *
+          COFF::RelocationSize;
+      }
       // TODO: Handle alignment.
     } else {
       i->Header.SizeOfRawData = 0;
@@ -374,6 +381,12 @@ void writeCOFF(COFFParser &CP, raw_ostream &OS) {
                                                         i != e; ++i) {
     if (!i->Data.empty())
       OS.write(reinterpret_cast<const char*>(&i->Data[0]), i->Data.size());
+    for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) {
+      const COFF::relocation &R = i->Relocations[I2];
+      OS << binary_le(R.VirtualAddress)
+         << binary_le(R.SymbolTableIndex)
+         << binary_le(R.Type);
+    }
   }
 
   // Output symbol table.