brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · 1c04b7f Raw
214 lines · c
1//===- COFFObject.h ---------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H10#define LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H11 12#include "llvm/ADT/ArrayRef.h"13#include "llvm/ADT/DenseMap.h"14#include "llvm/ADT/StringRef.h"15#include "llvm/ADT/iterator_range.h"16#include "llvm/BinaryFormat/COFF.h"17#include "llvm/Object/COFF.h"18#include <cstddef>19#include <cstdint>20#include <vector>21 22namespace llvm {23namespace objcopy {24namespace coff {25 26struct Relocation {27  Relocation() = default;28  Relocation(const object::coff_relocation &R) : Reloc(R) {}29 30  object::coff_relocation Reloc;31  size_t Target = 0;32  StringRef TargetName; // Used for diagnostics only33};34 35struct Section {36  object::coff_section Header;37  std::vector<Relocation> Relocs;38  StringRef Name;39  ssize_t UniqueId;40  size_t Index;41 42  ArrayRef<uint8_t> getContents() const {43    if (!OwnedContents.empty())44      return OwnedContents;45    return ContentsRef;46  }47 48  void setContentsRef(ArrayRef<uint8_t> Data) {49    OwnedContents.clear();50    ContentsRef = Data;51  }52 53  void setOwnedContents(std::vector<uint8_t> &&Data) {54    ContentsRef = ArrayRef<uint8_t>();55    OwnedContents = std::move(Data);56    Header.SizeOfRawData = OwnedContents.size();57  }58 59  void clearContents() {60    ContentsRef = ArrayRef<uint8_t>();61    OwnedContents.clear();62  }63 64private:65  ArrayRef<uint8_t> ContentsRef;66  std::vector<uint8_t> OwnedContents;67};68 69struct AuxSymbol {70  AuxSymbol(ArrayRef<uint8_t> In) {71    assert(In.size() == sizeof(Opaque));72    llvm::copy(In, Opaque);73  }74 75  ArrayRef<uint8_t> getRef() const {76    return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));77  }78 79  uint8_t Opaque[sizeof(object::coff_symbol16)];80};81 82struct Symbol {83  object::coff_symbol32 Sym;84  StringRef Name;85  std::vector<AuxSymbol> AuxData;86  StringRef AuxFile;87  ssize_t TargetSectionId;88  ssize_t AssociativeComdatTargetSectionId = 0;89  std::optional<size_t> WeakTargetSymbolId;90  size_t UniqueId;91  size_t RawIndex;92  size_t OriginalRawIndex;93  bool Referenced;94};95 96struct Object {97  bool IsPE = false;98 99  object::dos_header DosHeader;100  ArrayRef<uint8_t> DosStub;101 102  object::coff_file_header CoffFileHeader;103 104  bool Is64 = false;105  object::pe32plus_header PeHeader;106  uint32_t BaseOfData = 0; // pe32plus_header lacks this field.107 108  std::vector<object::data_directory> DataDirectories;109 110  ArrayRef<Symbol> getSymbols() const { return Symbols; }111  // This allows mutating individual Symbols, but not mutating the list112  // of symbols itself.113  iterator_range<std::vector<Symbol>::iterator> getMutableSymbols() {114    return make_range(Symbols.begin(), Symbols.end());115  }116 117  const Symbol *findSymbol(size_t UniqueId) const;118 119  void addSymbols(ArrayRef<Symbol> NewSymbols);120  Error removeSymbols(function_ref<Expected<bool>(const Symbol &)> ToRemove);121 122  // Set the Referenced field on all Symbols, based on relocations in123  // all sections.124  Error markSymbols();125 126  ArrayRef<Section> getSections() const { return Sections; }127  // This allows mutating individual Sections, but not mutating the list128  // of sections itself.129  iterator_range<std::vector<Section>::iterator> getMutableSections() {130    return make_range(Sections.begin(), Sections.end());131  }132 133  const Section *findSection(ssize_t UniqueId) const;134 135  void addSections(ArrayRef<Section> NewSections);136  void removeSections(function_ref<bool(const Section &)> ToRemove);137  void truncateSections(function_ref<bool(const Section &)> ToTruncate);138 139private:140  std::vector<Symbol> Symbols;141  DenseMap<size_t, Symbol *> SymbolMap;142 143  size_t NextSymbolUniqueId = 0;144  size_t NextSymbolOriginalIndex = 0;145 146  std::vector<Section> Sections;147  DenseMap<ssize_t, Section *> SectionMap;148 149  ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.150 151  // Update SymbolMap.152  void updateSymbols();153 154  // Update SectionMap and Index in each Section.155  void updateSections();156};157 158// Copy between coff_symbol16 and coff_symbol32.159// The source and destination files can use either coff_symbol16 or160// coff_symbol32, while we always store them as coff_symbol32 in the161// intermediate data structure.162template <class Symbol1Ty, class Symbol2Ty>163void copySymbol(Symbol1Ty &Dest, const Symbol2Ty &Src) {164  static_assert(sizeof(Dest.Name.ShortName) == sizeof(Src.Name.ShortName),165                "Mismatched name sizes");166  memcpy(Dest.Name.ShortName, Src.Name.ShortName, sizeof(Dest.Name.ShortName));167  Dest.Value = Src.Value;168  Dest.SectionNumber = Src.SectionNumber;169  Dest.Type = Src.Type;170  Dest.StorageClass = Src.StorageClass;171  Dest.NumberOfAuxSymbols = Src.NumberOfAuxSymbols;172}173 174// Copy between pe32_header and pe32plus_header.175// We store the intermediate state in a pe32plus_header.176template <class PeHeader1Ty, class PeHeader2Ty>177void copyPeHeader(PeHeader1Ty &Dest, const PeHeader2Ty &Src) {178  Dest.Magic = Src.Magic;179  Dest.MajorLinkerVersion = Src.MajorLinkerVersion;180  Dest.MinorLinkerVersion = Src.MinorLinkerVersion;181  Dest.SizeOfCode = Src.SizeOfCode;182  Dest.SizeOfInitializedData = Src.SizeOfInitializedData;183  Dest.SizeOfUninitializedData = Src.SizeOfUninitializedData;184  Dest.AddressOfEntryPoint = Src.AddressOfEntryPoint;185  Dest.BaseOfCode = Src.BaseOfCode;186  Dest.ImageBase = Src.ImageBase;187  Dest.SectionAlignment = Src.SectionAlignment;188  Dest.FileAlignment = Src.FileAlignment;189  Dest.MajorOperatingSystemVersion = Src.MajorOperatingSystemVersion;190  Dest.MinorOperatingSystemVersion = Src.MinorOperatingSystemVersion;191  Dest.MajorImageVersion = Src.MajorImageVersion;192  Dest.MinorImageVersion = Src.MinorImageVersion;193  Dest.MajorSubsystemVersion = Src.MajorSubsystemVersion;194  Dest.MinorSubsystemVersion = Src.MinorSubsystemVersion;195  Dest.Win32VersionValue = Src.Win32VersionValue;196  Dest.SizeOfImage = Src.SizeOfImage;197  Dest.SizeOfHeaders = Src.SizeOfHeaders;198  Dest.CheckSum = Src.CheckSum;199  Dest.Subsystem = Src.Subsystem;200  Dest.DLLCharacteristics = Src.DLLCharacteristics;201  Dest.SizeOfStackReserve = Src.SizeOfStackReserve;202  Dest.SizeOfStackCommit = Src.SizeOfStackCommit;203  Dest.SizeOfHeapReserve = Src.SizeOfHeapReserve;204  Dest.SizeOfHeapCommit = Src.SizeOfHeapCommit;205  Dest.LoaderFlags = Src.LoaderFlags;206  Dest.NumberOfRvaAndSize = Src.NumberOfRvaAndSize;207}208 209} // end namespace coff210} // end namespace objcopy211} // end namespace llvm212 213#endif // LLVM_LIB_OBJCOPY_COFF_COFFOBJECT_H214