diff --git a/test/Object/yaml2obj-readobj.test b/test/Object/yaml2obj-readobj.test index 545ccc48aa4..3031f5ed31b 100644 --- a/test/Object/yaml2obj-readobj.test +++ b/test/Object/yaml2obj-readobj.test @@ -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: ] diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 5741d95c542..7f8663b8243 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -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(&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.