LLVM: lib/ObjCopy/COFF/COFFObjcopy.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15

22#include

23

24namespace llvm {

25namespace objcopy {

26namespace coff {

27

28using namespace object;

29using namespace COFF;

30

33}

34

37 return 0;

39 return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,

41}

42

47 if (!LinkTargetOrErr)

49 auto LinkTarget = std::move(*LinkTargetOrErr);

50 uint32_t CRC32 = llvm::crc32(arrayRefFromStringRef(LinkTarget->getBuffer()));

51

53 size_t CRCPos = alignTo(FileName.size() + 1, 4);

54 std::vector<uint8_t> Data(CRCPos + 4);

55 memcpy(Data.data(), FileName.data(), FileName.size());

58}

59

60

65

68 Sec.Name = Name;

69 Sec.Header.VirtualSize = NeedVA ? Sec.getContents().size() : 0u;

70 Sec.Header.VirtualAddress = NeedVA ? getNextRVA(Obj) : 0u;

71 Sec.Header.SizeOfRawData =

72 NeedVA ? alignTo(Sec.Header.VirtualSize,

74 : Sec.getContents().size();

75

76 Sec.Header.PointerToRelocations = 0;

77 Sec.Header.PointerToLinenumbers = 0;

78

79 Sec.Header.NumberOfLinenumbers = 0;

81

83}

84

88 if (!Contents)

90

91 addSection(Obj, ".gnu_debuglink", *Contents,

94

96}

97

99

100 const uint32_t PreserveMask =

108

109

110

112

120 NewCharacteristics |=

130

131 return NewCharacteristics;

132}

133

137 continue;

138

140

141 std::unique_ptr Buffer;

143 Buffer = std::move(*B);

144 else

145 return B.takeError();

146

147 llvm::copy(Contents, Buffer->getBufferStart());

148 if (Error E = Buffer->commit())

149 return E;

150

152 }

153 return createStringError(object_error::parse_failed, "section '%s' not found",

155}

156

162 return E;

163 }

164

165

167

168

169 if (Config.OnlySection.empty() && Config.OnlySection.matches(Sec.Name))

170 return true;

171

174 if (isDebugSection(Sec) &&

175 (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)

176 return true;

177 }

178

180 return true;

181

182 return false;

183 });

184

185 if (Config.OnlyKeepDebug) {

189 : nullptr;

190

191

194 !(DebugDir && DebugDir->Size > 0 &&

200 });

201 }

202

203

207

208

210 Config.SymbolsToRemove.empty())

212 return E;

213

216 if (I != Config.SymbolsToRename.end())

218 }

219

221

222

224 return true;

225

227

231 "'" + Config.OutputFilename + "': not stripping symbol '" +

232 Sym.Name.str() + "' because it is named in a relocation");

233 return true;

234 }

235

237

238

239

240

243 if (Config.StripUnneeded ||

244 Config.UnneededSymbolsToRemove.matches(Sym.Name))

245 return true;

246

247

248

249

253 return true;

254 }

255

256 return false;

257 };

258

259

261 return Err;

262

263 if (Config.SetSectionFlags.empty())

265 const auto It = Config.SetSectionFlags.find(Sec.Name);

266 if (It != Config.SetSectionFlags.end())

269 }

270

273 const auto It = Config.SetSectionFlags.find(NewSection.SectionName);

274 if (It != Config.SetSectionFlags.end())

276 else

278

281 NewSection.SectionData->getBufferStart()),

282 NewSection.SectionData->getBufferSize()),

284 }

285

288 return Sec.Name == NewSection.SectionName;

289 });

292 "could not find section with name '%s'",

294 size_t ContentSize = It->getContents().size();

295 if (!ContentSize)

298 "section '%s' cannot be updated because it does not have contents",

300 if (ContentSize < NewSection.SectionData->getBufferSize())

303 "new section cannot be larger than previous section");

304 It->setOwnedContents({NewSection.SectionData->getBufferStart(),

305 NewSection.SectionData->getBufferEnd()});

306 }

307

308 if (Config.AddGnuDebugLink.empty())

310 return E;

311

314 if (!Obj.IsPE)

