aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/tools/llvm-objcopy/COFF
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/llvm12/tools/llvm-objcopy/COFF
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/tools/llvm-objcopy/COFF')
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp538
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.h62
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp200
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h418
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.cpp452
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.h84
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.cpp898
-rw-r--r--contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.h124
8 files changed, 1388 insertions, 1388 deletions
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index b5de8a45a8..3c058e4785 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -1,292 +1,292 @@
-//===- COFFObjcopy.cpp ----------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "COFFObjcopy.h"
-#include "Buffer.h"
-#include "CopyConfig.h"
-#include "Object.h"
-#include "Reader.h"
-#include "Writer.h"
-
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/CRC.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Path.h"
-#include <cassert>
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-using namespace object;
-using namespace COFF;
-
-static bool isDebugSection(const Section &Sec) {
- return Sec.Name.startswith(".debug");
-}
-
-static uint64_t getNextRVA(const Object &Obj) {
- if (Obj.getSections().empty())
- return 0;
- const Section &Last = Obj.getSections().back();
- return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
- Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
-}
-
+//===- COFFObjcopy.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "COFFObjcopy.h"
+#include "Buffer.h"
+#include "CopyConfig.h"
+#include "Object.h"
+#include "Reader.h"
+#include "Writer.h"
+
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/CRC.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Path.h"
+#include <cassert>
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+using namespace object;
+using namespace COFF;
+
+static bool isDebugSection(const Section &Sec) {
+ return Sec.Name.startswith(".debug");
+}
+
+static uint64_t getNextRVA(const Object &Obj) {
+ if (Obj.getSections().empty())
+ return 0;
+ const Section &Last = Obj.getSections().back();
+ return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
+ Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
+}
+
static Expected<std::vector<uint8_t>>
createGnuDebugLinkSectionContents(StringRef File) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> LinkTargetOrErr =
- MemoryBuffer::getFile(File);
- if (!LinkTargetOrErr)
+ ErrorOr<std::unique_ptr<MemoryBuffer>> LinkTargetOrErr =
+ MemoryBuffer::getFile(File);
+ if (!LinkTargetOrErr)
return createFileError(File, LinkTargetOrErr.getError());
- auto LinkTarget = std::move(*LinkTargetOrErr);
- uint32_t CRC32 = llvm::crc32(arrayRefFromStringRef(LinkTarget->getBuffer()));
-
- StringRef FileName = sys::path::filename(File);
- size_t CRCPos = alignTo(FileName.size() + 1, 4);
- std::vector<uint8_t> Data(CRCPos + 4);
- memcpy(Data.data(), FileName.data(), FileName.size());
- support::endian::write32le(Data.data() + CRCPos, CRC32);
- return Data;
-}
-
-// Adds named section with given contents to the object.
-static void addSection(Object &Obj, StringRef Name, ArrayRef<uint8_t> Contents,
- uint32_t Characteristics) {
- bool NeedVA = Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
- IMAGE_SCN_MEM_WRITE);
-
- Section Sec;
- Sec.setOwnedContents(Contents);
- Sec.Name = Name;
- Sec.Header.VirtualSize = NeedVA ? Sec.getContents().size() : 0u;
- Sec.Header.VirtualAddress = NeedVA ? getNextRVA(Obj) : 0u;
- Sec.Header.SizeOfRawData =
- NeedVA ? alignTo(Sec.Header.VirtualSize,
- Obj.IsPE ? Obj.PeHeader.FileAlignment : 1)
- : Sec.getContents().size();
- // Sec.Header.PointerToRawData is filled in by the writer.
- Sec.Header.PointerToRelocations = 0;
- Sec.Header.PointerToLinenumbers = 0;
- // Sec.Header.NumberOfRelocations is filled in by the writer.
- Sec.Header.NumberOfLinenumbers = 0;
- Sec.Header.Characteristics = Characteristics;
-
- Obj.addSections(Sec);
-}
-
+ auto LinkTarget = std::move(*LinkTargetOrErr);
+ uint32_t CRC32 = llvm::crc32(arrayRefFromStringRef(LinkTarget->getBuffer()));
+
+ StringRef FileName = sys::path::filename(File);
+ size_t CRCPos = alignTo(FileName.size() + 1, 4);
+ std::vector<uint8_t> Data(CRCPos + 4);
+ memcpy(Data.data(), FileName.data(), FileName.size());
+ support::endian::write32le(Data.data() + CRCPos, CRC32);
+ return Data;
+}
+
+// Adds named section with given contents to the object.
+static void addSection(Object &Obj, StringRef Name, ArrayRef<uint8_t> Contents,
+ uint32_t Characteristics) {
+ bool NeedVA = Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ |
+ IMAGE_SCN_MEM_WRITE);
+
+ Section Sec;
+ Sec.setOwnedContents(Contents);
+ Sec.Name = Name;
+ Sec.Header.VirtualSize = NeedVA ? Sec.getContents().size() : 0u;
+ Sec.Header.VirtualAddress = NeedVA ? getNextRVA(Obj) : 0u;
+ Sec.Header.SizeOfRawData =
+ NeedVA ? alignTo(Sec.Header.VirtualSize,
+ Obj.IsPE ? Obj.PeHeader.FileAlignment : 1)
+ : Sec.getContents().size();
+ // Sec.Header.PointerToRawData is filled in by the writer.
+ Sec.Header.PointerToRelocations = 0;
+ Sec.Header.PointerToLinenumbers = 0;
+ // Sec.Header.NumberOfRelocations is filled in by the writer.
+ Sec.Header.NumberOfLinenumbers = 0;
+ Sec.Header.Characteristics = Characteristics;
+
+ Obj.addSections(Sec);
+}
+
static Error addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
Expected<std::vector<uint8_t>> Contents =
- createGnuDebugLinkSectionContents(DebugLinkFile);
+ createGnuDebugLinkSectionContents(DebugLinkFile);
if (!Contents)
return Contents.takeError();
addSection(Obj, ".gnu_debuglink", *Contents,
- IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
- IMAGE_SCN_MEM_DISCARDABLE);
+ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
+ IMAGE_SCN_MEM_DISCARDABLE);
return Error::success();
-}
-
-static void setSectionFlags(Section &Sec, SectionFlag AllFlags) {
- // Need to preserve alignment flags.
- const uint32_t PreserveMask =
- IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_ALIGN_4BYTES |
- IMAGE_SCN_ALIGN_8BYTES | IMAGE_SCN_ALIGN_16BYTES |
- IMAGE_SCN_ALIGN_32BYTES | IMAGE_SCN_ALIGN_64BYTES |
- IMAGE_SCN_ALIGN_128BYTES | IMAGE_SCN_ALIGN_256BYTES |
- IMAGE_SCN_ALIGN_512BYTES | IMAGE_SCN_ALIGN_1024BYTES |
- IMAGE_SCN_ALIGN_2048BYTES | IMAGE_SCN_ALIGN_4096BYTES |
- IMAGE_SCN_ALIGN_8192BYTES;
-
- // Setup new section characteristics based on the flags provided in command
- // line.
- uint32_t NewCharacteristics =
- (Sec.Header.Characteristics & PreserveMask) | IMAGE_SCN_MEM_READ;
-
- if ((AllFlags & SectionFlag::SecAlloc) && !(AllFlags & SectionFlag::SecLoad))
- NewCharacteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
- if (AllFlags & SectionFlag::SecNoload)
- NewCharacteristics |= IMAGE_SCN_LNK_REMOVE;
- if (!(AllFlags & SectionFlag::SecReadonly))
- NewCharacteristics |= IMAGE_SCN_MEM_WRITE;
- if (AllFlags & SectionFlag::SecDebug)
- NewCharacteristics |=
- IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE;
- if (AllFlags & SectionFlag::SecCode)
- NewCharacteristics |= IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
- if (AllFlags & SectionFlag::SecData)
- NewCharacteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
- if (AllFlags & SectionFlag::SecShare)
- NewCharacteristics |= IMAGE_SCN_MEM_SHARED;
- if (AllFlags & SectionFlag::SecExclude)
- NewCharacteristics |= IMAGE_SCN_LNK_REMOVE;
-
- Sec.Header.Characteristics = NewCharacteristics;
-}
-
-static Error handleArgs(const CopyConfig &Config, Object &Obj) {
- // Perform the actual section removals.
- Obj.removeSections([&Config](const Section &Sec) {
- // Contrary to --only-keep-debug, --only-section fully removes sections that
- // aren't mentioned.
- if (!Config.OnlySection.empty() && !Config.OnlySection.matches(Sec.Name))
- return true;
-
- if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
- Config.DiscardMode == DiscardType::All || Config.StripUnneeded) {
- if (isDebugSection(Sec) &&
- (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
- return true;
- }
-
- if (Config.ToRemove.matches(Sec.Name))
- return true;
-
- return false;
- });
-
- if (Config.OnlyKeepDebug) {
- // For --only-keep-debug, we keep all other sections, but remove their
- // content. The VirtualSize field in the section header is kept intact.
- Obj.truncateSections([](const Section &Sec) {
- return !isDebugSection(Sec) && Sec.Name != ".buildid" &&
- ((Sec.Header.Characteristics &
- (IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA)) != 0);
- });
- }
-
- // StripAll removes all symbols and thus also removes all relocations.
- if (Config.StripAll || Config.StripAllGNU)
- for (Section &Sec : Obj.getMutableSections())
- Sec.Relocs.clear();
-
- // If we need to do per-symbol removals, initialize the Referenced field.
- if (Config.StripUnneeded || Config.DiscardMode == DiscardType::All ||
- !Config.SymbolsToRemove.empty())
- if (Error E = Obj.markSymbols())
- return E;
-
- for (Symbol &Sym : Obj.getMutableSymbols()) {
- auto I = Config.SymbolsToRename.find(Sym.Name);
- if (I != Config.SymbolsToRename.end())
- Sym.Name = I->getValue();
- }
-
+}
+
+static void setSectionFlags(Section &Sec, SectionFlag AllFlags) {
+ // Need to preserve alignment flags.
+ const uint32_t PreserveMask =
+ IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_ALIGN_4BYTES |
+ IMAGE_SCN_ALIGN_8BYTES | IMAGE_SCN_ALIGN_16BYTES |
+ IMAGE_SCN_ALIGN_32BYTES | IMAGE_SCN_ALIGN_64BYTES |
+ IMAGE_SCN_ALIGN_128BYTES | IMAGE_SCN_ALIGN_256BYTES |
+ IMAGE_SCN_ALIGN_512BYTES | IMAGE_SCN_ALIGN_1024BYTES |
+ IMAGE_SCN_ALIGN_2048BYTES | IMAGE_SCN_ALIGN_4096BYTES |
+ IMAGE_SCN_ALIGN_8192BYTES;
+
+ // Setup new section characteristics based on the flags provided in command
+ // line.
+ uint32_t NewCharacteristics =
+ (Sec.Header.Characteristics & PreserveMask) | IMAGE_SCN_MEM_READ;
+
+ if ((AllFlags & SectionFlag::SecAlloc) && !(AllFlags & SectionFlag::SecLoad))
+ NewCharacteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
+ if (AllFlags & SectionFlag::SecNoload)
+ NewCharacteristics |= IMAGE_SCN_LNK_REMOVE;
+ if (!(AllFlags & SectionFlag::SecReadonly))
+ NewCharacteristics |= IMAGE_SCN_MEM_WRITE;
+ if (AllFlags & SectionFlag::SecDebug)
+ NewCharacteristics |=
+ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE;
+ if (AllFlags & SectionFlag::SecCode)
+ NewCharacteristics |= IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE;
+ if (AllFlags & SectionFlag::SecData)
+ NewCharacteristics |= IMAGE_SCN_CNT_INITIALIZED_DATA;
+ if (AllFlags & SectionFlag::SecShare)
+ NewCharacteristics |= IMAGE_SCN_MEM_SHARED;
+ if (AllFlags & SectionFlag::SecExclude)
+ NewCharacteristics |= IMAGE_SCN_LNK_REMOVE;
+
+ Sec.Header.Characteristics = NewCharacteristics;
+}
+
+static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
+ // Contrary to --only-keep-debug, --only-section fully removes sections that
+ // aren't mentioned.
+ if (!Config.OnlySection.empty() && !Config.OnlySection.matches(Sec.Name))
+ return true;
+
+ if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
+ Config.DiscardMode == DiscardType::All || Config.StripUnneeded) {
+ if (isDebugSection(Sec) &&
+ (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
+ return true;
+ }
+
+ if (Config.ToRemove.matches(Sec.Name))
+ return true;
+
+ return false;
+ });
+
+ if (Config.OnlyKeepDebug) {
+ // For --only-keep-debug, we keep all other sections, but remove their
+ // content. The VirtualSize field in the section header is kept intact.
+ Obj.truncateSections([](const Section &Sec) {
+ return !isDebugSection(Sec) && Sec.Name != ".buildid" &&
+ ((Sec.Header.Characteristics &
+ (IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA)) != 0);
+ });
+ }
+
+ // StripAll removes all symbols and thus also removes all relocations.
+ if (Config.StripAll || Config.StripAllGNU)
+ for (Section &Sec : Obj.getMutableSections())
+ Sec.Relocs.clear();
+
+ // If we need to do per-symbol removals, initialize the Referenced field.
+ if (Config.StripUnneeded || Config.DiscardMode == DiscardType::All ||
+ !Config.SymbolsToRemove.empty())
+ if (Error E = Obj.markSymbols())
+ return E;
+
+ for (Symbol &Sym : Obj.getMutableSymbols()) {
+ auto I = Config.SymbolsToRename.find(Sym.Name);
+ if (I != Config.SymbolsToRename.end())
+ Sym.Name = I->getValue();
+ }
+
auto ToRemove = [&](const Symbol &Sym) -> Expected<bool> {
- // For StripAll, all relocations have been stripped and we remove all
- // symbols.
- if (Config.StripAll || Config.StripAllGNU)
- return true;
-
- if (Config.SymbolsToRemove.matches(Sym.Name)) {
- // Explicitly removing a referenced symbol is an error.
- if (Sym.Referenced)
+ // For StripAll, all relocations have been stripped and we remove all
+ // symbols.
+ if (Config.StripAll || Config.StripAllGNU)
+ return true;
+
+ if (Config.SymbolsToRemove.matches(Sym.Name)) {
+ // Explicitly removing a referenced symbol is an error.
+ if (Sym.Referenced)
return createStringError(
llvm::errc::invalid_argument,
"'" + Config.OutputFilename + "': not stripping symbol '" +
Sym.Name.str() + "' because it is named in a relocation");
- return true;
- }
-
- if (!Sym.Referenced) {
- // With --strip-unneeded, GNU objcopy removes all unreferenced local
- // symbols, and any unreferenced undefined external.
- // With --strip-unneeded-symbol we strip only specific unreferenced
- // local symbol instead of removing all of such.
- if (Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC ||
- Sym.Sym.SectionNumber == 0)
- if (Config.StripUnneeded ||
- Config.UnneededSymbolsToRemove.matches(Sym.Name))
- return true;
-
- // GNU objcopy keeps referenced local symbols and external symbols
- // if --discard-all is set, similar to what --strip-unneeded does,
- // but undefined local symbols are kept when --discard-all is set.
- if (Config.DiscardMode == DiscardType::All &&
- Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC &&
- Sym.Sym.SectionNumber != 0)
- return true;
- }
-
- return false;
+ return true;
+ }
+
+ if (!Sym.Referenced) {
+ // With --strip-unneeded, GNU objcopy removes all unreferenced local
+ // symbols, and any unreferenced undefined external.
+ // With --strip-unneeded-symbol we strip only specific unreferenced
+ // local symbol instead of removing all of such.
+ if (Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC ||
+ Sym.Sym.SectionNumber == 0)
+ if (Config.StripUnneeded ||
+ Config.UnneededSymbolsToRemove.matches(Sym.Name))
+ return true;
+
+ // GNU objcopy keeps referenced local symbols and external symbols
+ // if --discard-all is set, similar to what --strip-unneeded does,
+ // but undefined local symbols are kept when --discard-all is set.
+ if (Config.DiscardMode == DiscardType::All &&
+ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC &&
+ Sym.Sym.SectionNumber != 0)
+ return true;
+ }
+
+ return false;
};
-
+
// Actually do removals of symbols.
if (Error Err = Obj.removeSymbols(ToRemove))
return Err;
- if (!Config.SetSectionFlags.empty())
- for (Section &Sec : Obj.getMutableSections()) {
- const auto It = Config.SetSectionFlags.find(Sec.Name);
- if (It != Config.SetSectionFlags.end())
- setSectionFlags(Sec, It->second.NewFlags);
- }
-
- for (const auto &Flag : Config.AddSection) {
- StringRef SecName, FileName;
- std::tie(SecName, FileName) = Flag.split("=");
-
- auto BufOrErr = MemoryBuffer::getFile(FileName);
- if (!BufOrErr)
- return createFileError(FileName, errorCodeToError(BufOrErr.getError()));
- auto Buf = std::move(*BufOrErr);
-
- addSection(
- Obj, SecName,
- makeArrayRef(reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
- Buf->getBufferSize()),
- IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_1BYTES);
- }
-
- if (!Config.AddGnuDebugLink.empty())
+ if (!Config.SetSectionFlags.empty())
+ for (Section &Sec : Obj.getMutableSections()) {
+ const auto It = Config.SetSectionFlags.find(Sec.Name);
+ if (It != Config.SetSectionFlags.end())
+ setSectionFlags(Sec, It->second.NewFlags);
+ }
+
+ for (const auto &Flag : Config.AddSection) {
+ StringRef SecName, FileName;
+ std::tie(SecName, FileName) = Flag.split("=");
+
+ auto BufOrErr = MemoryBuffer::getFile(FileName);
+ if (!BufOrErr)
+ return createFileError(FileName, errorCodeToError(BufOrErr.getError()));
+ auto Buf = std::move(*BufOrErr);
+
+ addSection(
+ Obj, SecName,
+ makeArrayRef(reinterpret_cast<const uint8_t *>(Buf->getBufferStart()),
+ Buf->getBufferSize()),
+ IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_1BYTES);
+ }
+
+ if (!Config.AddGnuDebugLink.empty())
if (Error E = addGnuDebugLink(Obj, Config.AddGnuDebugLink))
return E;
-
- if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
- Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
- !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
- !Config.AllocSectionsPrefix.empty() || !Config.DumpSection.empty() ||
- !Config.KeepSection.empty() || Config.NewSymbolVisibility ||
- !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
- !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
- !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
- !Config.SetSectionAlignment.empty() || Config.ExtractDWO ||
- Config.LocalizeHidden || Config.PreserveDates || Config.StripDWO ||
- Config.StripNonAlloc || Config.StripSections ||
- Config.StripSwiftSymbols || Config.Weaken ||
- Config.DecompressDebugSections ||
- Config.DiscardMode == DiscardType::Locals ||
- !Config.SymbolsToAdd.empty() || Config.EntryExpr) {
- return createStringError(llvm::errc::invalid_argument,
- "option not supported by llvm-objcopy for COFF");
- }
-
- return Error::success();
-}
-
-Error executeObjcopyOnBinary(const CopyConfig &Config, COFFObjectFile &In,
- Buffer &Out) {
- COFFReader Reader(In);
- Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
- if (!ObjOrErr)
- return createFileError(Config.InputFilename, ObjOrErr.takeError());
- Object *Obj = ObjOrErr->get();
- assert(Obj && "Unable to deserialize COFF object");
- if (Error E = handleArgs(Config, *Obj))
- return createFileError(Config.InputFilename, std::move(E));
- COFFWriter Writer(*Obj, Out);
- if (Error E = Writer.write())
- return createFileError(Config.OutputFilename, std::move(E));
- return Error::success();
-}
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
+
+ if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
+ Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
+ !Config.SplitDWO.empty() || !Config.SymbolsPrefix.empty() ||
+ !Config.AllocSectionsPrefix.empty() || !Config.DumpSection.empty() ||
+ !Config.KeepSection.empty() || Config.NewSymbolVisibility ||
+ !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
+ !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
+ !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
+ !Config.SetSectionAlignment.empty() || Config.ExtractDWO ||
+ Config.LocalizeHidden || Config.PreserveDates || Config.StripDWO ||
+ Config.StripNonAlloc || Config.StripSections ||
+ Config.StripSwiftSymbols || Config.Weaken ||
+ Config.DecompressDebugSections ||
+ Config.DiscardMode == DiscardType::Locals ||
+ !Config.SymbolsToAdd.empty() || Config.EntryExpr) {
+ return createStringError(llvm::errc::invalid_argument,
+ "option not supported by llvm-objcopy for COFF");
+ }
+
+ return Error::success();
+}
+
+Error executeObjcopyOnBinary(const CopyConfig &Config, COFFObjectFile &In,
+ Buffer &Out) {
+ COFFReader Reader(In);
+ Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
+ if (!ObjOrErr)
+ return createFileError(Config.InputFilename, ObjOrErr.takeError());
+ Object *Obj = ObjOrErr->get();
+ assert(Obj && "Unable to deserialize COFF object");
+ if (Error E = handleArgs(Config, *Obj))
+ return createFileError(Config.InputFilename, std::move(E));
+ COFFWriter Writer(*Obj, Out);
+ if (Error E = Writer.write())
+ return createFileError(Config.OutputFilename, std::move(E));
+ return Error::success();
+}
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.h b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.h
index 858759e52c..6b59f44946 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/COFFObjcopy.h
@@ -1,31 +1,31 @@
-//===- COFFObjcopy.h --------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
-#define LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
-
-namespace llvm {
-class Error;
-
-namespace object {
-class COFFObjectFile;
-} // end namespace object
-
-namespace objcopy {
-struct CopyConfig;
-class Buffer;
-
-namespace coff {
-Error executeObjcopyOnBinary(const CopyConfig &Config,
- object::COFFObjectFile &In, Buffer &Out);
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
-
-#endif // LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
+//===- COFFObjcopy.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
+#define LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
+
+namespace llvm {
+class Error;
+
+namespace object {
+class COFFObjectFile;
+} // end namespace object
+
+namespace objcopy {
+struct CopyConfig;
+class Buffer;
+
+namespace coff {
+Error executeObjcopyOnBinary(const CopyConfig &Config,
+ object::COFFObjectFile &In, Buffer &Out);
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp
index 1c17b8408e..fc67f1cb4d 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.cpp
@@ -1,39 +1,39 @@
-//===- Object.cpp ---------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "Object.h"
-#include "llvm/ADT/DenseSet.h"
-#include <algorithm>
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-using namespace object;
-
-void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
- for (Symbol S : NewSymbols) {
- S.UniqueId = NextSymbolUniqueId++;
- Symbols.emplace_back(S);
- }
- updateSymbols();
-}
-
-void Object::updateSymbols() {
- SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size());
- for (Symbol &Sym : Symbols)
- SymbolMap[Sym.UniqueId] = &Sym;
-}
-
-const Symbol *Object::findSymbol(size_t UniqueId) const {
+//===- Object.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Object.h"
+#include "llvm/ADT/DenseSet.h"
+#include <algorithm>
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+using namespace object;
+
+void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
+ for (Symbol S : NewSymbols) {
+ S.UniqueId = NextSymbolUniqueId++;
+ Symbols.emplace_back(S);
+ }
+ updateSymbols();
+}
+
+void Object::updateSymbols() {
+ SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size());
+ for (Symbol &Sym : Symbols)
+ SymbolMap[Sym.UniqueId] = &Sym;
+}
+
+const Symbol *Object::findSymbol(size_t UniqueId) const {
return SymbolMap.lookup(UniqueId);
-}
-
+}
+
Error Object::removeSymbols(
function_ref<Expected<bool>(const Symbol &)> ToRemove) {
Error Errs = Error::success();
@@ -46,61 +46,61 @@ Error Object::removeSymbols(
return *ShouldRemove;
});
- updateSymbols();
+ updateSymbols();
return Errs;
-}
-
-Error Object::markSymbols() {
- for (Symbol &Sym : Symbols)
- Sym.Referenced = false;
- for (const Section &Sec : Sections) {
- for (const Relocation &R : Sec.Relocs) {
- auto It = SymbolMap.find(R.Target);
- if (It == SymbolMap.end())
- return createStringError(object_error::invalid_symbol_index,
- "relocation target %zu not found", R.Target);
- It->second->Referenced = true;
- }
- }
- return Error::success();
-}
-
-void Object::addSections(ArrayRef<Section> NewSections) {
- for (Section S : NewSections) {
- S.UniqueId = NextSectionUniqueId++;
- Sections.emplace_back(S);
- }
- updateSections();
-}
-
-void Object::updateSections() {
- SectionMap = DenseMap<ssize_t, Section *>(Sections.size());
- size_t Index = 1;
- for (Section &S : Sections) {
- SectionMap[S.UniqueId] = &S;
- S.Index = Index++;
- }
-}
-
-const Section *Object::findSection(ssize_t UniqueId) const {
+}
+
+Error Object::markSymbols() {
+ for (Symbol &Sym : Symbols)
+ Sym.Referenced = false;
+ for (const Section &Sec : Sections) {
+ for (const Relocation &R : Sec.Relocs) {
+ auto It = SymbolMap.find(R.Target);
+ if (It == SymbolMap.end())
+ return createStringError(object_error::invalid_symbol_index,
+ "relocation target %zu not found", R.Target);
+ It->second->Referenced = true;
+ }
+ }
+ return Error::success();
+}
+
+void Object::addSections(ArrayRef<Section> NewSections) {
+ for (Section S : NewSections) {
+ S.UniqueId = NextSectionUniqueId++;
+ Sections.emplace_back(S);
+ }
+ updateSections();
+}
+
+void Object::updateSections() {
+ SectionMap = DenseMap<ssize_t, Section *>(Sections.size());
+ size_t Index = 1;
+ for (Section &S : Sections) {
+ SectionMap[S.UniqueId] = &S;
+ S.Index = Index++;
+ }
+}
+
+const Section *Object::findSection(ssize_t UniqueId) const {
return SectionMap.lookup(UniqueId);
-}
-
-void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
- DenseSet<ssize_t> AssociatedSections;
- auto RemoveAssociated = [&AssociatedSections](const Section &Sec) {
+}
+
+void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
+ DenseSet<ssize_t> AssociatedSections;
+ auto RemoveAssociated = [&AssociatedSections](const Section &Sec) {
return AssociatedSections.contains(Sec.UniqueId);
- };
- do {
- DenseSet<ssize_t> RemovedSections;
+ };
+ do {
+ DenseSet<ssize_t> RemovedSections;
llvm::erase_if(Sections, [ToRemove, &RemovedSections](const Section &Sec) {
bool Remove = ToRemove(Sec);
if (Remove)
RemovedSections.insert(Sec.UniqueId);
return Remove;
});
- // Remove all symbols referring to the removed sections.
- AssociatedSections.clear();
+ // Remove all symbols referring to the removed sections.
+ AssociatedSections.clear();
llvm::erase_if(
Symbols, [&RemovedSections, &AssociatedSections](const Symbol &Sym) {
// If there are sections that are associative to a removed
@@ -111,22 +111,22 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
AssociatedSections.insert(Sym.TargetSectionId);
return RemovedSections.contains(Sym.TargetSectionId);
});
- ToRemove = RemoveAssociated;
- } while (!AssociatedSections.empty());
- updateSections();
- updateSymbols();
-}
-
-void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) {
- for (Section &Sec : Sections) {
- if (ToTruncate(Sec)) {
- Sec.clearContents();
- Sec.Relocs.clear();
- Sec.Header.SizeOfRawData = 0;
- }
- }
-}
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
+ ToRemove = RemoveAssociated;
+ } while (!AssociatedSections.empty());
+ updateSections();
+ updateSymbols();
+}
+
+void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) {
+ for (Section &Sec : Sections) {
+ if (ToTruncate(Sec)) {
+ Sec.clearContents();
+ Sec.Relocs.clear();
+ Sec.Header.SizeOfRawData = 0;
+ }
+ }
+}
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h
index 0e854b58cb..9602f56e63 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Object.h
@@ -1,211 +1,211 @@
-//===- Object.h -------------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
-#define LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Object/COFF.h"
-#include <cstddef>
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-struct Relocation {
- Relocation() = default;
+//===- Object.h -------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
+#define LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/COFF.h"
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+struct Relocation {
+ Relocation() = default;
Relocation(const object::coff_relocation &R) : Reloc(R) {}
-
- object::coff_relocation Reloc;
- size_t Target = 0;
- StringRef TargetName; // Used for diagnostics only
-};
-
-struct Section {
- object::coff_section Header;
- std::vector<Relocation> Relocs;
- StringRef Name;
- ssize_t UniqueId;
- size_t Index;
-
- ArrayRef<uint8_t> getContents() const {
- if (!OwnedContents.empty())
- return OwnedContents;
- return ContentsRef;
- }
-
- void setContentsRef(ArrayRef<uint8_t> Data) {
- OwnedContents.clear();
- ContentsRef = Data;
- }
-
- void setOwnedContents(std::vector<uint8_t> &&Data) {
- ContentsRef = ArrayRef<uint8_t>();
- OwnedContents = std::move(Data);
- }
-
- void clearContents() {
- ContentsRef = ArrayRef<uint8_t>();
- OwnedContents.clear();
- }
-
-private:
- ArrayRef<uint8_t> ContentsRef;
- std::vector<uint8_t> OwnedContents;
-};
-
-struct AuxSymbol {
- AuxSymbol(ArrayRef<uint8_t> In) {
- assert(In.size() == sizeof(Opaque));
- std::copy(In.begin(), In.end(), Opaque);
- }
-
- ArrayRef<uint8_t> getRef() const {
- return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
- }
-
- uint8_t Opaque[sizeof(object::coff_symbol16)];
-};
-
-struct Symbol {
- object::coff_symbol32 Sym;
- StringRef Name;
- std::vector<AuxSymbol> AuxData;
- StringRef AuxFile;
- ssize_t TargetSectionId;
- ssize_t AssociativeComdatTargetSectionId = 0;
- Optional<size_t> WeakTargetSymbolId;
- size_t UniqueId;
- size_t RawIndex;
- bool Referenced;
-};
-
-struct Object {
- bool IsPE = false;
-
- object::dos_header DosHeader;
- ArrayRef<uint8_t> DosStub;
-
- object::coff_file_header CoffFileHeader;
-
- bool Is64 = false;
- object::pe32plus_header PeHeader;
- uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
-
- std::vector<object::data_directory> DataDirectories;
-
- ArrayRef<Symbol> getSymbols() const { return Symbols; }
- // This allows mutating individual Symbols, but not mutating the list
- // of symbols itself.
- iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {
- return make_range(Symbols.begin(), Symbols.end());
- }
-
- const Symbol *findSymbol(size_t UniqueId) const;
-
- void addSymbols(ArrayRef<Symbol> NewSymbols);
+
+ object::coff_relocation Reloc;
+ size_t Target = 0;
+ StringRef TargetName; // Used for diagnostics only
+};
+
+struct Section {
+ object::coff_section Header;
+ std::vector<Relocation> Relocs;
+ StringRef Name;
+ ssize_t UniqueId;
+ size_t Index;
+
+ ArrayRef<uint8_t> getContents() const {
+ if (!OwnedContents.empty())
+ return OwnedContents;
+ return ContentsRef;
+ }
+
+ void setContentsRef(ArrayRef<uint8_t> Data) {
+ OwnedContents.clear();
+ ContentsRef = Data;
+ }
+
+ void setOwnedContents(std::vector<uint8_t> &&Data) {
+ ContentsRef = ArrayRef<uint8_t>();
+ OwnedContents = std::move(Data);
+ }
+
+ void clearContents() {
+ ContentsRef = ArrayRef<uint8_t>();
+ OwnedContents.clear();
+ }
+
+private:
+ ArrayRef<uint8_t> ContentsRef;
+ std::vector<uint8_t> OwnedContents;
+};
+
+struct AuxSymbol {
+ AuxSymbol(ArrayRef<uint8_t> In) {
+ assert(In.size() == sizeof(Opaque));
+ std::copy(In.begin(), In.end(), Opaque);
+ }
+
+ ArrayRef<uint8_t> getRef() const {
+ return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
+ }
+
+ uint8_t Opaque[sizeof(object::coff_symbol16)];
+};
+
+struct Symbol {
+ object::coff_symbol32 Sym;
+ StringRef Name;
+ std::vector<AuxSymbol> AuxData;
+ StringRef AuxFile;
+ ssize_t TargetSectionId;
+ ssize_t AssociativeComdatTargetSectionId = 0;
+ Optional<size_t> WeakTargetSymbolId;
+ size_t UniqueId;
+ size_t RawIndex;
+ bool Referenced;
+};
+
+struct Object {
+ bool IsPE = false;
+
+ object::dos_header DosHeader;
+ ArrayRef<uint8_t> DosStub;
+
+ object::coff_file_header CoffFileHeader;
+
+ bool Is64 = false;
+ object::pe32plus_header PeHeader;
+ uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
+
+ std::vector<object::data_directory> DataDirectories;
+
+ ArrayRef<Symbol> getSymbols() const { return Symbols; }
+ // This allows mutating individual Symbols, but not mutating the list
+ // of symbols itself.
+ iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {
+ return make_range(Symbols.begin(), Symbols.end());
+ }
+
+ const Symbol *findSymbol(size_t UniqueId) const;
+
+ void addSymbols(ArrayRef<Symbol> NewSymbols);
Error removeSymbols(function_ref<Expected<bool>(const Symbol &)> ToRemove);
-
- // Set the Referenced field on all Symbols, based on relocations in
- // all sections.
- Error markSymbols();
-
- ArrayRef<Section> getSections() const { return Sections; }
- // This allows mutating individual Sections, but not mutating the list
- // of sections itself.
- iterator_range<std::vector<Section>::iterator> getMutableSections() {
- return make_range(Sections.begin(), Sections.end());
- }
-
- const Section *findSection(ssize_t UniqueId) const;
-
- void addSections(ArrayRef<Section> NewSections);
- void removeSections(function_ref<bool(const Section &)> ToRemove);
- void truncateSections(function_ref<bool(const Section &)> ToTruncate);
-
-private:
- std::vector<Symbol> Symbols;
- DenseMap<size_t, Symbol *> SymbolMap;
-
- size_t NextSymbolUniqueId = 0;
-
- std::vector<Section> Sections;
- DenseMap<ssize_t, Section *> SectionMap;
-
- ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
-
- // Update SymbolMap.
- void updateSymbols();
-
- // Update SectionMap and Index in each Section.
- void updateSections();
-};
-
-// Copy between coff_symbol16 and coff_symbol32.
-// The source and destination files can use either coff_symbol16 or
-// coff_symbol32, while we always store them as coff_symbol32 in the
-// intermediate data structure.
-template <class Symbol1Ty, class Symbol2Ty>
-void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
- static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),
- "Mismatched name sizes");
- memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));
- Dest.Value = Src.Value;
- Dest.SectionNumber = Src.SectionNumber;
- Dest.Type = Src.Type;
- Dest.StorageClass = Src.StorageClass;
- Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
-}
-
-// Copy between pe32_header and pe32plus_header.
-// We store the intermediate state in a pe32plus_header.
-template <class PeHeader1Ty, class PeHeader2Ty>
-void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {
- Dest.Magic = Src.Magic;
- Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
- Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
- Dest.SizeOfCode = Src.SizeOfCode;
- Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
- Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;
- Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
- Dest.BaseOfCode = Src.BaseOfCode;
- Dest.ImageBase = Src.ImageBase;
- Dest.SectionAlignment = Src.SectionAlignment;
- Dest.FileAlignment = Src.FileAlignment;
- Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;
- Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;
- Dest.MajorImageVersion = Src.MajorImageVersion;
- Dest.MinorImageVersion = Src.MinorImageVersion;
- Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
- Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
- Dest.Win32VersionValue = Src.Win32VersionValue;
- Dest.SizeOfImage = Src.SizeOfImage;
- Dest.SizeOfHeaders = Src.SizeOfHeaders;
- Dest.CheckSum = Src.CheckSum;
- Dest.Subsystem = Src.Subsystem;
- Dest.DLLCharacteristics = Src.DLLCharacteristics;
- Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
- Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
- Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
- Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
- Dest.LoaderFlags = Src.LoaderFlags;
- Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
-}
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
-
-#endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
+
+ // Set the Referenced field on all Symbols, based on relocations in
+ // all sections.
+ Error markSymbols();
+
+ ArrayRef<Section> getSections() const { return Sections; }
+ // This allows mutating individual Sections, but not mutating the list
+ // of sections itself.
+ iterator_range<std::vector<Section>::iterator> getMutableSections() {
+ return make_range(Sections.begin(), Sections.end());
+ }
+
+ const Section *findSection(ssize_t UniqueId) const;
+
+ void addSections(ArrayRef<Section> NewSections);
+ void removeSections(function_ref<bool(const Section &)> ToRemove);
+ void truncateSections(function_ref<bool(const Section &)> ToTruncate);
+
+private:
+ std::vector<Symbol> Symbols;
+ DenseMap<size_t, Symbol *> SymbolMap;
+
+ size_t NextSymbolUniqueId = 0;
+
+ std::vector<Section> Sections;
+ DenseMap<ssize_t, Section *> SectionMap;
+
+ ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
+
+ // Update SymbolMap.
+ void updateSymbols();
+
+ // Update SectionMap and Index in each Section.
+ void updateSections();
+};
+
+// Copy between coff_symbol16 and coff_symbol32.
+// The source and destination files can use either coff_symbol16 or
+// coff_symbol32, while we always store them as coff_symbol32 in the
+// intermediate data structure.
+template <class Symbol1Ty, class Symbol2Ty>
+void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {
+ static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),
+ "Mismatched name sizes");
+ memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));
+ Dest.Value = Src.Value;
+ Dest.SectionNumber = Src.SectionNumber;
+ Dest.Type = Src.Type;
+ Dest.StorageClass = Src.StorageClass;
+ Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;
+}
+
+// Copy between pe32_header and pe32plus_header.
+// We store the intermediate state in a pe32plus_header.
+template <class PeHeader1Ty, class PeHeader2Ty>
+void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {
+ Dest.Magic = Src.Magic;
+ Dest.MajorLinkerVersion = Src.MajorLinkerVersion;
+ Dest.MinorLinkerVersion = Src.MinorLinkerVersion;
+ Dest.SizeOfCode = Src.SizeOfCode;
+ Dest.SizeOfInitializedData = Src.SizeOfInitializedData;
+ Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;
+ Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;
+ Dest.BaseOfCode = Src.BaseOfCode;
+ Dest.ImageBase = Src.ImageBase;
+ Dest.SectionAlignment = Src.SectionAlignment;
+ Dest.FileAlignment = Src.FileAlignment;
+ Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;
+ Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;
+ Dest.MajorImageVersion = Src.MajorImageVersion;
+ Dest.MinorImageVersion = Src.MinorImageVersion;
+ Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;
+ Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;
+ Dest.Win32VersionValue = Src.Win32VersionValue;
+ Dest.SizeOfImage = Src.SizeOfImage;
+ Dest.SizeOfHeaders = Src.SizeOfHeaders;
+ Dest.CheckSum = Src.CheckSum;
+ Dest.Subsystem = Src.Subsystem;
+ Dest.DLLCharacteristics = Src.DLLCharacteristics;
+ Dest.SizeOfStackReserve = Src.SizeOfStackReserve;
+ Dest.SizeOfStackCommit = Src.SizeOfStackCommit;
+ Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;
+ Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;
+ Dest.LoaderFlags = Src.LoaderFlags;
+ Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;
+}
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_OBJCOPY_COFF_OBJECT_H
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.cpp
index d1beacb3bd..aafdc0f728 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.cpp
@@ -1,226 +1,226 @@
-//===- Reader.cpp ---------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "Reader.h"
-#include "Object.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstddef>
-#include <cstdint>
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-using namespace object;
-using namespace COFF;
-
-Error COFFReader::readExecutableHeaders(Object &Obj) const {
- const dos_header *DH = COFFObj.getDOSHeader();
- Obj.Is64 = COFFObj.is64();
- if (!DH)
- return Error::success();
-
- Obj.IsPE = true;
- Obj.DosHeader = *DH;
- if (DH->AddressOfNewExeHeader > sizeof(*DH))
- Obj.DosStub = ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&DH[1]),
- DH->AddressOfNewExeHeader - sizeof(*DH));
-
- if (COFFObj.is64()) {
- Obj.PeHeader = *COFFObj.getPE32PlusHeader();
- } else {
- const pe32_header *PE32 = COFFObj.getPE32Header();
- copyPeHeader(Obj.PeHeader, *PE32);
- // The pe32plus_header (stored in Object) lacks the BaseOfData field.
- Obj.BaseOfData = PE32->BaseOfData;
- }
-
- for (size_t I = 0; I < Obj.PeHeader.NumberOfRvaAndSize; I++) {
- const data_directory *Dir = COFFObj.getDataDirectory(I);
- if (!Dir)
- return errorCodeToError(object_error::parse_failed);
- Obj.DataDirectories.emplace_back(*Dir);
- }
- return Error::success();
-}
-
-Error COFFReader::readSections(Object &Obj) const {
- std::vector<Section> Sections;
- // Section indexing starts from 1.
- for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) {
- Expected<const coff_section *> SecOrErr = COFFObj.getSection(I);
- if (!SecOrErr)
- return SecOrErr.takeError();
- const coff_section *Sec = *SecOrErr;
- 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;
- S.setContentsRef(Contents);
- ArrayRef<coff_relocation> Relocs = COFFObj.getRelocations(Sec);
- for (const coff_relocation &R : Relocs)
- S.Relocs.push_back(R);
- if (Expected<StringRef> NameOrErr = COFFObj.getSectionName(Sec))
- S.Name = *NameOrErr;
- else
- return NameOrErr.takeError();
- }
- Obj.addSections(Sections);
- return Error::success();
-}
-
-Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
- std::vector<Symbol> Symbols;
- Symbols.reserve(COFFObj.getRawNumberOfSymbols());
- ArrayRef<Section> Sections = Obj.getSections();
- for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) {
- Expected<COFFSymbolRef> SymOrErr = COFFObj.getSymbol(I);
- if (!SymOrErr)
- return SymOrErr.takeError();
- COFFSymbolRef SymRef = *SymOrErr;
-
- Symbols.push_back(Symbol());
- Symbol &Sym = Symbols.back();
- // Copy symbols from the original form into an intermediate coff_symbol32.
- if (IsBigObj)
- copySymbol(Sym.Sym,
- *reinterpret_cast<const coff_symbol32 *>(SymRef.getRawPtr()));
- else
- copySymbol(Sym.Sym,
- *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));
- auto NameOrErr = COFFObj.getSymbolName(SymRef);
- if (!NameOrErr)
- return NameOrErr.takeError();
- Sym.Name = *NameOrErr;
-
- ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);
- size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16);
- assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
- // The auxillary symbols are structs of sizeof(coff_symbol16) each.
- // In the big object format (where symbols are coff_symbol32), each
- // auxillary symbol is padded with 2 bytes at the end. Copy each
- // auxillary symbol to the Sym.AuxData vector. For file symbols,
- // the whole range of aux symbols are interpreted as one null padded
- // string instead.
- if (SymRef.isFileRecord())
- Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),
- AuxData.size())
- .rtrim('\0');
- else
- for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)
- Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));
-
- // Find the unique id of the section
- if (SymRef.getSectionNumber() <=
- 0) // Special symbol (undefined/absolute/debug)
- Sym.TargetSectionId = SymRef.getSectionNumber();
- else if (static_cast<uint32_t>(SymRef.getSectionNumber() - 1) <
- Sections.size())
- Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
- else
- return createStringError(object_error::parse_failed,
- "section number out of range");
- // For section definitions, check if it is comdat associative, and if
- // it is, find the target section unique id.
- const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
- const coff_aux_weak_external *WE = SymRef.getWeakExternal();
- if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
- int32_t Index = SD->getNumber(IsBigObj);
- if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
- return createStringError(object_error::parse_failed,
- "unexpected associative section index");
- Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
- } else if (WE) {
- // This is a raw symbol index for now, but store it in the Symbol
- // until we've added them to the Object, which assigns the final
- // unique ids.
- Sym.WeakTargetSymbolId = WE->TagIndex;
- }
- I += 1 + SymRef.getNumberOfAuxSymbols();
- }
- Obj.addSymbols(Symbols);
- return Error::success();
-}
-
-Error COFFReader::setSymbolTargets(Object &Obj) const {
- std::vector<const Symbol *> RawSymbolTable;
- for (const Symbol &Sym : Obj.getSymbols()) {
- RawSymbolTable.push_back(&Sym);
- for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
- RawSymbolTable.push_back(nullptr);
- }
- for (Symbol &Sym : Obj.getMutableSymbols()) {
- // Convert WeakTargetSymbolId from the original raw symbol index to
- // a proper unique id.
- if (Sym.WeakTargetSymbolId) {
- if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())
- return createStringError(object_error::parse_failed,
- "weak external reference out of range");
- const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];
- if (Target == nullptr)
- return createStringError(object_error::parse_failed,
- "invalid SymbolTableIndex");
- Sym.WeakTargetSymbolId = Target->UniqueId;
- }
- }
- for (Section &Sec : Obj.getMutableSections()) {
- for (Relocation &R : Sec.Relocs) {
- if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
- return createStringError(object_error::parse_failed,
- "SymbolTableIndex out of range");
- const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex];
- if (Sym == nullptr)
- return createStringError(object_error::parse_failed,
- "invalid SymbolTableIndex");
- R.Target = Sym->UniqueId;
- R.TargetName = Sym->Name;
- }
- }
- return Error::success();
-}
-
-Expected<std::unique_ptr<Object>> COFFReader::create() const {
- auto Obj = std::make_unique<Object>();
-
- bool IsBigObj = false;
- if (const coff_file_header *CFH = COFFObj.getCOFFHeader()) {
- Obj->CoffFileHeader = *CFH;
- } else {
- const coff_bigobj_file_header *CBFH = COFFObj.getCOFFBigObjHeader();
- if (!CBFH)
- return createStringError(object_error::parse_failed,
- "no COFF file header returned");
- // Only copying the few fields from the bigobj header that we need
- // and won't recreate in the end.
- Obj->CoffFileHeader.Machine = CBFH->Machine;
- Obj->CoffFileHeader.TimeDateStamp = CBFH->TimeDateStamp;
- IsBigObj = true;
- }
-
- if (Error E = readExecutableHeaders(*Obj))
- return std::move(E);
- if (Error E = readSections(*Obj))
- return std::move(E);
- if (Error E = readSymbols(*Obj, IsBigObj))
- return std::move(E);
- if (Error E = setSymbolTargets(*Obj))
- return std::move(E);
-
- return std::move(Obj);
-}
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
+//===- Reader.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Reader.h"
+#include "Object.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+using namespace object;
+using namespace COFF;
+
+Error COFFReader::readExecutableHeaders(Object &Obj) const {
+ const dos_header *DH = COFFObj.getDOSHeader();
+ Obj.Is64 = COFFObj.is64();
+ if (!DH)
+ return Error::success();
+
+ Obj.IsPE = true;
+ Obj.DosHeader = *DH;
+ if (DH->AddressOfNewExeHeader > sizeof(*DH))
+ Obj.DosStub = ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&DH[1]),
+ DH->AddressOfNewExeHeader - sizeof(*DH));
+
+ if (COFFObj.is64()) {
+ Obj.PeHeader = *COFFObj.getPE32PlusHeader();
+ } else {
+ const pe32_header *PE32 = COFFObj.getPE32Header();
+ copyPeHeader(Obj.PeHeader, *PE32);
+ // The pe32plus_header (stored in Object) lacks the BaseOfData field.
+ Obj.BaseOfData = PE32->BaseOfData;
+ }
+
+ for (size_t I = 0; I < Obj.PeHeader.NumberOfRvaAndSize; I++) {
+ const data_directory *Dir = COFFObj.getDataDirectory(I);
+ if (!Dir)
+ return errorCodeToError(object_error::parse_failed);
+ Obj.DataDirectories.emplace_back(*Dir);
+ }
+ return Error::success();
+}
+
+Error COFFReader::readSections(Object &Obj) const {
+ std::vector<Section> Sections;
+ // Section indexing starts from 1.
+ for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) {
+ Expected<const coff_section *> SecOrErr = COFFObj.getSection(I);
+ if (!SecOrErr)
+ return SecOrErr.takeError();
+ const coff_section *Sec = *SecOrErr;
+ 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;
+ S.setContentsRef(Contents);
+ ArrayRef<coff_relocation> Relocs = COFFObj.getRelocations(Sec);
+ for (const coff_relocation &R : Relocs)
+ S.Relocs.push_back(R);
+ if (Expected<StringRef> NameOrErr = COFFObj.getSectionName(Sec))
+ S.Name = *NameOrErr;
+ else
+ return NameOrErr.takeError();
+ }
+ Obj.addSections(Sections);
+ return Error::success();
+}
+
+Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ std::vector<Symbol> Symbols;
+ Symbols.reserve(COFFObj.getRawNumberOfSymbols());
+ ArrayRef<Section> Sections = Obj.getSections();
+ for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) {
+ Expected<COFFSymbolRef> SymOrErr = COFFObj.getSymbol(I);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
+ COFFSymbolRef SymRef = *SymOrErr;
+
+ Symbols.push_back(Symbol());
+ Symbol &Sym = Symbols.back();
+ // Copy symbols from the original form into an intermediate coff_symbol32.
+ if (IsBigObj)
+ copySymbol(Sym.Sym,
+ *reinterpret_cast<const coff_symbol32 *>(SymRef.getRawPtr()));
+ else
+ copySymbol(Sym.Sym,
+ *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));
+ auto NameOrErr = COFFObj.getSymbolName(SymRef);
+ if (!NameOrErr)
+ return NameOrErr.takeError();
+ Sym.Name = *NameOrErr;
+
+ ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);
+ size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16);
+ assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
+ // The auxillary symbols are structs of sizeof(coff_symbol16) each.
+ // In the big object format (where symbols are coff_symbol32), each
+ // auxillary symbol is padded with 2 bytes at the end. Copy each
+ // auxillary symbol to the Sym.AuxData vector. For file symbols,
+ // the whole range of aux symbols are interpreted as one null padded
+ // string instead.
+ if (SymRef.isFileRecord())
+ Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),
+ AuxData.size())
+ .rtrim('\0');
+ else
+ for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)
+ Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));
+
+ // Find the unique id of the section
+ if (SymRef.getSectionNumber() <=
+ 0) // Special symbol (undefined/absolute/debug)
+ Sym.TargetSectionId = SymRef.getSectionNumber();
+ else if (static_cast<uint32_t>(SymRef.getSectionNumber() - 1) <
+ Sections.size())
+ Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
+ else
+ return createStringError(object_error::parse_failed,
+ "section number out of range");
+ // For section definitions, check if it is comdat associative, and if
+ // it is, find the target section unique id.
+ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
+ const coff_aux_weak_external *WE = SymRef.getWeakExternal();
+ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ int32_t Index = SD->getNumber(IsBigObj);
+ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
+ return createStringError(object_error::parse_failed,
+ "unexpected associative section index");
+ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
+ } else if (WE) {
+ // This is a raw symbol index for now, but store it in the Symbol
+ // until we've added them to the Object, which assigns the final
+ // unique ids.
+ Sym.WeakTargetSymbolId = WE->TagIndex;
+ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+ }
+ Obj.addSymbols(Symbols);
+ return Error::success();
+}
+
+Error COFFReader::setSymbolTargets(Object &Obj) const {
+ std::vector<const Symbol *> RawSymbolTable;
+ for (const Symbol &Sym : Obj.getSymbols()) {
+ RawSymbolTable.push_back(&Sym);
+ for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
+ RawSymbolTable.push_back(nullptr);
+ }
+ for (Symbol &Sym : Obj.getMutableSymbols()) {
+ // Convert WeakTargetSymbolId from the original raw symbol index to
+ // a proper unique id.
+ if (Sym.WeakTargetSymbolId) {
+ if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())
+ return createStringError(object_error::parse_failed,
+ "weak external reference out of range");
+ const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];
+ if (Target == nullptr)
+ return createStringError(object_error::parse_failed,
+ "invalid SymbolTableIndex");
+ Sym.WeakTargetSymbolId = Target->UniqueId;
+ }
+ }
+ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+ return createStringError(object_error::parse_failed,
+ "SymbolTableIndex out of range");
+ const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex];
+ if (Sym == nullptr)
+ return createStringError(object_error::parse_failed,
+ "invalid SymbolTableIndex");
+ R.Target = Sym->UniqueId;
+ R.TargetName = Sym->Name;
+ }
+ }
+ return Error::success();
+}
+
+Expected<std::unique_ptr<Object>> COFFReader::create() const {
+ auto Obj = std::make_unique<Object>();
+
+ bool IsBigObj = false;
+ if (const coff_file_header *CFH = COFFObj.getCOFFHeader()) {
+ Obj->CoffFileHeader = *CFH;
+ } else {
+ const coff_bigobj_file_header *CBFH = COFFObj.getCOFFBigObjHeader();
+ if (!CBFH)
+ return createStringError(object_error::parse_failed,
+ "no COFF file header returned");
+ // Only copying the few fields from the bigobj header that we need
+ // and won't recreate in the end.
+ Obj->CoffFileHeader.Machine = CBFH->Machine;
+ Obj->CoffFileHeader.TimeDateStamp = CBFH->TimeDateStamp;
+ IsBigObj = true;
+ }
+
+ if (Error E = readExecutableHeaders(*Obj))
+ return std::move(E);
+ if (Error E = readSections(*Obj))
+ return std::move(E);
+ if (Error E = readSymbols(*Obj, IsBigObj))
+ return std::move(E);
+ if (Error E = setSymbolTargets(*Obj))
+ return std::move(E);
+
+ return std::move(Obj);
+}
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.h b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.h
index ec15369db0..573b768c06 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Reader.h
@@ -1,42 +1,42 @@
-//===- Reader.h -------------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_OBJCOPY_COFF_READER_H
-#define LLVM_TOOLS_OBJCOPY_COFF_READER_H
-
-#include "Buffer.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-struct Object;
-
-using object::COFFObjectFile;
-
-class COFFReader {
- const COFFObjectFile &COFFObj;
-
- Error readExecutableHeaders(Object &Obj) const;
- Error readSections(Object &Obj) const;
- Error readSymbols(Object &Obj, bool IsBigObj) const;
- Error setSymbolTargets(Object &Obj) const;
-
-public:
- explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {}
- Expected<std::unique_ptr<Object>> create() const;
-};
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
-
-#endif // LLVM_TOOLS_OBJCOPY_COFF_READER_H
+//===- Reader.h -------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_OBJCOPY_COFF_READER_H
+#define LLVM_TOOLS_OBJCOPY_COFF_READER_H
+
+#include "Buffer.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+struct Object;
+
+using object::COFFObjectFile;
+
+class COFFReader {
+ const COFFObjectFile &COFFObj;
+
+ Error readExecutableHeaders(Object &Obj) const;
+ Error readSections(Object &Obj) const;
+ Error readSymbols(Object &Obj, bool IsBigObj) const;
+ Error setSymbolTargets(Object &Obj) const;
+
+public:
+ explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {}
+ Expected<std::unique_ptr<Object>> create() const;
+};
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_OBJCOPY_COFF_READER_H
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.cpp b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.cpp
index 6b560890a4..3fff721dcb 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.cpp
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.cpp
@@ -1,449 +1,449 @@
-//===- Writer.cpp ---------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "Writer.h"
-#include "Object.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstddef>
-#include <cstdint>
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-using namespace object;
-using namespace COFF;
-
-Error COFFWriter::finalizeRelocTargets() {
- for (Section &Sec : Obj.getMutableSections()) {
- for (Relocation &R : Sec.Relocs) {
- const Symbol *Sym = Obj.findSymbol(R.Target);
- if (Sym == nullptr)
- return createStringError(object_error::invalid_symbol_index,
- "relocation target '%s' (%zu) not found",
- R.TargetName.str().c_str(), R.Target);
- R.Reloc.SymbolTableIndex = Sym->RawIndex;
- }
- }
- return Error::success();
-}
-
-Error COFFWriter::finalizeSymbolContents() {
- for (Symbol &Sym : Obj.getMutableSymbols()) {
- if (Sym.TargetSectionId <= 0) {
- // Undefined, or a special kind of symbol. These negative values
- // are stored in the SectionNumber field which is unsigned.
- Sym.Sym.SectionNumber = static_cast<uint32_t>(Sym.TargetSectionId);
- } else {
- const Section *Sec = Obj.findSection(Sym.TargetSectionId);
- if (Sec == nullptr)
- return createStringError(object_error::invalid_symbol_index,
- "symbol '%s' points to a removed section",
- Sym.Name.str().c_str());
- Sym.Sym.SectionNumber = Sec->Index;
-
- if (Sym.Sym.NumberOfAuxSymbols == 1 &&
- Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
- coff_aux_section_definition *SD =
- reinterpret_cast<coff_aux_section_definition *>(
- Sym.AuxData[0].Opaque);
- uint32_t SDSectionNumber;
- if (Sym.AssociativeComdatTargetSectionId == 0) {
- // Not a comdat associative section; just set the Number field to
- // the number of the section itself.
- SDSectionNumber = Sec->Index;
- } else {
- Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId);
- if (Sec == nullptr)
- return createStringError(
- object_error::invalid_symbol_index,
- "symbol '%s' is associative to a removed section",
- Sym.Name.str().c_str());
- SDSectionNumber = Sec->Index;
- }
- // Update the section definition with the new section number.
- SD->NumberLowPart = static_cast<uint16_t>(SDSectionNumber);
- SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
- }
- }
- // Check that we actually have got AuxData to match the weak symbol target
- // we want to set. Only >= 1 would be required, but only == 1 makes sense.
- if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
- coff_aux_weak_external *WE =
- reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque);
- const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
- if (Target == nullptr)
- return createStringError(object_error::invalid_symbol_index,
- "symbol '%s' is missing its weak target",
- Sym.Name.str().c_str());
- WE->TagIndex = Target->RawIndex;
- }
- }
- return Error::success();
-}
-
-void COFFWriter::layoutSections() {
- for (auto &S : Obj.getMutableSections()) {
- if (S.Header.SizeOfRawData > 0)
- S.Header.PointerToRawData = FileSize;
- FileSize += S.Header.SizeOfRawData; // For executables, this is already
- // aligned to FileAlignment.
- 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);
-
- if (S.Header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
- SizeOfInitializedData += S.Header.SizeOfRawData;
- }
-}
-
-size_t COFFWriter::finalizeStringTable() {
- for (const auto &S : Obj.getSections())
- if (S.Name.size() > COFF::NameSize)
- StrTabBuilder.add(S.Name);
-
- for (const auto &S : Obj.getSymbols())
- if (S.Name.size() > COFF::NameSize)
- StrTabBuilder.add(S.Name);
-
- StrTabBuilder.finalize();
-
- for (auto &S : Obj.getMutableSections()) {
- memset(S.Header.Name, 0, sizeof(S.Header.Name));
- if (S.Name.size() > COFF::NameSize) {
- snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d",
- (int)StrTabBuilder.getOffset(S.Name));
- } else {
- memcpy(S.Header.Name, S.Name.data(), S.Name.size());
- }
- }
- for (auto &S : Obj.getMutableSymbols()) {
- if (S.Name.size() > COFF::NameSize) {
- S.Sym.Name.Offset.Zeroes = 0;
- S.Sym.Name.Offset.Offset = StrTabBuilder.getOffset(S.Name);
- } else {
- strncpy(S.Sym.Name.ShortName, S.Name.data(), COFF::NameSize);
- }
- }
- return StrTabBuilder.getSize();
-}
-
-template <class SymbolTy>
-std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
- size_t RawSymIndex = 0;
- for (auto &S : Obj.getMutableSymbols()) {
- // Symbols normally have NumberOfAuxSymbols set correctly all the time.
- // For file symbols, we need to know the output file's symbol size to be
- // able to calculate the number of slots it occupies.
- if (!S.AuxFile.empty())
- S.Sym.NumberOfAuxSymbols =
- alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy);
- S.RawIndex = RawSymIndex;
- RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols;
- }
- return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy));
-}
-
-Error COFFWriter::finalize(bool IsBigObj) {
- size_t SymTabSize, SymbolSize;
- std::tie(SymTabSize, SymbolSize) = IsBigObj
- ? finalizeSymbolTable<coff_symbol32>()
- : finalizeSymbolTable<coff_symbol16>();
-
- if (Error E = finalizeRelocTargets())
- return E;
- if (Error E = finalizeSymbolContents())
- return E;
-
- size_t SizeOfHeaders = 0;
- FileAlignment = 1;
- size_t PeHeaderSize = 0;
- if (Obj.IsPE) {
- Obj.DosHeader.AddressOfNewExeHeader =
- sizeof(Obj.DosHeader) + Obj.DosStub.size();
- SizeOfHeaders += Obj.DosHeader.AddressOfNewExeHeader + sizeof(PEMagic);
-
- FileAlignment = Obj.PeHeader.FileAlignment;
- Obj.PeHeader.NumberOfRvaAndSize = Obj.DataDirectories.size();
-
- PeHeaderSize = Obj.Is64 ? sizeof(pe32plus_header) : sizeof(pe32_header);
- SizeOfHeaders +=
- PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size();
- }
- Obj.CoffFileHeader.NumberOfSections = Obj.getSections().size();
- SizeOfHeaders +=
- IsBigObj ? sizeof(coff_bigobj_file_header) : sizeof(coff_file_header);
- SizeOfHeaders += sizeof(coff_section) * Obj.getSections().size();
- SizeOfHeaders = alignTo(SizeOfHeaders, FileAlignment);
-
- Obj.CoffFileHeader.SizeOfOptionalHeader =
- PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size();
-
- FileSize = SizeOfHeaders;
- SizeOfInitializedData = 0;
-
- layoutSections();
-
- if (Obj.IsPE) {
- Obj.PeHeader.SizeOfHeaders = SizeOfHeaders;
- Obj.PeHeader.SizeOfInitializedData = SizeOfInitializedData;
-
- if (!Obj.getSections().empty()) {
- const Section &S = Obj.getSections().back();
- Obj.PeHeader.SizeOfImage =
- alignTo(S.Header.VirtualAddress + S.Header.VirtualSize,
- Obj.PeHeader.SectionAlignment);
- }
-
- // If the PE header had a checksum, clear it, since it isn't valid
- // any longer. (We don't calculate a new one.)
- Obj.PeHeader.CheckSum = 0;
- }
-
- size_t StrTabSize = finalizeStringTable();
-
- size_t PointerToSymbolTable = FileSize;
- // StrTabSize <= 4 is the size of an empty string table, only consisting
- // of the length field.
- if (SymTabSize == 0 && StrTabSize <= 4 && Obj.IsPE) {
- // For executables, don't point to the symbol table and skip writing
- // the length field, if both the symbol and string tables are empty.
- PointerToSymbolTable = 0;
- StrTabSize = 0;
- }
-
- size_t NumRawSymbols = SymTabSize / SymbolSize;
- Obj.CoffFileHeader.PointerToSymbolTable = PointerToSymbolTable;
- Obj.CoffFileHeader.NumberOfSymbols = NumRawSymbols;
- FileSize += SymTabSize + StrTabSize;
- FileSize = alignTo(FileSize, FileAlignment);
-
- return Error::success();
-}
-
-void COFFWriter::writeHeaders(bool IsBigObj) {
- uint8_t *Ptr = Buf.getBufferStart();
- if (Obj.IsPE) {
- memcpy(Ptr, &Obj.DosHeader, sizeof(Obj.DosHeader));
- Ptr += sizeof(Obj.DosHeader);
- memcpy(Ptr, Obj.DosStub.data(), Obj.DosStub.size());
- Ptr += Obj.DosStub.size();
- memcpy(Ptr, PEMagic, sizeof(PEMagic));
- Ptr += sizeof(PEMagic);
- }
- if (!IsBigObj) {
- memcpy(Ptr, &Obj.CoffFileHeader, sizeof(Obj.CoffFileHeader));
- Ptr += sizeof(Obj.CoffFileHeader);
- } else {
- // Generate a coff_bigobj_file_header, filling it in with the values
- // from Obj.CoffFileHeader. All extra fields that don't exist in
- // coff_file_header can be set to hardcoded values.
- coff_bigobj_file_header BigObjHeader;
- BigObjHeader.Sig1 = IMAGE_FILE_MACHINE_UNKNOWN;
- BigObjHeader.Sig2 = 0xffff;
- BigObjHeader.Version = BigObjHeader::MinBigObjectVersion;
- BigObjHeader.Machine = Obj.CoffFileHeader.Machine;
- BigObjHeader.TimeDateStamp = Obj.CoffFileHeader.TimeDateStamp;
- memcpy(BigObjHeader.UUID, BigObjMagic, sizeof(BigObjMagic));
- BigObjHeader.unused1 = 0;
- BigObjHeader.unused2 = 0;
- BigObjHeader.unused3 = 0;
- BigObjHeader.unused4 = 0;
- // The value in Obj.CoffFileHeader.NumberOfSections is truncated, thus
- // get the original one instead.
- BigObjHeader.NumberOfSections = Obj.getSections().size();
- BigObjHeader.PointerToSymbolTable = Obj.CoffFileHeader.PointerToSymbolTable;
- BigObjHeader.NumberOfSymbols = Obj.CoffFileHeader.NumberOfSymbols;
-
- memcpy(Ptr, &BigObjHeader, sizeof(BigObjHeader));
- Ptr += sizeof(BigObjHeader);
- }
- if (Obj.IsPE) {
- if (Obj.Is64) {
- memcpy(Ptr, &Obj.PeHeader, sizeof(Obj.PeHeader));
- Ptr += sizeof(Obj.PeHeader);
- } else {
- pe32_header PeHeader;
- copyPeHeader(PeHeader, Obj.PeHeader);
- // The pe32plus_header (stored in Object) lacks the BaseOfData field.
- PeHeader.BaseOfData = Obj.BaseOfData;
-
- memcpy(Ptr, &PeHeader, sizeof(PeHeader));
- Ptr += sizeof(PeHeader);
- }
- for (const auto &DD : Obj.DataDirectories) {
- memcpy(Ptr, &DD, sizeof(DD));
- Ptr += sizeof(DD);
- }
- }
- for (const auto &S : Obj.getSections()) {
- memcpy(Ptr, &S.Header, sizeof(S.Header));
- Ptr += sizeof(S.Header);
- }
-}
-
-void COFFWriter::writeSections() {
- for (const auto &S : Obj.getSections()) {
- uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData;
- ArrayRef<uint8_t> Contents = S.getContents();
- std::copy(Contents.begin(), Contents.end(), Ptr);
-
- // For executable sections, pad the remainder of the raw data size with
- // 0xcc, which is int3 on x86.
- if ((S.Header.Characteristics & IMAGE_SCN_CNT_CODE) &&
- S.Header.SizeOfRawData > Contents.size())
- memset(Ptr + Contents.size(), 0xcc,
- 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);
- }
- }
-}
-
-template <class SymbolTy> void COFFWriter::writeSymbolStringTables() {
- uint8_t *Ptr = Buf.getBufferStart() + Obj.CoffFileHeader.PointerToSymbolTable;
- for (const auto &S : Obj.getSymbols()) {
- // Convert symbols back to the right size, from coff_symbol32.
- copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
- S.Sym);
- Ptr += sizeof(SymbolTy);
- if (!S.AuxFile.empty()) {
- // For file symbols, just write the string into the aux symbol slots,
- // assuming that the unwritten parts are initialized to zero in the memory
- // mapped file.
- std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr);
- Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy);
- } else {
- // For other auxillary symbols, write their opaque payload into one symbol
- // table slot each. For big object files, the symbols are larger than the
- // opaque auxillary symbol struct and we leave padding at the end of each
- // entry.
- for (const AuxSymbol &AuxSym : S.AuxData) {
- ArrayRef<uint8_t> Ref = AuxSym.getRef();
- std::copy(Ref.begin(), Ref.end(), Ptr);
- Ptr += sizeof(SymbolTy);
- }
- }
- }
- if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
- // Always write a string table in object files, even an empty one.
- StrTabBuilder.write(Ptr);
- Ptr += StrTabBuilder.getSize();
- }
-}
-
-Error COFFWriter::write(bool IsBigObj) {
- if (Error E = finalize(IsBigObj))
- return E;
-
- if (Error E = Buf.allocate(FileSize))
- return E;
-
- writeHeaders(IsBigObj);
- writeSections();
- if (IsBigObj)
- writeSymbolStringTables<coff_symbol32>();
- else
- writeSymbolStringTables<coff_symbol16>();
-
- if (Obj.IsPE)
- if (Error E = patchDebugDirectory())
- return E;
-
- return Buf.commit();
-}
-
-Expected<uint32_t> COFFWriter::virtualAddressToFileAddress(uint32_t RVA) {
- for (const auto &S : Obj.getSections()) {
- if (RVA >= S.Header.VirtualAddress &&
- RVA < S.Header.VirtualAddress + S.Header.SizeOfRawData)
- return S.Header.PointerToRawData + RVA - S.Header.VirtualAddress;
- }
- return createStringError(object_error::parse_failed,
- "debug directory payload not found");
-}
-
-// Locate which sections contain the debug directories, iterate over all
-// the debug_directory structs in there, and set the PointerToRawData field
-// in all of them, according to their new physical location in the file.
-Error COFFWriter::patchDebugDirectory() {
- if (Obj.DataDirectories.size() < DEBUG_DIRECTORY)
- return Error::success();
- const data_directory *Dir = &Obj.DataDirectories[DEBUG_DIRECTORY];
- if (Dir->Size <= 0)
- return Error::success();
- for (const auto &S : Obj.getSections()) {
- if (Dir->RelativeVirtualAddress >= S.Header.VirtualAddress &&
- Dir->RelativeVirtualAddress <
- S.Header.VirtualAddress + S.Header.SizeOfRawData) {
- if (Dir->RelativeVirtualAddress + Dir->Size >
- S.Header.VirtualAddress + S.Header.SizeOfRawData)
- return createStringError(object_error::parse_failed,
- "debug directory extends past end of section");
-
- size_t Offset = Dir->RelativeVirtualAddress - S.Header.VirtualAddress;
- uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData + Offset;
- uint8_t *End = Ptr + Dir->Size;
- while (Ptr < End) {
- debug_directory *Debug = reinterpret_cast<debug_directory *>(Ptr);
- if (!Debug->AddressOfRawData)
- return createStringError(object_error::parse_failed,
- "debug directory payload outside of "
- "mapped sections not supported");
- if (Expected<uint32_t> FilePosOrErr =
- virtualAddressToFileAddress(Debug->AddressOfRawData))
- Debug->PointerToRawData = *FilePosOrErr;
- else
- return FilePosOrErr.takeError();
- Ptr += sizeof(debug_directory);
- Offset += sizeof(debug_directory);
- }
- // Debug directory found and patched, all done.
- return Error::success();
- }
- }
- return createStringError(object_error::parse_failed,
- "debug directory not found");
-}
-
-Error COFFWriter::write() {
- bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16;
- if (IsBigObj && Obj.IsPE)
- return createStringError(object_error::parse_failed,
- "too many sections for executable");
- return write(IsBigObj);
-}
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
+//===- Writer.cpp ---------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Writer.h"
+#include "Object.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+using namespace object;
+using namespace COFF;
+
+Error COFFWriter::finalizeRelocTargets() {
+ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ const Symbol *Sym = Obj.findSymbol(R.Target);
+ if (Sym == nullptr)
+ return createStringError(object_error::invalid_symbol_index,
+ "relocation target '%s' (%zu) not found",
+ R.TargetName.str().c_str(), R.Target);
+ R.Reloc.SymbolTableIndex = Sym->RawIndex;
+ }
+ }
+ return Error::success();
+}
+
+Error COFFWriter::finalizeSymbolContents() {
+ for (Symbol &Sym : Obj.getMutableSymbols()) {
+ if (Sym.TargetSectionId <= 0) {
+ // Undefined, or a special kind of symbol. These negative values
+ // are stored in the SectionNumber field which is unsigned.
+ Sym.Sym.SectionNumber = static_cast<uint32_t>(Sym.TargetSectionId);
+ } else {
+ const Section *Sec = Obj.findSection(Sym.TargetSectionId);
+ if (Sec == nullptr)
+ return createStringError(object_error::invalid_symbol_index,
+ "symbol '%s' points to a removed section",
+ Sym.Name.str().c_str());
+ Sym.Sym.SectionNumber = Sec->Index;
+
+ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
+ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
+ coff_aux_section_definition *SD =
+ reinterpret_cast<coff_aux_section_definition *>(
+ Sym.AuxData[0].Opaque);
+ uint32_t SDSectionNumber;
+ if (Sym.AssociativeComdatTargetSectionId == 0) {
+ // Not a comdat associative section; just set the Number field to
+ // the number of the section itself.
+ SDSectionNumber = Sec->Index;
+ } else {
+ Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId);
+ if (Sec == nullptr)
+ return createStringError(
+ object_error::invalid_symbol_index,
+ "symbol '%s' is associative to a removed section",
+ Sym.Name.str().c_str());
+ SDSectionNumber = Sec->Index;
+ }
+ // Update the section definition with the new section number.
+ SD->NumberLowPart = static_cast<uint16_t>(SDSectionNumber);
+ SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
+ }
+ }
+ // Check that we actually have got AuxData to match the weak symbol target
+ // we want to set. Only >= 1 would be required, but only == 1 makes sense.
+ if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
+ coff_aux_weak_external *WE =
+ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque);
+ const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
+ if (Target == nullptr)
+ return createStringError(object_error::invalid_symbol_index,
+ "symbol '%s' is missing its weak target",
+ Sym.Name.str().c_str());
+ WE->TagIndex = Target->RawIndex;
+ }
+ }
+ return Error::success();
+}
+
+void COFFWriter::layoutSections() {
+ for (auto &S : Obj.getMutableSections()) {
+ if (S.Header.SizeOfRawData > 0)
+ S.Header.PointerToRawData = FileSize;
+ FileSize += S.Header.SizeOfRawData; // For executables, this is already
+ // aligned to FileAlignment.
+ 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);
+
+ if (S.Header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
+ SizeOfInitializedData += S.Header.SizeOfRawData;
+ }
+}
+
+size_t COFFWriter::finalizeStringTable() {
+ for (const auto &S : Obj.getSections())
+ if (S.Name.size() > COFF::NameSize)
+ StrTabBuilder.add(S.Name);
+
+ for (const auto &S : Obj.getSymbols())
+ if (S.Name.size() > COFF::NameSize)
+ StrTabBuilder.add(S.Name);
+
+ StrTabBuilder.finalize();
+
+ for (auto &S : Obj.getMutableSections()) {
+ memset(S.Header.Name, 0, sizeof(S.Header.Name));
+ if (S.Name.size() > COFF::NameSize) {
+ snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d",
+ (int)StrTabBuilder.getOffset(S.Name));
+ } else {
+ memcpy(S.Header.Name, S.Name.data(), S.Name.size());
+ }
+ }
+ for (auto &S : Obj.getMutableSymbols()) {
+ if (S.Name.size() > COFF::NameSize) {
+ S.Sym.Name.Offset.Zeroes = 0;
+ S.Sym.Name.Offset.Offset = StrTabBuilder.getOffset(S.Name);
+ } else {
+ strncpy(S.Sym.Name.ShortName, S.Name.data(), COFF::NameSize);
+ }
+ }
+ return StrTabBuilder.getSize();
+}
+
+template <class SymbolTy>
+std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+ size_t RawSymIndex = 0;
+ for (auto &S : Obj.getMutableSymbols()) {
+ // Symbols normally have NumberOfAuxSymbols set correctly all the time.
+ // For file symbols, we need to know the output file's symbol size to be
+ // able to calculate the number of slots it occupies.
+ if (!S.AuxFile.empty())
+ S.Sym.NumberOfAuxSymbols =
+ alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy);
+ S.RawIndex = RawSymIndex;
+ RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols;
+ }
+ return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy));
+}
+
+Error COFFWriter::finalize(bool IsBigObj) {
+ size_t SymTabSize, SymbolSize;
+ std::tie(SymTabSize, SymbolSize) = IsBigObj
+ ? finalizeSymbolTable<coff_symbol32>()
+ : finalizeSymbolTable<coff_symbol16>();
+
+ if (Error E = finalizeRelocTargets())
+ return E;
+ if (Error E = finalizeSymbolContents())
+ return E;
+
+ size_t SizeOfHeaders = 0;
+ FileAlignment = 1;
+ size_t PeHeaderSize = 0;
+ if (Obj.IsPE) {
+ Obj.DosHeader.AddressOfNewExeHeader =
+ sizeof(Obj.DosHeader) + Obj.DosStub.size();
+ SizeOfHeaders += Obj.DosHeader.AddressOfNewExeHeader + sizeof(PEMagic);
+
+ FileAlignment = Obj.PeHeader.FileAlignment;
+ Obj.PeHeader.NumberOfRvaAndSize = Obj.DataDirectories.size();
+
+ PeHeaderSize = Obj.Is64 ? sizeof(pe32plus_header) : sizeof(pe32_header);
+ SizeOfHeaders +=
+ PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size();
+ }
+ Obj.CoffFileHeader.NumberOfSections = Obj.getSections().size();
+ SizeOfHeaders +=
+ IsBigObj ? sizeof(coff_bigobj_file_header) : sizeof(coff_file_header);
+ SizeOfHeaders += sizeof(coff_section) * Obj.getSections().size();
+ SizeOfHeaders = alignTo(SizeOfHeaders, FileAlignment);
+
+ Obj.CoffFileHeader.SizeOfOptionalHeader =
+ PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size();
+
+ FileSize = SizeOfHeaders;
+ SizeOfInitializedData = 0;
+
+ layoutSections();
+
+ if (Obj.IsPE) {
+ Obj.PeHeader.SizeOfHeaders = SizeOfHeaders;
+ Obj.PeHeader.SizeOfInitializedData = SizeOfInitializedData;
+
+ if (!Obj.getSections().empty()) {
+ const Section &S = Obj.getSections().back();
+ Obj.PeHeader.SizeOfImage =
+ alignTo(S.Header.VirtualAddress + S.Header.VirtualSize,
+ Obj.PeHeader.SectionAlignment);
+ }
+
+ // If the PE header had a checksum, clear it, since it isn't valid
+ // any longer. (We don't calculate a new one.)
+ Obj.PeHeader.CheckSum = 0;
+ }
+
+ size_t StrTabSize = finalizeStringTable();
+
+ size_t PointerToSymbolTable = FileSize;
+ // StrTabSize <= 4 is the size of an empty string table, only consisting
+ // of the length field.
+ if (SymTabSize == 0 && StrTabSize <= 4 && Obj.IsPE) {
+ // For executables, don't point to the symbol table and skip writing
+ // the length field, if both the symbol and string tables are empty.
+ PointerToSymbolTable = 0;
+ StrTabSize = 0;
+ }
+
+ size_t NumRawSymbols = SymTabSize / SymbolSize;
+ Obj.CoffFileHeader.PointerToSymbolTable = PointerToSymbolTable;
+ Obj.CoffFileHeader.NumberOfSymbols = NumRawSymbols;
+ FileSize += SymTabSize + StrTabSize;
+ FileSize = alignTo(FileSize, FileAlignment);
+
+ return Error::success();
+}
+
+void COFFWriter::writeHeaders(bool IsBigObj) {
+ uint8_t *Ptr = Buf.getBufferStart();
+ if (Obj.IsPE) {
+ memcpy(Ptr, &Obj.DosHeader, sizeof(Obj.DosHeader));
+ Ptr += sizeof(Obj.DosHeader);
+ memcpy(Ptr, Obj.DosStub.data(), Obj.DosStub.size());
+ Ptr += Obj.DosStub.size();
+ memcpy(Ptr, PEMagic, sizeof(PEMagic));
+ Ptr += sizeof(PEMagic);
+ }
+ if (!IsBigObj) {
+ memcpy(Ptr, &Obj.CoffFileHeader, sizeof(Obj.CoffFileHeader));
+ Ptr += sizeof(Obj.CoffFileHeader);
+ } else {
+ // Generate a coff_bigobj_file_header, filling it in with the values
+ // from Obj.CoffFileHeader. All extra fields that don't exist in
+ // coff_file_header can be set to hardcoded values.
+ coff_bigobj_file_header BigObjHeader;
+ BigObjHeader.Sig1 = IMAGE_FILE_MACHINE_UNKNOWN;
+ BigObjHeader.Sig2 = 0xffff;
+ BigObjHeader.Version = BigObjHeader::MinBigObjectVersion;
+ BigObjHeader.Machine = Obj.CoffFileHeader.Machine;
+ BigObjHeader.TimeDateStamp = Obj.CoffFileHeader.TimeDateStamp;
+ memcpy(BigObjHeader.UUID, BigObjMagic, sizeof(BigObjMagic));
+ BigObjHeader.unused1 = 0;
+ BigObjHeader.unused2 = 0;
+ BigObjHeader.unused3 = 0;
+ BigObjHeader.unused4 = 0;
+ // The value in Obj.CoffFileHeader.NumberOfSections is truncated, thus
+ // get the original one instead.
+ BigObjHeader.NumberOfSections = Obj.getSections().size();
+ BigObjHeader.PointerToSymbolTable = Obj.CoffFileHeader.PointerToSymbolTable;
+ BigObjHeader.NumberOfSymbols = Obj.CoffFileHeader.NumberOfSymbols;
+
+ memcpy(Ptr, &BigObjHeader, sizeof(BigObjHeader));
+ Ptr += sizeof(BigObjHeader);
+ }
+ if (Obj.IsPE) {
+ if (Obj.Is64) {
+ memcpy(Ptr, &Obj.PeHeader, sizeof(Obj.PeHeader));
+ Ptr += sizeof(Obj.PeHeader);
+ } else {
+ pe32_header PeHeader;
+ copyPeHeader(PeHeader, Obj.PeHeader);
+ // The pe32plus_header (stored in Object) lacks the BaseOfData field.
+ PeHeader.BaseOfData = Obj.BaseOfData;
+
+ memcpy(Ptr, &PeHeader, sizeof(PeHeader));
+ Ptr += sizeof(PeHeader);
+ }
+ for (const auto &DD : Obj.DataDirectories) {
+ memcpy(Ptr, &DD, sizeof(DD));
+ Ptr += sizeof(DD);
+ }
+ }
+ for (const auto &S : Obj.getSections()) {
+ memcpy(Ptr, &S.Header, sizeof(S.Header));
+ Ptr += sizeof(S.Header);
+ }
+}
+
+void COFFWriter::writeSections() {
+ for (const auto &S : Obj.getSections()) {
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData;
+ ArrayRef<uint8_t> Contents = S.getContents();
+ std::copy(Contents.begin(), Contents.end(), Ptr);
+
+ // For executable sections, pad the remainder of the raw data size with
+ // 0xcc, which is int3 on x86.
+ if ((S.Header.Characteristics & IMAGE_SCN_CNT_CODE) &&
+ S.Header.SizeOfRawData > Contents.size())
+ memset(Ptr + Contents.size(), 0xcc,
+ 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);
+ }
+ }
+}
+
+template <class SymbolTy> void COFFWriter::writeSymbolStringTables() {
+ uint8_t *Ptr = Buf.getBufferStart() + Obj.CoffFileHeader.PointerToSymbolTable;
+ for (const auto &S : Obj.getSymbols()) {
+ // Convert symbols back to the right size, from coff_symbol32.
+ copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
+ S.Sym);
+ Ptr += sizeof(SymbolTy);
+ if (!S.AuxFile.empty()) {
+ // For file symbols, just write the string into the aux symbol slots,
+ // assuming that the unwritten parts are initialized to zero in the memory
+ // mapped file.
+ std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr);
+ Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy);
+ } else {
+ // For other auxillary symbols, write their opaque payload into one symbol
+ // table slot each. For big object files, the symbols are larger than the
+ // opaque auxillary symbol struct and we leave padding at the end of each
+ // entry.
+ for (const AuxSymbol &AuxSym : S.AuxData) {
+ ArrayRef<uint8_t> Ref = AuxSym.getRef();
+ std::copy(Ref.begin(), Ref.end(), Ptr);
+ Ptr += sizeof(SymbolTy);
+ }
+ }
+ }
+ if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
+ // Always write a string table in object files, even an empty one.
+ StrTabBuilder.write(Ptr);
+ Ptr += StrTabBuilder.getSize();
+ }
+}
+
+Error COFFWriter::write(bool IsBigObj) {
+ if (Error E = finalize(IsBigObj))
+ return E;
+
+ if (Error E = Buf.allocate(FileSize))
+ return E;
+
+ writeHeaders(IsBigObj);
+ writeSections();
+ if (IsBigObj)
+ writeSymbolStringTables<coff_symbol32>();
+ else
+ writeSymbolStringTables<coff_symbol16>();
+
+ if (Obj.IsPE)
+ if (Error E = patchDebugDirectory())
+ return E;
+
+ return Buf.commit();
+}
+
+Expected<uint32_t> COFFWriter::virtualAddressToFileAddress(uint32_t RVA) {
+ for (const auto &S : Obj.getSections()) {
+ if (RVA >= S.Header.VirtualAddress &&
+ RVA < S.Header.VirtualAddress + S.Header.SizeOfRawData)
+ return S.Header.PointerToRawData + RVA - S.Header.VirtualAddress;
+ }
+ return createStringError(object_error::parse_failed,
+ "debug directory payload not found");
+}
+
+// Locate which sections contain the debug directories, iterate over all
+// the debug_directory structs in there, and set the PointerToRawData field
+// in all of them, according to their new physical location in the file.
+Error COFFWriter::patchDebugDirectory() {
+ if (Obj.DataDirectories.size() < DEBUG_DIRECTORY)
+ return Error::success();
+ const data_directory *Dir = &Obj.DataDirectories[DEBUG_DIRECTORY];
+ if (Dir->Size <= 0)
+ return Error::success();
+ for (const auto &S : Obj.getSections()) {
+ if (Dir->RelativeVirtualAddress >= S.Header.VirtualAddress &&
+ Dir->RelativeVirtualAddress <
+ S.Header.VirtualAddress + S.Header.SizeOfRawData) {
+ if (Dir->RelativeVirtualAddress + Dir->Size >
+ S.Header.VirtualAddress + S.Header.SizeOfRawData)
+ return createStringError(object_error::parse_failed,
+ "debug directory extends past end of section");
+
+ size_t Offset = Dir->RelativeVirtualAddress - S.Header.VirtualAddress;
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData + Offset;
+ uint8_t *End = Ptr + Dir->Size;
+ while (Ptr < End) {
+ debug_directory *Debug = reinterpret_cast<debug_directory *>(Ptr);
+ if (!Debug->AddressOfRawData)
+ return createStringError(object_error::parse_failed,
+ "debug directory payload outside of "
+ "mapped sections not supported");
+ if (Expected<uint32_t> FilePosOrErr =
+ virtualAddressToFileAddress(Debug->AddressOfRawData))
+ Debug->PointerToRawData = *FilePosOrErr;
+ else
+ return FilePosOrErr.takeError();
+ Ptr += sizeof(debug_directory);
+ Offset += sizeof(debug_directory);
+ }
+ // Debug directory found and patched, all done.
+ return Error::success();
+ }
+ }
+ return createStringError(object_error::parse_failed,
+ "debug directory not found");
+}
+
+Error COFFWriter::write() {
+ bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16;
+ if (IsBigObj && Obj.IsPE)
+ return createStringError(object_error::parse_failed,
+ "too many sections for executable");
+ return write(IsBigObj);
+}
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.h b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.h
index 3c0bdcbd5d..cd6a17984c 100644
--- a/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.h
+++ b/contrib/libs/llvm12/tools/llvm-objcopy/COFF/Writer.h
@@ -1,62 +1,62 @@
-//===- Writer.h -------------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
-#define LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
-
-#include "Buffer.h"
-#include "llvm/MC/StringTableBuilder.h"
-#include "llvm/Support/Error.h"
-#include <cstddef>
-#include <utility>
-
-namespace llvm {
-namespace objcopy {
-namespace coff {
-
-struct Object;
-
-class COFFWriter {
- Object &Obj;
- Buffer &Buf;
-
- size_t FileSize;
- size_t FileAlignment;
- size_t SizeOfInitializedData;
- StringTableBuilder StrTabBuilder;
-
- template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
- Error finalizeRelocTargets();
- Error finalizeSymbolContents();
- void layoutSections();
- size_t finalizeStringTable();
-
- Error finalize(bool IsBigObj);
-
- void writeHeaders(bool IsBigObj);
- void writeSections();
- template <class SymbolTy> void writeSymbolStringTables();
-
- Error write(bool IsBigObj);
-
- Error patchDebugDirectory();
- Expected<uint32_t> virtualAddressToFileAddress(uint32_t RVA);
-
-public:
- virtual ~COFFWriter() {}
- Error write();
-
- COFFWriter(Object &Obj, Buffer &Buf)
- : Obj(Obj), Buf(Buf), StrTabBuilder(StringTableBuilder::WinCOFF) {}
-};
-
-} // end namespace coff
-} // end namespace objcopy
-} // end namespace llvm
-
-#endif // LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
+//===- Writer.h -------------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
+#define LLVM_TOOLS_OBJCOPY_COFF_WRITER_H
+
+#include "Buffer.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/Error.h"
+#include <cstddef>
+#include <utility>
+
+namespace llvm {
+namespace objcopy {
+namespace coff {
+
+struct Object;
+
+class COFFWriter {
+ Object &Obj;
+ Buffer &Buf;
+
+ size_t FileSize;
+ size_t FileAlignment;
+ size_t SizeOfInitializedData;
+ StringTableBuilder StrTabBuilder;
+
+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+ Error finalizeRelocTargets();
+ Error finalizeSymbolContents();
+ void layoutSections();
+ size_t finalizeStringTable();
+
+ Error finalize(bool IsBigObj);
+
+ void writeHeaders(bool IsBigObj);
+ void writeSections();
+ template <class SymbolTy> void writeSymbolStringTables();
+
+ Error write(bool IsBigObj);
+
+ Error patchDebugDirectory();
+ Expected<uint32_t> virtualAddressToFileAddress(uint32_t RVA);
+
+public:
+ virtual ~COFFWriter() {}
+ Error write();
+
+ COFFWriter(Object &Obj, Buffer &Buf)
+ : Obj(Obj), Buf(Buf), StrTabBuilder(StringTableBuilder::WinCOFF) {}
+};
+
+} // end namespace coff
+} // end namespace objcopy
+} // end namespace llvm
+
+#endif // LLVM_TOOLS_OBJCOPY_COFF_WRITER_H