LLVM  16.0.0git
Archive.cpp
Go to the documentation of this file.
1 //===- Archive.cpp --------------------------------------------------------===//
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 
9 #include "Archive.h"
12 #include "llvm/ObjCopy/ObjCopy.h"
13 #include "llvm/Object/Error.h"
14 #include "llvm/Object/MachO.h"
17 
18 namespace llvm {
19 namespace objcopy {
20 
21 using namespace llvm::object;
22 
23 Expected<std::vector<NewArchiveMember>>
25  std::vector<NewArchiveMember> NewArchiveMembers;
26  Error Err = Error::success();
27  for (const Archive::Child &Child : Ar.children(Err)) {
28  Expected<StringRef> ChildNameOrErr = Child.getName();
29  if (!ChildNameOrErr)
30  return createFileError(Ar.getFileName(), ChildNameOrErr.takeError());
31 
32  Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
33  if (!ChildOrErr)
34  return createFileError(Ar.getFileName() + "(" + *ChildNameOrErr + ")",
35  ChildOrErr.takeError());
36 
37  SmallVector<char, 0> Buffer;
38  raw_svector_ostream MemStream(Buffer);
39 
40  if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MemStream))
41  return std::move(E);
42 
44  Child, Config.getCommonConfig().DeterministicArchives);
45  if (!Member)
46  return createFileError(Ar.getFileName(), Member.takeError());
47 
48  Member->Buf = std::make_unique<SmallVectorMemoryBuffer>(
49  std::move(Buffer), ChildNameOrErr.get());
50  Member->MemberName = Member->Buf->getBufferIdentifier();
51  NewArchiveMembers.push_back(std::move(*Member));
52  }
53  if (Err)
55  std::move(Err));
56  return std::move(NewArchiveMembers);
57 }
58 
59 // For regular archives this function simply calls llvm::writeArchive,
60 // For thin archives it writes the archive file itself as well as its members.
62  ArrayRef<NewArchiveMember> NewMembers,
63  bool WriteSymtab, object::Archive::Kind Kind,
64  bool Deterministic, bool Thin) {
65  if (Kind == object::Archive::K_BSD && !NewMembers.empty() &&
66  NewMembers.front().detectKindFromObject() == object::Archive::K_DARWIN)
68 
69  if (Error E = writeArchive(ArcName, NewMembers, WriteSymtab, Kind,
70  Deterministic, Thin))
71  return createFileError(ArcName, std::move(E));
72 
73  if (!Thin)
74  return Error::success();
75 
76  for (const NewArchiveMember &Member : NewMembers) {
77  // For regular files (as is the case for deepWriteArchive),
78  // FileOutputBuffer::create will return OnDiskBuffer.
79  // OnDiskBuffer uses a temporary file and then renames it. So in reality
80  // there is no inefficiency / duplicated in-memory buffers in this case. For
81  // now in-memory buffers can not be completely avoided since
82  // NewArchiveMember still requires them even though writeArchive does not
83  // write them on disk.
85  FileOutputBuffer::create(Member.MemberName, Member.Buf->getBufferSize(),
87  if (!FB)
88  return FB.takeError();
89  std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(),
90  (*FB)->getBufferStart());
91  if (Error E = (*FB)->commit())
92  return E;
93  }
94  return Error::success();
95 }
96 
98  const object::Archive &Ar) {
99  Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
100  createNewArchiveMembers(Config, Ar);
101  if (!NewArchiveMembersOrErr)
102  return NewArchiveMembersOrErr.takeError();
103  const CommonConfig &CommonConfig = Config.getCommonConfig();
104  return deepWriteArchive(CommonConfig.OutputFilename, *NewArchiveMembersOrErr,
105  Ar.hasSymbolTable(), Ar.kind(),
107 }
108 
109 } // end namespace objcopy
110 } // end namespace llvm
llvm::NewArchiveMember
Definition: ArchiveWriter.h:20
llvm::object::Archive::Kind
Kind
Definition: Archive.h:339
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::object::Archive::children
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition: Archive.h:347
llvm::SmallVector< char, 0 >
MultiFormatConfig.h
SmallVectorMemoryBuffer.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
Archive.h
llvm::objcopy::executeObjcopyOnBinary
Error executeObjcopyOnBinary(const MultiFormatConfig &Config, object::Binary &In, raw_ostream &Out)
Applies the transformations described by Config to In and writes the result into Out.
Definition: ObjCopy.cpp:38
FileOutputBuffer.h
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:159
MachO.h
llvm::objcopy::MultiFormatConfig::getCommonConfig
virtual const CommonConfig & getCommonConfig() const =0
llvm::object::Archive
Definition: Archive.h:159
llvm::object
Definition: DWARFDebugLoc.h:25
Error.h
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::FileOutputBuffer::F_executable
@ F_executable
Set the 'x' bit on the resulting file.
Definition: FileOutputBuffer.h:32
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::writeArchive
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
Definition: ArchiveWriter.cpp:823
llvm::objcopy::MultiFormatConfig
Definition: MultiFormatConfig.h:24
CommonConfig.h
llvm::object::Archive::isThin
bool isThin() const
Definition: Archive.h:342
llvm::objcopy::CommonConfig::DeterministicArchives
bool DeterministicArchives
Definition: CommonConfig.h:251
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
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::object::Archive::hasSymbolTable
bool hasSymbolTable() const
Definition: Archive.cpp:1169
llvm::objcopy::executeObjcopyOnArchive
Error executeObjcopyOnArchive(const MultiFormatConfig &Config, const object::Archive &Ar)
Applies the transformations described by Config to each member in archive Ar.
Definition: Archive.cpp:97
llvm::objcopy::deepWriteArchive
static Error deepWriteArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin)
Definition: Archive.cpp:61
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:566
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::ArrayRef::front
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:167
llvm::object::Archive::Child
Definition: Archive.h:163
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::object::Archive::kind
Kind kind() const
Definition: Archive.h:341
llvm::object::Archive::K_DARWIN
@ K_DARWIN
Definition: Archive.h:339
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:596
llvm::object::Binary::getFileName
StringRef getFileName() const
Definition: Binary.cpp:41
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:659
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::NewArchiveMember::getOldMember
static Expected< NewArchiveMember > getOldMember(const object::Archive::Child &OldMember, bool Deterministic)
Definition: ArchiveWriter.cpp:85