diff options
| author | Sergey Dmitriev <serguei.n.dmitriev@intel.com> | 2019-11-14 09:50:36 -0800 | 
|---|---|---|
| committer | Sergey Dmitriev <serguei.n.dmitriev@intel.com> | 2019-11-14 10:31:50 -0800 | 
| commit | caa9493da85561c6a2308bf9821fe6d14323b8f5 (patch) | |
| tree | 09d07e2a6b9a2f44681b52b2bd0f5baa1c5016c4 /llvm/tools/llvm-objcopy/COFF | |
| parent | c6b09bff5671600f8e764d3847023d0996f328d9 (diff) | |
| download | bcm5719-llvm-caa9493da85561c6a2308bf9821fe6d14323b8f5.tar.gz bcm5719-llvm-caa9493da85561c6a2308bf9821fe6d14323b8f5.zip  | |
[llvm-objcopy][COFF] Add support for extended relocation tables
Summary: This patch adds support for COFF objects with extended relocation tables to the llvm-objcopy tool.
Reviewers: jhenderson, MaskRay, mstorsjo, alexshap, rupprecht
Reviewed By: mstorsjo
Subscribers: jakehehrlich, abrachet, seiya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70205
Diffstat (limited to 'llvm/tools/llvm-objcopy/COFF')
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Reader.cpp | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/COFF/Writer.cpp | 22 | 
2 files changed, 20 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp index 2fcec0057c0..7be9cce2be3 100644 --- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp @@ -63,6 +63,7 @@ Error COFFReader::readSections(Object &Obj) const {      Sections.push_back(Section());      Section &S = Sections.back();      S.Header = *Sec; +    S.Header.Characteristics &= ~COFF::IMAGE_SCN_LNK_NRELOC_OVFL;      ArrayRef<uint8_t> Contents;      if (Error E = COFFObj.getSectionContents(Sec, Contents))        return E; @@ -74,9 +75,6 @@ Error COFFReader::readSections(Object &Obj) const {        S.Name = *NameOrErr;      else        return NameOrErr.takeError(); -    if (Sec->hasExtendedRelocations()) -      return createStringError(object_error::parse_failed, -                               "extended relocations not supported yet");    }    Obj.addSections(Sections);    return Error::success(); diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp index 6db37435fd9..e35e0474a36 100644 --- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp +++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp @@ -97,9 +97,16 @@ void COFFWriter::layoutSections() {        S.Header.PointerToRawData = FileSize;      FileSize += S.Header.SizeOfRawData; // For executables, this is already                                          // aligned to FileAlignment. -    S.Header.NumberOfRelocations = S.Relocs.size(); -    S.Header.PointerToRelocations = -        S.Header.NumberOfRelocations > 0 ? FileSize : 0; +    if (S.Relocs.size() >= 0xffff) { +      S.Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; +      S.Header.NumberOfRelocations = 0xffff; +      S.Header.PointerToRelocations = FileSize; +      FileSize += sizeof(coff_relocation); +    } else { +      S.Header.NumberOfRelocations = S.Relocs.size(); +      S.Header.PointerToRelocations = S.Relocs.size() ? FileSize : 0; +    } +      FileSize += S.Relocs.size() * sizeof(coff_relocation);      FileSize = alignTo(FileSize, FileAlignment); @@ -307,6 +314,15 @@ void COFFWriter::writeSections() {               S.Header.SizeOfRawData - Contents.size());      Ptr += S.Header.SizeOfRawData; + +    if (S.Relocs.size() >= 0xffff) { +      object::coff_relocation R; +      R.VirtualAddress = S.Relocs.size() + 1; +      R.SymbolTableIndex = 0; +      R.Type = 0; +      memcpy(Ptr, &R, sizeof(R)); +      Ptr += sizeof(R); +    }      for (const auto &R : S.Relocs) {        memcpy(Ptr, &R.Reloc, sizeof(R.Reloc));        Ptr += sizeof(R.Reloc);  | 

