Path: blob/main/contrib/llvm-project/llvm/lib/ObjCopy/COFF/COFFObject.h
35268 views
//===- COFFObject.h ---------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H9#define LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H1011#include "llvm/ADT/ArrayRef.h"12#include "llvm/ADT/DenseMap.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/ADT/iterator_range.h"15#include "llvm/BinaryFormat/COFF.h"16#include "llvm/Object/COFF.h"17#include <cstddef>18#include <cstdint>19#include <vector>2021namespace llvm {22namespace objcopy {23namespace coff {2425struct Relocation {26Relocation() = default;27Relocation(const object::coff_relocation &R) : Reloc(R) {}2829object::coff_relocation Reloc;30size_t Target = 0;31StringRef TargetName; // Used for diagnostics only32};3334struct Section {35object::coff_section Header;36std::vector<Relocation> Relocs;37StringRef Name;38ssize_t UniqueId;39size_t Index;4041ArrayRef<uint8_t> getContents() const {42if (!OwnedContents.empty())43return OwnedContents;44return ContentsRef;45}4647void setContentsRef(ArrayRef<uint8_t> Data) {48OwnedContents.clear();49ContentsRef = Data;50}5152void setOwnedContents(std::vector<uint8_t> &&Data) {53ContentsRef = ArrayRef<uint8_t>();54OwnedContents = std::move(Data);55Header.SizeOfRawData = OwnedContents.size();56}5758void clearContents() {59ContentsRef = ArrayRef<uint8_t>();60OwnedContents.clear();61}6263private:64ArrayRef<uint8_t> ContentsRef;65std::vector<uint8_t> OwnedContents;66};6768struct AuxSymbol {69AuxSymbol(ArrayRef<uint8_t> In) {70assert(In.size() == sizeof(Opaque));71std::copy(In.begin(), In.end(), Opaque);72}7374ArrayRef<uint8_t> getRef() const {75return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));76}7778uint8_t Opaque[sizeof(object::coff_symbol16)];79};8081struct Symbol {82object::coff_symbol32 Sym;83StringRef Name;84std::vector<AuxSymbol> AuxData;85StringRef AuxFile;86ssize_t TargetSectionId;87ssize_t AssociativeComdatTargetSectionId = 0;88std::optional<size_t> WeakTargetSymbolId;89size_t UniqueId;90size_t RawIndex;91bool Referenced;92};9394struct Object {95bool IsPE = false;9697object::dos_header DosHeader;98ArrayRef<uint8_t> DosStub;99100object::coff_file_header CoffFileHeader;101102bool Is64 = false;103object::pe32plus_header PeHeader;104uint32_t BaseOfData = 0; // pe32plus_header lacks this field.105106std::vector<object::data_directory> DataDirectories;107108ArrayRef<Symbol> getSymbols() const { return Symbols; }109// This allows mutating individual Symbols, but not mutating the list110// of symbols itself.111iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {112return make_range(Symbols.begin(), Symbols.end());113}114115const Symbol *findSymbol(size_t UniqueId) const;116117void addSymbols(ArrayRef<Symbol> NewSymbols);118Error removeSymbols(function_ref<Expected<bool>(const Symbol &)> ToRemove);119120// Set the Referenced field on all Symbols, based on relocations in121// all sections.122Error markSymbols();123124ArrayRef<Section> getSections() const { return Sections; }125// This allows mutating individual Sections, but not mutating the list126// of sections itself.127iterator_range<std::vector<Section>::iterator> getMutableSections() {128return make_range(Sections.begin(), Sections.end());129}130131const Section *findSection(ssize_t UniqueId) const;132133void addSections(ArrayRef<Section> NewSections);134void removeSections(function_ref<bool(const Section &)> ToRemove);135void truncateSections(function_ref<bool(const Section &)> ToTruncate);136137private:138std::vector<Symbol> Symbols;139DenseMap<size_t, Symbol *> SymbolMap;140141size_t NextSymbolUniqueId = 0;142143std::vector<Section> Sections;144DenseMap<ssize_t, Section *> SectionMap;145146ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.147148// Update SymbolMap.149void updateSymbols();150151// Update SectionMap and Index in each Section.152void updateSections();153};154155// Copy between coff_symbol16 and coff_symbol32.156// The source and destination files can use either coff_symbol16 or157// coff_symbol32, while we always store them as coff_symbol32 in the158// intermediate data structure.159template <class Symbol1Ty, class Symbol2Ty>160void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {161static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),162"Mismatched name sizes");163memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));164Dest.Value = Src.Value;165Dest.SectionNumber = Src.SectionNumber;166Dest.Type = Src.Type;167Dest.StorageClass = Src.StorageClass;168Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;169}170171// Copy between pe32_header and pe32plus_header.172// We store the intermediate state in a pe32plus_header.173template <class PeHeader1Ty, class PeHeader2Ty>174void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {175Dest.Magic = Src.Magic;176Dest.MajorLinkerVersion = Src.MajorLinkerVersion;177Dest.MinorLinkerVersion = Src.MinorLinkerVersion;178Dest.SizeOfCode = Src.SizeOfCode;179Dest.SizeOfInitializedData = Src.SizeOfInitializedData;180Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;181Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;182Dest.BaseOfCode = Src.BaseOfCode;183Dest.ImageBase = Src.ImageBase;184Dest.SectionAlignment = Src.SectionAlignment;185Dest.FileAlignment = Src.FileAlignment;186Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;187Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;188Dest.MajorImageVersion = Src.MajorImageVersion;189Dest.MinorImageVersion = Src.MinorImageVersion;190Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;191Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;192Dest.Win32VersionValue = Src.Win32VersionValue;193Dest.SizeOfImage = Src.SizeOfImage;194Dest.SizeOfHeaders = Src.SizeOfHeaders;195Dest.CheckSum = Src.CheckSum;196Dest.Subsystem = Src.Subsystem;197Dest.DLLCharacteristics = Src.DLLCharacteristics;198Dest.SizeOfStackReserve = Src.SizeOfStackReserve;199Dest.SizeOfStackCommit = Src.SizeOfStackCommit;200Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;201Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;202Dest.LoaderFlags = Src.LoaderFlags;203Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;204}205206} // end namespace coff207} // end namespace objcopy208} // end namespace llvm209210#endif // LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H211212213