LLVM  16.0.0git
MachOObjcopy.cpp
Go to the documentation of this file.
1 //===- MachOObjcopy.cpp -----------------------------------------*- 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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "Archive.h"
11 #include "MachOReader.h"
12 #include "MachOWriter.h"
13 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/ObjCopy/ObjCopy.h"
21 #include "llvm/Support/Errc.h"
22 #include "llvm/Support/Error.h"
24 #include "llvm/Support/Path.h"
26 
27 using namespace llvm;
28 using namespace llvm::objcopy;
29 using namespace llvm::objcopy::macho;
30 using namespace llvm::object;
31 
32 using SectionPred = std::function<bool(const std::unique_ptr<Section> &Sec)>;
33 using LoadCommandPred = std::function<bool(const LoadCommand &LC)>;
34 
35 #ifndef NDEBUG
37  // TODO: Add support for LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB and
38  // LC_LAZY_LOAD_DYLIB
39  return LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH ||
40  LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_ID_DYLIB ||
41  LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_LOAD_DYLIB ||
42  LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_LOAD_WEAK_DYLIB;
43 }
44 #endif
45 
48  "unsupported load command encountered");
49 
50  return StringRef(reinterpret_cast<const char *>(LC.Payload.data()),
51  LC.Payload.size())
52  .rtrim('\0');
53 }
54 
55 static Error removeSections(const CommonConfig &Config, Object &Obj) {
56  SectionPred RemovePred = [](const std::unique_ptr<Section> &) {
57  return false;
58  };
59 
60  if (!Config.ToRemove.empty()) {
61  RemovePred = [&Config, RemovePred](const std::unique_ptr<Section> &Sec) {
62  return Config.ToRemove.matches(Sec->CanonicalName);
63  };
64  }
65 
66  if (Config.StripAll || Config.StripDebug) {
67  // Remove all debug sections.
68  RemovePred = [RemovePred](const std::unique_ptr<Section> &Sec) {
69  if (Sec->Segname == "__DWARF")
70  return true;
71 
72  return RemovePred(Sec);
73  };
74  }
75 
76  if (!Config.OnlySection.empty()) {
77  // Overwrite RemovePred because --only-section takes priority.
78  RemovePred = [&Config](const std::unique_ptr<Section> &Sec) {
79  return !Config.OnlySection.matches(Sec->CanonicalName);
80  };
81  }
82 
83  return Obj.removeSections(RemovePred);
84 }
85 
86 static void markSymbols(const CommonConfig &, Object &Obj) {
87  // Symbols referenced from the indirect symbol table must not be removed.
89  if (ISE.Symbol)
90  (*ISE.Symbol)->Referenced = true;
91 }
92 
93 static void updateAndRemoveSymbols(const CommonConfig &Config,
94  const MachOConfig &MachOConfig,
95  Object &Obj) {
96  for (SymbolEntry &Sym : Obj.SymTable) {
97  auto I = Config.SymbolsToRename.find(Sym.Name);
98  if (I != Config.SymbolsToRename.end())
99  Sym.Name = std::string(I->getValue());
100  }
101 
102  auto RemovePred = [&Config, &MachOConfig,
103  &Obj](const std::unique_ptr<SymbolEntry> &N) {
104  if (N->Referenced)
105  return false;
106  if (MachOConfig.KeepUndefined && N->isUndefinedSymbol())
107  return false;
108  if (N->n_desc & MachO::REFERENCED_DYNAMICALLY)
109  return false;
110  if (Config.StripAll)
111  return true;
112  if (Config.DiscardMode == DiscardType::All && !(N->n_type & MachO::N_EXT))
113  return true;
114  // This behavior is consistent with cctools' strip.
116  (Obj.Header.Flags & MachO::MH_DYLDLINK) && Obj.SwiftVersion &&
117  *Obj.SwiftVersion && N->isSwiftSymbol())
118  return true;
119  return false;
120  };
121 
122  Obj.SymTable.removeSymbols(RemovePred);
123 }
124 
125 template <typename LCType>
128  "unsupported load command encountered");
129 
130  uint32_t NewCmdsize = alignTo(sizeof(LCType) + S.size() + 1, 8);
131 
132  LC.MachOLoadCommand.load_command_data.cmdsize = NewCmdsize;
133  LC.Payload.assign(NewCmdsize - sizeof(LCType), 0);
134  std::copy(S.begin(), S.end(), LC.Payload.begin());
135 }
136 
138  LoadCommand LC;
139  MachO::rpath_command RPathLC;
140  RPathLC.cmd = MachO::LC_RPATH;
141  RPathLC.path = sizeof(MachO::rpath_command);
142  RPathLC.cmdsize = alignTo(sizeof(MachO::rpath_command) + Path.size() + 1, 8);
143  LC.MachOLoadCommand.rpath_command_data = RPathLC;
144  LC.Payload.assign(RPathLC.cmdsize - sizeof(MachO::rpath_command), 0);
145  std::copy(Path.begin(), Path.end(), LC.Payload.begin());
146  return LC;
147 }
148 
150  // Remove RPaths.
151  DenseSet<StringRef> RPathsToRemove(MachOConfig.RPathsToRemove.begin(),
153 
154  LoadCommandPred RemovePred = [&RPathsToRemove,
155  &MachOConfig](const LoadCommand &LC) {
156  if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH) {
157  // When removing all RPaths we don't need to care
158  // about what it contains
160  return true;
161 
162  StringRef RPath = getPayloadString(LC);
163  if (RPathsToRemove.count(RPath)) {
164  RPathsToRemove.erase(RPath);
165  return true;
166  }
167  }
168  return false;
169  };
170 
171  if (Error E = Obj.removeLoadCommands(RemovePred))
172  return E;
173 
174  // Emit an error if the Mach-O binary does not contain an rpath path name
175  // specified in -delete_rpath.
176  for (StringRef RPath : MachOConfig.RPathsToRemove) {
177  if (RPathsToRemove.count(RPath))
179  "no LC_RPATH load command with path: %s",
180  RPath.str().c_str());
181  }
182 
183  DenseSet<StringRef> RPaths;
184 
185  // Get all existing RPaths.
186  for (LoadCommand &LC : Obj.LoadCommands) {
187  if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH)
188  RPaths.insert(getPayloadString(LC));
189  }
190 
191  // Throw errors for invalid RPaths.
192  for (const auto &OldNew : MachOConfig.RPathsToUpdate) {
193  StringRef Old = OldNew.getFirst();
194  StringRef New = OldNew.getSecond();
195  if (!RPaths.contains(Old))
197  "no LC_RPATH load command with path: " + Old);
198  if (RPaths.contains(New))
200  "rpath '" + New +
201  "' would create a duplicate load command");
202  }
203 
204  // Update load commands.
205  for (LoadCommand &LC : Obj.LoadCommands) {
206  switch (LC.MachOLoadCommand.load_command_data.cmd) {
207  case MachO::LC_ID_DYLIB:
209  updateLoadCommandPayloadString<MachO::dylib_command>(
210  LC, *MachOConfig.SharedLibId);
211  break;
212 
213  case MachO::LC_RPATH: {
214  StringRef RPath = getPayloadString(LC);
215  StringRef NewRPath = MachOConfig.RPathsToUpdate.lookup(RPath);
216  if (!NewRPath.empty())
217  updateLoadCommandPayloadString<MachO::rpath_command>(LC, NewRPath);
218  break;
219  }
220 
221  // TODO: Add LC_REEXPORT_DYLIB, LC_LAZY_LOAD_DYLIB, and LC_LOAD_UPWARD_DYLIB
222  // here once llvm-objcopy supports them.
223  case MachO::LC_LOAD_DYLIB:
224  case MachO::LC_LOAD_WEAK_DYLIB:
225  StringRef InstallName = getPayloadString(LC);
226  StringRef NewInstallName =
227  MachOConfig.InstallNamesToUpdate.lookup(InstallName);
228  if (!NewInstallName.empty())
229  updateLoadCommandPayloadString<MachO::dylib_command>(LC,
230  NewInstallName);
231  break;
232  }
233  }
234 
235  // Add new RPaths.
236  for (StringRef RPath : MachOConfig.RPathToAdd) {
237  if (RPaths.contains(RPath))
239  "rpath '" + RPath +
240  "' would create a duplicate load command");
241  RPaths.insert(RPath);
242  Obj.LoadCommands.push_back(buildRPathLoadCommand(RPath));
243  }
244 
245  for (StringRef RPath : MachOConfig.RPathToPrepend) {
246  if (RPaths.contains(RPath))
248  "rpath '" + RPath +
249  "' would create a duplicate load command");
250 
251  RPaths.insert(RPath);
252  Obj.LoadCommands.insert(Obj.LoadCommands.begin(),
253  buildRPathLoadCommand(RPath));
254  }
255 
256  // Unlike appending rpaths, the indexes of subsequent load commands must
257  // be recalculated after prepending one.
258  if (!MachOConfig.RPathToPrepend.empty())
260 
261  // Remove any empty segments if required.
262  if (!MachOConfig.EmptySegmentsToRemove.empty()) {
263  auto RemovePred = [&MachOConfig](const LoadCommand &LC) {
264  if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_SEGMENT_64 ||
265  LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_SEGMENT) {
266  return LC.Sections.empty() &&
268  }
269  return false;
270  };
271  if (Error E = Obj.removeLoadCommands(RemovePred))
272  return E;
273  }
274 
275  return Error::success();
276 }
277 
278 static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
279  Object &Obj) {
280  for (LoadCommand &LC : Obj.LoadCommands)
281  for (const std::unique_ptr<Section> &Sec : LC.Sections) {
282  if (Sec->CanonicalName == SecName) {
284  FileOutputBuffer::create(Filename, Sec->Content.size());
285  if (!BufferOrErr)
286  return BufferOrErr.takeError();
287  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
288  llvm::copy(Sec->Content, Buf->getBufferStart());
289 
290  if (Error E = Buf->commit())
291  return E;
292  return Error::success();
293  }
294  }
295 
296  return createStringError(object_error::parse_failed, "section '%s' not found",
297  SecName.str().c_str());
298 }
299 
300 static Error addSection(const NewSectionInfo &NewSection, Object &Obj) {
301  std::pair<StringRef, StringRef> Pair = NewSection.SectionName.split(',');
302  StringRef TargetSegName = Pair.first;
303  Section Sec(TargetSegName, Pair.second);
304  Sec.Content =
305  Obj.NewSectionsContents.save(NewSection.SectionData->getBuffer());
306  Sec.Size = Sec.Content.size();
307 
308  // Add the a section into an existing segment.
309  for (LoadCommand &LC : Obj.LoadCommands) {
310  Optional<StringRef> SegName = LC.getSegmentName();
311  if (SegName && SegName == TargetSegName) {
313  for (const std::unique_ptr<Section> &S : LC.Sections)
314  Addr = std::max(Addr, S->Addr + S->Size);
315  LC.Sections.push_back(std::make_unique<Section>(Sec));
316  LC.Sections.back()->Addr = Addr;
317  return Error::success();
318  }
319  }
320 
321  // There's no segment named TargetSegName. Create a new load command and
322  // Insert a new section into it.
323  LoadCommand &NewSegment =
324  Obj.addSegment(TargetSegName, alignTo(Sec.Size, 16384));
325  NewSegment.Sections.push_back(std::make_unique<Section>(Sec));
326  NewSegment.Sections.back()->Addr = *NewSegment.getSegmentVMAddr();
327  return Error::success();
328 }
329 
331  StringRef SegName;
332  std::tie(SegName, SecName) = SecName.split(",");
333  auto FoundSeg =
334  llvm::find_if(O.LoadCommands, [SegName](const LoadCommand &LC) {
335  return LC.getSegmentName() == SegName;
336  });
337  if (FoundSeg == O.LoadCommands.end())
339  "could not find segment with name '%s'",
340  SegName.str().c_str());
341  auto FoundSec = llvm::find_if(FoundSeg->Sections,
342  [SecName](const std::unique_ptr<Section> &Sec) {
343  return Sec->Sectname == SecName;
344  });
345  if (FoundSec == FoundSeg->Sections.end())
347  "could not find section with name '%s'",
348  SecName.str().c_str());
349 
350  assert(FoundSec->get()->CanonicalName == (SegName + "," + SecName).str());
351  return *FoundSec->get();
352 }
353 
354 static Error updateSection(const NewSectionInfo &NewSection, Object &O) {
355  Expected<Section &> SecToUpdateOrErr = findSection(NewSection.SectionName, O);
356 
357  if (!SecToUpdateOrErr)
358  return SecToUpdateOrErr.takeError();
359  Section &Sec = *SecToUpdateOrErr;
360 
361  if (NewSection.SectionData->getBufferSize() > Sec.Size)
362  return createStringError(
364  "new section cannot be larger than previous section");
365  Sec.Content = O.NewSectionsContents.save(NewSection.SectionData->getBuffer());
366  Sec.Size = Sec.Content.size();
367  return Error::success();
368 }
369 
370 // isValidMachOCannonicalName returns success if Name is a MachO cannonical name
371 // ("<segment>,<section>") and lengths of both segment and section names are
372 // valid.
374  if (Name.count(',') != 1)
376  "invalid section name '%s' (should be formatted "
377  "as '<segment name>,<section name>')",
378  Name.str().c_str());
379 
380  std::pair<StringRef, StringRef> Pair = Name.split(',');
381  if (Pair.first.size() > 16)
383  "too long segment name: '%s'",
384  Pair.first.str().c_str());
385  if (Pair.second.size() > 16)
387  "too long section name: '%s'",
388  Pair.second.str().c_str());
389  return Error::success();
390 }
391 
392 static Error handleArgs(const CommonConfig &Config,
393  const MachOConfig &MachOConfig, Object &Obj) {
394  // Dump sections before add/remove for compatibility with GNU objcopy.
395  for (StringRef Flag : Config.DumpSection) {
397  StringRef FileName;
398  std::tie(SectionName, FileName) = Flag.split('=');
399  if (Error E = dumpSectionToFile(SectionName, FileName, Obj))
400  return E;
401  }
402 
403  if (Error E = removeSections(Config, Obj))
404  return E;
405 
406  // Mark symbols to determine which symbols are still needed.
407  if (Config.StripAll)
408  markSymbols(Config, Obj);
409 
410  updateAndRemoveSymbols(Config, MachOConfig, Obj);
411 
412  if (Config.StripAll)
413  for (LoadCommand &LC : Obj.LoadCommands)
414  for (std::unique_ptr<Section> &Sec : LC.Sections)
415  Sec->Relocations.clear();
416 
417  for (const NewSectionInfo &NewSection : Config.AddSection) {
418  if (Error E = isValidMachOCannonicalName(NewSection.SectionName))
419  return E;
420  if (Error E = addSection(NewSection, Obj))
421  return E;
422  }
423 
424  for (const NewSectionInfo &NewSection : Config.UpdateSection) {
425  if (Error E = isValidMachOCannonicalName(NewSection.SectionName))
426  return E;
427  if (Error E = updateSection(NewSection, Obj))
428  return E;
429  }
430 
432  return E;
433 
434  return Error::success();
435 }
436 
438  const MachOConfig &MachOConfig,
440  raw_ostream &Out) {
443  if (!O)
444  return createFileError(Config.InputFilename, O.takeError());
445 
446  if (O->get()->Header.FileType == MachO::HeaderFileType::MH_PRELOAD)
447  return createStringError(std::errc::not_supported,
448  "%s: MH_PRELOAD files are not supported",
449  Config.InputFilename.str().c_str());
450 
451  if (Error E = handleArgs(Config, MachOConfig, **O))
452  return createFileError(Config.InputFilename, std::move(E));
453 
454  // Page size used for alignment of segment sizes in Mach-O executables and
455  // dynamic libraries.
457  switch (In.getArch()) {
458  case Triple::ArchType::arm:
459  case Triple::ArchType::aarch64:
460  case Triple::ArchType::aarch64_32:
461  PageSize = 16384;
462  break;
463  default:
464  PageSize = 4096;
465  }
466 
467  MachOWriter Writer(**O, In.is64Bit(), In.isLittleEndian(),
469  if (auto E = Writer.finalize())
470  return E;
471  return Writer.write();
472 }
473 
475  const MultiFormatConfig &Config, const MachOUniversalBinary &In,
476  raw_ostream &Out) {
478  SmallVector<Slice, 2> Slices;
479  for (const auto &O : In.objects()) {
480  Expected<std::unique_ptr<Archive>> ArOrErr = O.getAsArchive();
481  if (ArOrErr) {
482  Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
483  createNewArchiveMembers(Config, **ArOrErr);
484  if (!NewArchiveMembersOrErr)
485  return NewArchiveMembersOrErr.takeError();
486  auto Kind = (*ArOrErr)->kind();
489  Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrErr =
490  writeArchiveToBuffer(*NewArchiveMembersOrErr,
491  (*ArOrErr)->hasSymbolTable(), Kind,
493  (*ArOrErr)->isThin());
494  if (!OutputBufferOrErr)
495  return OutputBufferOrErr.takeError();
496  Expected<std::unique_ptr<Binary>> BinaryOrErr =
497  object::createBinary(**OutputBufferOrErr);
498  if (!BinaryOrErr)
499  return BinaryOrErr.takeError();
500  Binaries.emplace_back(std::move(*BinaryOrErr),
501  std::move(*OutputBufferOrErr));
502  Slices.emplace_back(*cast<Archive>(Binaries.back().getBinary()),
503  O.getCPUType(), O.getCPUSubType(),
504  O.getArchFlagName(), O.getAlign());
505  continue;
506  }
507  // The methods getAsArchive, getAsObjectFile, getAsIRObject of the class
508  // ObjectForArch return an Error in case of the type mismatch. We need to
509  // check each in turn to see what kind of slice this is, so ignore errors
510  // produced along the way.
511  consumeError(ArOrErr.takeError());
512 
513  Expected<std::unique_ptr<MachOObjectFile>> ObjOrErr = O.getAsObjectFile();
514  if (!ObjOrErr) {
515  consumeError(ObjOrErr.takeError());
516  return createStringError(
517  std::errc::invalid_argument,
518  "slice for '%s' of the universal Mach-O binary "
519  "'%s' is not a Mach-O object or an archive",
520  O.getArchFlagName().c_str(),
521  Config.getCommonConfig().InputFilename.str().c_str());
522  }
523  std::string ArchFlagName = O.getArchFlagName();
524 
525  SmallVector<char, 0> Buffer;
526  raw_svector_ostream MemStream(Buffer);
527 
529  if (!MachO)
530  return MachO.takeError();
531 
532  if (Error E = executeObjcopyOnBinary(Config.getCommonConfig(), *MachO,
533  **ObjOrErr, MemStream))
534  return E;
535 
536  auto MB = std::make_unique<SmallVectorMemoryBuffer>(
537  std::move(Buffer), ArchFlagName, /*RequiresNullTerminator=*/false);
539  if (!BinaryOrErr)
540  return BinaryOrErr.takeError();
541  Binaries.emplace_back(std::move(*BinaryOrErr), std::move(MB));
542  Slices.emplace_back(*cast<MachOObjectFile>(Binaries.back().getBinary()),
543  O.getAlign());
544  }
545 
546  if (Error Err = writeUniversalBinaryToStream(Slices, Out))
547  return Err;
548 
549  return Error::success();
550 }
MachOUniversalWriter.h
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:156
llvm::errc::invalid_argument
@ invalid_argument
llvm::objcopy::MachOConfig::RPathToPrepend
std::vector< StringRef > RPathToPrepend
Definition: MachOConfig.h:24
llvm::objcopy::macho::Object::NewSectionsContents
StringSaver NewSectionsContents
Definition: MachOObject.h:344
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::objcopy::CommonConfig::OutputFilename
StringRef OutputFilename
Definition: CommonConfig.h:205
llvm::objcopy::CommonConfig::InputFilename
StringRef InputFilename
Definition: CommonConfig.h:203
llvm::object::Archive::K_BSD
@ K_BSD
Definition: Archive.h:339
llvm::objcopy::MachOConfig::InstallNamesToUpdate
DenseMap< StringRef, StringRef > InstallNamesToUpdate
Definition: MachOConfig.h:26
MachOConfig.h
llvm::objcopy::MultiFormatConfig::getMachOConfig
virtual Expected< const MachOConfig & > getMachOConfig() const =0
markSymbols
static void markSymbols(const CommonConfig &, Object &Obj)
Definition: MachOObjcopy.cpp:86
llvm::objcopy::macho::Object::IndirectSymTable
IndirectSymbolTable IndirectSymTable
Definition: MachOObject.h:309
llvm::objcopy::macho::Section::Content
StringRef Content
Definition: MachOObject.h:57
llvm::MachO::rpath_command::cmdsize
uint32_t cmdsize
Definition: MachO.h:801
llvm::objcopy::NewSectionInfo::SectionName
StringRef SectionName
Definition: CommonConfig.h:196
MachOWriter.h
SectionPred
std::function< bool(const SectionBase &Sec)> SectionPred
Definition: ELFObjcopy.cpp:53
llvm::MachO::N_EXT
@ N_EXT
Definition: MachO.h:310
llvm::objcopy::NameMatcher::matches
bool matches(StringRef S) const
Definition: CommonConfig.h:150
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
Path.h
MultiFormatConfig.h
SmallVectorMemoryBuffer.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::objcopy::macho::executeObjcopyOnMachOUniversalBinary
Error executeObjcopyOnMachOUniversalBinary(const MultiFormatConfig &Config, const object::MachOUniversalBinary &In, raw_ostream &Out)
Apply the transformations described by Config and MachOConfig to In and writes the result into Out.
Definition: MachOObjcopy.cpp:474
llvm::objcopy::macho::SymbolTable::removeSymbols
void removeSymbols(function_ref< bool(const std::unique_ptr< SymbolEntry > &)> ToRemove)
Definition: MachOObject.cpp:35
llvm::MachO::rpath_command
Definition: MachO.h:799
Error.h
updateLoadCommandPayloadString
static void updateLoadCommandPayloadString(LoadCommand &LC, StringRef S)
Definition: MachOObjcopy.cpp:126
llvm::objcopy::MachOConfig::EmptySegmentsToRemove
DenseSet< StringRef > EmptySegmentsToRemove
Definition: MachOConfig.h:33
llvm::objcopy::macho::IndirectSymbolEntry::Symbol
Optional< SymbolEntry * > Symbol
The Symbol referenced by this entry.
Definition: MachOObject.h:155
llvm::objcopy::CommonConfig::SymbolsToRename
StringMap< StringRef > SymbolsToRename
Definition: CommonConfig.h:245
llvm::objcopy::MachOConfig::KeepUndefined
bool KeepUndefined
Definition: MachOConfig.h:37
llvm::objcopy::CommonConfig::DiscardMode
DiscardType DiscardMode
Definition: CommonConfig.h:219
Errc.h
dumpSectionToFile
static Error dumpSectionToFile(StringRef SecName, StringRef Filename, Object &Obj)
Definition: MachOObjcopy.cpp:278
addSection
static Error addSection(const NewSectionInfo &NewSection, Object &Obj)
Definition: MachOObjcopy.cpp:300
llvm::copy
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1836
llvm::Optional
Definition: APInt.h:33
llvm::MachO::rpath_command::path
uint32_t path
Definition: MachO.h:802
FileOutputBuffer.h
llvm::objcopy::macho
Definition: MachOObjcopy.h:26
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::objcopy::macho::MachOReader
Definition: MachOReader.h:30
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::objcopy::macho::Reader
Definition: MachOReader.h:24
llvm::objcopy::macho::Object::SwiftVersion
Optional< uint32_t > SwiftVersion
Definition: MachOObject.h:317
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::objcopy::MachOConfig::RemoveAllRpaths
bool RemoveAllRpaths
Definition: MachOConfig.h:40
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::count
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1042
getPayloadString
static StringRef getPayloadString(const LoadCommand &LC)
Definition: MachOObjcopy.cpp:46
llvm::objcopy::macho::IndirectSymbolTable::Symbols
std::vector< IndirectSymbolEntry > Symbols
Definition: MachOObject.h:162
llvm::objcopy::macho::LoadCommand::getSegmentName
Optional< StringRef > getSegmentName() const
Definition: MachOObject.cpp:204
llvm::objcopy::MultiFormatConfig::getCommonConfig
virtual const CommonConfig & getCommonConfig() const =0
llvm::objcopy::macho::IndirectSymbolEntry
Definition: MachOObject.h:149
llvm::objcopy::macho::MachHeader::Flags
uint32_t Flags
Definition: MachOObject.h:34
llvm::object
Definition: DWARFDebugLoc.h:25
ArchiveWriter.h
PageSize
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
llvm::objcopy::CommonConfig::OnlySection
NameMatcher OnlySection
Definition: CommonConfig.h:228
llvm::createFileError
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1319
llvm::objcopy::macho::Object::removeLoadCommands
Error removeLoadCommands(function_ref< bool(const LoadCommand &)> ToRemove)
Definition: MachOObject.cpp:91
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::objcopy::NewSectionInfo
Definition: CommonConfig.h:191
llvm::MachO::rpath_command::cmd
uint32_t cmd
Definition: MachO.h:800
llvm::objcopy::macho::LoadCommand
Definition: MachOObject.h:79
MachOUniversal.h
llvm::objcopy::MachOConfig
Definition: MachOConfig.h:21
llvm::objcopy::CommonConfig::AddSection
std::vector< NewSectionInfo > AddSection
Definition: CommonConfig.h:222
llvm::objcopy::macho::Object
Definition: MachOObject.h:297
DenseSet.h
llvm::objcopy::MachOConfig::RPathToAdd
std::vector< StringRef > RPathToAdd
Definition: MachOConfig.h:23
llvm::objcopy::CommonConfig::DumpSection
std::vector< StringRef > DumpSection
Definition: CommonConfig.h:223
llvm::objcopy::macho::SymbolEntry::Name
std::string Name
Definition: MachOObject.h:106
llvm::objcopy::macho::executeObjcopyOnBinary
Error executeObjcopyOnBinary(const CommonConfig &Config, const MachOConfig &MachOConfig, object::MachOObjectFile &In, raw_ostream &Out)
Apply the transformations described by Config and MachOConfig to In and writes the result into Out.
Definition: MachOObjcopy.cpp:437
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
llvm::objcopy::macho::Section::Size
uint64_t Size
Definition: MachOObject.h:46
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::AMDGPU::ElfNote::SectionName
const char SectionName[]
Definition: AMDGPUPTNote.h:24
llvm::objcopy::MultiFormatConfig
Definition: MultiFormatConfig.h:24
CommonConfig.h
llvm::objcopy::macho::Object::updateLoadCommandIndexes
void updateLoadCommandIndexes()
Definition: MachOObject.cpp:40
llvm::objcopy::NewSectionInfo::SectionData
std::shared_ptr< MemoryBuffer > SectionData
Definition: CommonConfig.h:197
llvm::objcopy::macho::Object::SymTable
SymbolTable SymTable
Definition: MachOObject.h:301
llvm::objcopy::MachOConfig::SharedLibId
Optional< StringRef > SharedLibId
Definition: MachOConfig.h:30
llvm::objcopy::macho::LoadCommand::getSegmentVMAddr
Optional< uint64_t > getSegmentVMAddr() const
Definition: MachOObject.cpp:216
llvm::objcopy::MachOConfig::RPathsToRemove
DenseSet< StringRef > RPathsToRemove
Definition: MachOConfig.h:27
llvm::objcopy::NameMatcher::empty
bool empty() const
Definition: CommonConfig.h:155
updateSection
static Error updateSection(const NewSectionInfo &NewSection, Object &O)
Definition: MachOObjcopy.cpp:354
llvm::object::MachOObjectFile
Definition: MachO.h:406
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::objcopy::macho::LoadCommand::Sections
std::vector< std::unique_ptr< Section > > Sections
Definition: MachOObject.h:94
llvm::objcopy::CommonConfig::DeterministicArchives
bool DeterministicArchives
Definition: CommonConfig.h:251
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:264
llvm::objcopy::macho::MachOWriter
Definition: MachOWriter.h:24
uint64_t
llvm::objcopy::macho::Object::removeSections
Error removeSections(function_ref< bool(const std::unique_ptr< Section > &)> ToRemove)
Definition: MachOObject.cpp:102
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
llvm::objcopy::createNewArchiveMembers
Expected< std::vector< NewArchiveMember > > createNewArchiveMembers(const MultiFormatConfig &Config, const Archive &Ar)
Applies the transformations described by Config to each member in archive Ar.
Definition: Archive.cpp:24
llvm::objcopy::macho::Object::LoadCommands
std::vector< LoadCommand > LoadCommands
Definition: MachOObject.h:299
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::StringRef::rtrim
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition: StringRef.h:796
llvm::objcopy::macho::LoadCommand::MachOLoadCommand
MachO::macho_load_command MachOLoadCommand
Definition: MachOObject.h:83
isValidMachOCannonicalName
static Error isValidMachOCannonicalName(StringRef Name)
Definition: MachOObjcopy.cpp:373
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::objcopy::macho::Object::addSegment
LoadCommand & addSegment(StringRef SegName, uint64_t SegVMSize)
Creates a new segment load command in the object and returns a reference to the newly created load co...
Definition: MachOObject.cpp:184
buildRPathLoadCommand
static LoadCommand buildRPathLoadCommand(StringRef Path)
Definition: MachOObjcopy.cpp:137
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LoadCommandPred
std::function< bool(const LoadCommand &LC)> LoadCommandPred
Definition: MachOObjcopy.cpp:33
llvm::objcopy::CommonConfig::StripDebug
bool StripDebug
Definition: CommonConfig.h:259
findSection
static Expected< Section & > findSection(StringRef SecName, Object &O)
Definition: MachOObjcopy.cpp:330
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::objcopy::macho::SymbolEntry
Definition: MachOObject.h:105
llvm::objcopy::MachOConfig::RPathsToUpdate
DenseMap< StringRef, StringRef > RPathsToUpdate
Definition: MachOConfig.h:25
MachOReader.h
llvm::objcopy::MachOConfig::StripSwiftSymbols
bool StripSwiftSymbols
Definition: MachOConfig.h:36
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::contains
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:185
uint32_t
updateAndRemoveSymbols
static void updateAndRemoveSymbols(const CommonConfig &Config, const MachOConfig &MachOConfig, Object &Obj)
Definition: MachOObjcopy.cpp:93
llvm::objcopy::macho::MachOWriter::write
Error write()
Definition: MachOWriter.cpp:659
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
MachOObjcopy.h
llvm::FileOutputBuffer::create
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...
Definition: FileOutputBuffer.cpp:156
llvm::objcopy::macho::LoadCommand::Payload
std::vector< uint8_t > Payload
Definition: MachOObject.h:88
llvm::objcopy::macho::MachOWriter::finalize
Error finalize()
Definition: MachOWriter.cpp:657
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1761
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
handleArgs
static Error handleArgs(const CommonConfig &Config, const MachOConfig &MachOConfig, Object &Obj)
Definition: MachOObjcopy.cpp:392
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1238
llvm::objcopy::macho::Object::Header
MachHeader Header
Definition: MachOObject.h:298
llvm::object::writeUniversalBinaryToStream
Error writeUniversalBinaryToStream(ArrayRef< Slice > Slices, raw_ostream &Out)
Definition: MachOUniversalWriter.cpp:273
llvm::MachO::MH_DYLDLINK
@ MH_DYLDLINK
Definition: MachO.h:62
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::objcopy::CommonConfig::UpdateSection
std::vector< NewSectionInfo > UpdateSection
Definition: CommonConfig.h:224
llvm::objcopy::DiscardType::All
@ All
removeSections
static Error removeSections(const CommonConfig &Config, Object &Obj)
Definition: MachOObjcopy.cpp:55
llvm::objcopy::CommonConfig::StripAll
bool StripAll
Definition: CommonConfig.h:256
llvm::object::Archive::K_DARWIN
@ K_DARWIN
Definition: Archive.h:339
llvm::MachO::MH_PRELOAD
@ MH_PRELOAD
Definition: MachO.h:47
isLoadCommandWithPayloadString
static bool isLoadCommandWithPayloadString(const LoadCommand &LC)
Definition: MachOObjcopy.cpp:36
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:596
llvm::sys::path::filename
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:577
llvm::objcopy::macho::Section
Definition: MachOObject.h:39
N
#define N
llvm::MachO::REFERENCED_DYNAMICALLY
@ REFERENCED_DYNAMICALLY
Definition: MachO.h:343
processLoadCommands
static Error processLoadCommands(const MachOConfig &MachOConfig, Object &Obj)
Definition: MachOObjcopy.cpp:149
llvm::StringSaver::save
StringRef save(const char *S)
Definition: StringSaver.h:30
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:659
llvm::object::createBinary
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr, bool InitContent=true)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:45
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::erase
bool erase(const ValueT &V)
Definition: DenseSet.h:101
llvm::objcopy::CommonConfig::ToRemove
NameMatcher ToRemove
Definition: CommonConfig.h:229
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:221
llvm::objcopy::CommonConfig
Definition: CommonConfig.h:201
ObjCopy.h
copy
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
Definition: README.txt:101
llvm::objcopy
Definition: COFFConfig.h:15
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:693
llvm::object::MachOUniversalBinary
Definition: MachOUniversal.h:30
llvm::objcopy::macho::Reader::create
virtual Expected< std::unique_ptr< Object > > create() const =0
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:941
llvm::writeArchiveToBuffer
Expected< std::unique_ptr< MemoryBuffer > > writeArchiveToBuffer(ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin)
Definition: ArchiveWriter.cpp:856