317 "'" + Config.OutputFilename +

318 "': unable to set subsystem on a relocatable object file");

325 }

326

328}

329

335 if (!ObjOrErr)

338 assert(Obj && "Unable to deserialize COFF object");

342 if (Error E = Writer.write())

345}

346

347}

348}

349}

ReachingDefAnalysis InstSet & ToRemove

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

This class represents an Operation in the Expression.

Represents either an error or a value T.

std::error_code getError() const

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

static Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)

Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr size_t size() const

size - Get the string size.

constexpr const char * data() const

data - Get a pointer to the start of the string (which may not be null terminated).

Expected< std::unique_ptr< Object > > create() const

This class implements an extremely fast bulk output stream that can only output to a stream.

@ IMAGE_SCN_ALIGN_64BYTES

@ IMAGE_SCN_ALIGN_128BYTES

@ IMAGE_SCN_ALIGN_256BYTES

@ IMAGE_SCN_ALIGN_1024BYTES

@ IMAGE_SCN_ALIGN_512BYTES

@ IMAGE_SCN_CNT_UNINITIALIZED_DATA

@ IMAGE_SCN_MEM_DISCARDABLE

@ IMAGE_SCN_ALIGN_4096BYTES

@ IMAGE_SCN_CNT_INITIALIZED_DATA

@ IMAGE_SCN_ALIGN_8192BYTES

@ IMAGE_SCN_ALIGN_16BYTES

@ IMAGE_SCN_ALIGN_32BYTES

@ IMAGE_SCN_ALIGN_2048BYTES

@ IMAGE_SYM_CLASS_STATIC

Static.

static bool isDebugSection(const Section &Sec)

Error executeObjcopyOnBinary(const CommonConfig &Config, const COFFConfig &, object::COFFObjectFile &In, raw_ostream &Out)

Apply the transformations described by Config and COFFConfig to In and writes the result into Out.

static void addSection(Object &Obj, StringRef Name, ArrayRef< uint8_t > Contents, uint32_t Characteristics)

static uint32_t flagsToCharacteristics(SectionFlag AllFlags, uint32_t OldChar)

static Error dumpSection(Object &O, StringRef SectionName, StringRef FileName)

static uint64_t getNextRVA(const Object &Obj)

static Error handleArgs(const CommonConfig &Config, const COFFConfig &COFFConfig, Object &Obj)

static Error addGnuDebugLink(Object &Obj, StringRef DebugLinkFile)

static Expected< std::vector< uint8_t > > createGnuDebugLinkSectionContents(StringRef File)

void write32le(void *P, uint32_t V)

StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get filename.

This is an optimization pass for GlobalISel generic memory operations.

Error createFileError(const Twine &F, Error E)

Concatenate a source file path and/or name with an Error.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

uint32_t crc32(ArrayRef< uint8_t > Data)

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

OutputIt copy(R &&Range, OutputIt Out)

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

std::optional< unsigned > MinorSubsystemVersion

std::optional< unsigned > Subsystem

std::optional< unsigned > MajorSubsystemVersion

std::shared_ptr< MemoryBuffer > SectionData

iterator_range< std::vector< Symbol >::iterator > getMutableSymbols()

void truncateSections(function_ref< bool(const Section &)> ToTruncate)

std::vector< object::data_directory > DataDirectories

void addSections(ArrayRef< Section > NewSections)

object::pe32plus_header PeHeader

void removeSections(function_ref< bool(const Section &)> ToRemove)

iterator_range< std::vector< Section >::iterator > getMutableSections()

ArrayRef< Section > getSections() const

Error removeSymbols(function_ref< Expected< bool >(const Symbol &)> ToRemove)

void setOwnedContents(std::vector< uint8_t > &&Data)

object::coff_section Header

std::vector< Relocation > Relocs

ArrayRef< uint8_t > getContents() const

object::coff_symbol32 Sym

support::ulittle32_t Characteristics

support::ulittle32_t SizeOfRawData

support::ulittle32_t VirtualAddress

SectionNumberType SectionNumber

support::ulittle32_t RelativeVirtualAddress

support::ulittle32_t Size