LLVM 23.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"
13#include "llvm/Object/Error.h"
16
17using namespace llvm;
18using namespace llvm::objcopy;
19using namespace llvm::object;
20
23 const Archive &Ar) {
24 std::vector<NewArchiveMember> NewArchiveMembers;
25 Error Err = Error::success();
26 for (const Archive::Child &Child : Ar.children(Err)) {
27 Expected<StringRef> ChildNameOrErr = Child.getName();
28 if (!ChildNameOrErr)
29 return createFileError(Ar.getFileName(), ChildNameOrErr.takeError());
30
31 auto MemberName = [&](StringRef Prefix) {
32 return (Twine(Prefix) + "(" + *ChildNameOrErr + ")").str();
33 };
34
35 Expected<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
36 if (!ChildOrErr)
37 return createFileError(MemberName(Ar.getFileName()),
38 ChildOrErr.takeError());
39
40 const CommonConfig &CC = Config.getCommonConfig();
41 if (CC.Verbose) {
42 StringRef FormatName = getObjectFormatName(*ChildOrErr->get());
43 printCopyMessage(MemberName(Ar.getFileName()), FormatName,
44 MemberName(CC.OutputFilename), FormatName);
45 }
46
48 raw_svector_ostream MemStream(Buffer);
49
50 if (Error E = executeObjcopyOnBinary(Config, *ChildOrErr->get(), MemStream))
51 return std::move(E);
52
55 if (!Member)
56 return createFileError(Ar.getFileName(), Member.takeError());
57
58 Member->Buf = std::make_unique<SmallVectorMemoryBuffer>(
59 std::move(Buffer), ChildNameOrErr.get());
60 Member->MemberName = Member->Buf->getBufferIdentifier();
61 NewArchiveMembers.push_back(std::move(*Member));
62 }
63 if (Err)
65 std::move(Err));
66 return std::move(NewArchiveMembers);
67}
68
69// For regular archives this function simply calls llvm::writeArchive,
70// For thin archives it writes the archive file itself as well as its members.
73 SymtabWritingMode WriteSymtab,
74 object::Archive::Kind Kind, bool Deterministic,
75 bool Thin) {
76 if (Kind == object::Archive::K_BSD && !NewMembers.empty() &&
77 NewMembers.front().detectKindFromObject() == object::Archive::K_DARWIN)
79
80 if (Error E = writeArchive(ArcName, NewMembers, WriteSymtab, Kind,
81 Deterministic, Thin))
82 return createFileError(ArcName, std::move(E));
83
84 if (!Thin)
85 return Error::success();
86
87 for (const NewArchiveMember &Member : NewMembers) {
88 // For regular files (as is the case for deepWriteArchive),
89 // FileOutputBuffer::create will return OnDiskBuffer.
90 // OnDiskBuffer uses a temporary file and then renames it. So in reality
91 // there is no inefficiency / duplicated in-memory buffers in this case. For
92 // now in-memory buffers can not be completely avoided since
93 // NewArchiveMember still requires them even though writeArchive does not
94 // write them on disk.
96 FileOutputBuffer::create(Member.MemberName, Member.Buf->getBufferSize(),
98 if (!FB)
99 return FB.takeError();
100 std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(),
101 (*FB)->getBufferStart());
102 if (Error E = (*FB)->commit())
103 return E;
104 }
105 return Error::success();
106}
107
109 const object::Archive &Ar) {
110 Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
111 createNewArchiveMembers(Config, Ar);
112 if (!NewArchiveMembersOrErr)
113 return NewArchiveMembersOrErr.takeError();
114 const CommonConfig &CommonConfig = Config.getCommonConfig();
115 return deepWriteArchive(CommonConfig.OutputFilename, *NewArchiveMembersOrErr,
119 Ar.isThin());
120}
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error deepWriteArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin)
Definition Archive.cpp:71
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
static LLVM_ABI 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...
@ F_executable
Set the 'x' bit on the resulting file.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
virtual const CommonConfig & getCommonConfig() const =0
bool isThin() const
Definition Archive.h:398
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition Archive.h:404
bool hasSymbolTable() const
Definition Archive.cpp:1430
Kind kind() const
Definition Archive.h:397
StringRef getFileName() const
Definition Binary.cpp:41
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI StringRef getObjectFormatName(const object::Binary &B)
Returns the format name of B if it is an ObjectFile, or "" otherwise.
Definition ObjCopy.cpp:35
LLVM_ABI void printCopyMessage(StringRef InPath, StringRef InFormatName, StringRef OutPath, StringRef OutFormatName)
Prints information about the input and output files involved in a copy operation to stdout.
Definition ObjCopy.cpp:41
LLVM_ABI 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:51
LLVM_ABI Error executeObjcopyOnArchive(const MultiFormatConfig &Config, const object::Archive &Ar)
Applies the transformations described by Config to each member in archive Ar.
Definition Archive.cpp:108
Expected< std::vector< NewArchiveMember > > createNewArchiveMembers(const MultiFormatConfig &Config, const object::Archive &Ar)
Applies the transformations described by Config to each member in archive Ar.
Definition Archive.cpp:22
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.
Definition Error.h:1415
LLVM_ABI Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, SymtabWritingMode WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr, std::optional< bool > IsEC=std::nullopt, function_ref< void(Error)> Warn=warnToStderr)
SymtabWritingMode
static LLVM_ABI Expected< NewArchiveMember > getOldMember(const object::Archive::Child &OldMember, bool Deterministic)