29 #if !defined(_MSC_VER) && !defined(__MINGW32__)
53 return ModTimeOrErr.takeError();
90 if (!MemberBufferOrErr)
98 M.
Buf = std::move(*MemberBufferOrErr);
100 M.
ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
102 M.
UID = Status.getUser();
103 M.
GID = Status.getGroup();
109 template <
typename T>
111 bool MayTruncate =
false) {
112 uint64_t OldPos = OS.
tell();
114 unsigned SizeSoFar = OS.
tell() - OldPos;
115 if (Size > SizeSoFar) {
116 OS.
indent(Size - SizeSoFar);
117 }
else if (Size < SizeSoFar) {
118 assert(MayTruncate &&
"Data doesn't fit in Size");
121 OS.
seek(OldPos + Size);
135 unsigned UID,
unsigned GID,
unsigned Perms,
unsigned Size) {
147 unsigned UID,
unsigned GID,
unsigned Perms,
156 unsigned UID,
unsigned GID,
unsigned Perms,
158 uint64_t PosAfterHeader = Out.
tell() + 60 + Name.
size();
161 unsigned NameWithPadding = Name.
size() + Pad;
164 NameWithPadding + Size);
168 Out.
write(uint8_t(0));
172 return Thin || Name.
size() >= 16;
178 std::vector<unsigned>::iterator &StringMapIndexIter,
180 unsigned UID,
unsigned GID,
unsigned Perms,
unsigned Size) {
198 while (*FromI == *ToI) {
204 for (
auto FromE =
sys::path::end(DirFrom); FromI != FromE; ++FromI)
213 std::replace(Relative.
begin(), Relative.
end(),
'\\',
'/');
216 return Relative.
str();
221 std::vector<unsigned> &StringMapIndexes,
223 unsigned StartOffset = 0;
225 StringRef Path = M.Buf->getBufferIdentifier();
229 if (StartOffset == 0) {
232 StartOffset = Out.
tell();
234 StringMapIndexes.push_back(Out.
tell() - StartOffset);
240 Out << M.Buf->getBufferIdentifier();
246 if (StartOffset == 0)
250 int Pos = Out.
tell();
251 Out.
seek(StartOffset - 12);
257 using namespace std::chrono;
268 std::vector<unsigned> &MemberOffsetRefs,
bool Deterministic) {
269 unsigned HeaderStartOffset = 0;
270 unsigned BodyStartOffset = 0;
274 for (
unsigned MemberNum = 0,
N = Members.
size(); MemberNum <
N; ++MemberNum) {
275 MemoryBufferRef MemberBuffer = Members[MemberNum].Buf->getMemBufferRef();
286 if (!HeaderStartOffset) {
287 HeaderStartOffset = Out.
tell();
292 BodyStartOffset = Out.
tell();
305 unsigned NameOffset = NameOS.
tell();
306 if (
auto EC = S.printName(NameOS))
309 MemberOffsetRefs.push_back(MemberNum);
311 print32(Out, Kind, NameOffset);
316 if (HeaderStartOffset == 0)
328 Out.
write(uint8_t(0));
331 unsigned Pos = Out.
tell();
332 const unsigned MemberHeaderSize = 60;
333 Out.
seek(HeaderStartOffset + 48);
337 Out.
seek(BodyStartOffset);
338 unsigned NumSyms = MemberOffsetRefs.size();
342 print32(Out, Kind, NumSyms * 8);
345 return BodyStartOffset + 4;
348 std::pair<StringRef, std::error_code>
350 std::vector<NewArchiveMember> &NewMembers,
352 bool Deterministic,
bool Thin,
353 std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
355 "Only the gnu format has a thin mode");
359 TmpArchiveFD, TmpArchive))
360 return std::make_pair(ArcName, EC);
369 std::vector<unsigned> MemberOffsetRefs;
371 std::vector<std::unique_ptr<MemoryBuffer>> Buffers;
372 std::vector<MemoryBufferRef> Members;
373 std::vector<sys::fs::file_status> NewMemberStatus;
375 unsigned MemberReferenceOffset = 0;
378 Out, Kind, NewMembers, MemberOffsetRefs, Deterministic);
379 if (
auto EC = MemberReferenceOffsetOrErr.
getError())
380 return std::make_pair(ArcName, EC);
381 MemberReferenceOffset = MemberReferenceOffsetOrErr.
get();
384 std::vector<unsigned> StringMapIndexes;
388 std::vector<unsigned>::iterator StringMapIndexIter = StringMapIndexes.begin();
389 std::vector<unsigned> MemberOffset;
393 unsigned Pos = Out.
tell();
394 MemberOffset.push_back(Pos);
398 StringMapIndexIter, M.ModTime, M.UID, M.GID, M.Perms,
399 M.Buf->getBufferSize());
408 if (MemberReferenceOffset) {
409 Out.
seek(MemberReferenceOffset);
410 for (
unsigned MemberNum : MemberOffsetRefs) {
413 print32(Out, Kind, MemberOffset[MemberNum]);
430 OldArchiveBuf.reset();
433 return std::make_pair(
"", std::error_code());
const_iterator end(StringRef path)
Get end iterator over path.
std::error_code getError() const
Represents either an error or a value T.
LLVM_ATTRIBUTE_ALWAYS_INLINE std::time_t toTimeT(TimePoint<> TP)
Convert a TimePoint to std::time_t.
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, unsigned Mode=all_read|all_write)
Create a uniquely named file.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, SmallVectorImpl< char > *RealPath=nullptr)
static void printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, bool Thin, StringRef Name, std::vector< unsigned >::iterator &StringMapIndexIter, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
Expected< unsigned > getGID() const
uint64_t seek(uint64_t off)
Flushes the stream and repositions the underlying file descriptor position to the offset specified fr...
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an SmallVector or SmallString.
const_iterator begin(StringRef path)
Get begin iterator over path.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(int FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatileSize=false)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
Error takeError()
Take ownership of the stored error.
file_status - Represents the result of a call to stat and friends.
static void print32(raw_ostream &Out, object::Archive::Kind Kind, uint32_t Val)
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
static void printBSDMemberHeader(raw_fd_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
std::pair< StringRef, std::error_code > writeArchive(StringRef ArcName, std::vector< NewArchiveMember > &NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
std::error_code make_error_code(BitcodeError E)
bool is_absolute(const Twine &path)
Is path absolute?
Tagged union holding either a T or a Error.
uint64_t tell() const
tell - Return the current offset with the file.
static ErrorOr< unsigned > writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind, ArrayRef< NewArchiveMember > Members, std::vector< unsigned > &MemberOffsetRefs, bool Deterministic)
Function Alias Analysis false
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
size_t size() const
size - Get the array size.
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Expected< sys::fs::perms > getAccessMode() const
StringRef filename(StringRef path)
Get filename.
static void printRestOfMemberHeader(raw_fd_ostream &Out, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
Expected< unsigned > getUID() const
This is an important class for using LLVM in a threaded context.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
perms permissions() const
static void write(bool isBE, void *P, T V)
void consumeError(Error Err)
Consume a Error without doing anything.
raw_ostream & write(unsigned char C)
std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
StringRef getBuffer() const
static bool useStringTable(bool Thin, StringRef Name)
StringRef str()
Return a StringRef for the vector contents.
reference get()
Returns a reference to the stored T value.
static Expected< NewArchiveMember > getOldMember(const object::Archive::Child &OldMember, bool Deterministic)
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
StringRef parent_path(StringRef path)
Get parent path.
StringRef str() const
Explicit conversion to StringRef.
basic_symbol_iterator_range symbols() const
Adapter to write values to a stream in a particular byte order.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
A raw_ostream that writes to a file descriptor.
static void printGNUSmallMemberHeader(raw_fd_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName, ArrayRef< NewArchiveMember > Members, std::vector< unsigned > &StringMapIndexes, bool Thin)
This is a value type class that represents a single symbol in the list of symbols in the object file...
TimePoint getLastModificationTime() const
static Expected< NewArchiveMember > getFile(StringRef FileName, bool Deterministic)
void close()
Manually flush the stream and close the file.
static std::string computeRelativePath(StringRef From, StringRef To)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void printWithSpacePadding(raw_fd_ostream &OS, T Data, unsigned Size, bool MayTruncate=false)
uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
NewArchiveMember()=default
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
std::unique_ptr< MemoryBuffer > Buf
static Expected< std::unique_ptr< SymbolicFile > > createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context)
sys::TimePoint< std::chrono::seconds > ModTime
Expected< MemoryBufferRef > getMemoryBufferRef() const
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.