29 #if !defined(_MSC_VER) && !defined(__MINGW32__)
39 : IsNewMember(
false), Name(Name), OldI(I) {}
42 : IsNewMember(
true), Name(Name), NewFilename(NewFilename) {}
80 bool MayTruncate =
false) {
81 uint64_t OldPos = OS.
tell();
83 unsigned SizeSoFar = OS.
tell() - OldPos;
84 if (Size > SizeSoFar) {
85 OS.
indent(Size - SizeSoFar);
86 }
else if (Size < SizeSoFar) {
87 assert(MayTruncate &&
"Data doesn't fit in Size");
90 OS.
seek(OldPos + Size);
104 unsigned GID,
unsigned Perms,
116 unsigned UID,
unsigned GID,
117 unsigned Perms,
unsigned Size) {
124 unsigned GID,
unsigned Perms,
unsigned Size) {
125 uint64_t PosAfterHeader = Out.
tell() + 60 + Name.
size();
128 unsigned NameWithPadding = Name.
size() + Pad;
131 NameWithPadding + Size);
133 assert(PosAfterHeader == Out.
tell());
135 Out.
write(uint8_t(0));
141 std::vector<unsigned>::iterator &StringMapIndexIter,
143 unsigned Perms,
unsigned Size) {
146 if (Name.
size() < 16)
155 std::vector<unsigned> &StringMapIndexes) {
156 unsigned StartOffset = 0;
161 if (Name.
size() < 16)
163 if (StartOffset == 0) {
166 StartOffset = Out.
tell();
168 StringMapIndexes.push_back(Out.
tell() - StartOffset);
169 Out << Name <<
"/\n";
171 if (StartOffset == 0)
175 int Pos = Out.
tell();
176 Out.
seek(StartOffset - 12);
194 std::vector<unsigned> &MemberOffsetRefs,
bool Deterministic) {
195 unsigned HeaderStartOffset = 0;
196 unsigned BodyStartOffset = 0;
200 for (
unsigned MemberNum = 0,
N = Members.
size(); MemberNum <
N; ++MemberNum) {
209 if (!HeaderStartOffset) {
210 HeaderStartOffset = Out.
tell();
215 BodyStartOffset = Out.
tell();
220 uint32_t Symflags = S.getFlags();
228 unsigned NameOffset = NameOS.
tell();
229 if (
auto EC = S.printName(NameOS))
232 MemberOffsetRefs.push_back(MemberNum);
234 print32(Out, Kind, NameOffset);
239 if (HeaderStartOffset == 0)
251 Out.
write(uint8_t(0));
254 unsigned Pos = Out.
tell();
255 const unsigned MemberHeaderSize = 60;
256 Out.
seek(HeaderStartOffset + 48);
260 Out.
seek(BodyStartOffset);
261 unsigned NumSyms = MemberOffsetRefs.size();
265 print32(Out, Kind, NumSyms * 8);
268 return BodyStartOffset + 4;
272 StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers,
277 TmpArchiveFD, TmpArchive))
278 return std::make_pair(ArcName, EC);
284 std::vector<unsigned> MemberOffsetRefs;
286 std::vector<std::unique_ptr<MemoryBuffer>> Buffers;
287 std::vector<MemoryBufferRef> Members;
288 std::vector<sys::fs::file_status> NewMemberStatus;
290 for (
unsigned I = 0,
N = NewMembers.size();
I <
N; ++
I) {
296 NewMemberStatus.resize(NewMemberStatus.size() + 1);
300 return std::make_pair(Filename, EC);
304 if (
auto EC = MemberBufferOrErr.
getError())
305 return std::make_pair(Filename, EC);
306 if (close(FD.
get()) != 0)
307 return std::make_pair(Filename,
308 std::error_code(errno, std::generic_category()));
309 Buffers.push_back(std::move(MemberBufferOrErr.
get()));
310 MemberRef = Buffers.back()->getMemBufferRef();
315 if (
auto EC = MemberBufferOrErr.
getError())
316 return std::make_pair(
"", EC);
317 MemberRef = MemberBufferOrErr.
get();
319 Members.push_back(MemberRef);
322 unsigned MemberReferenceOffset = 0;
325 Out, Kind, NewMembers, Members, MemberOffsetRefs, Deterministic);
326 if (
auto EC = MemberReferenceOffsetOrErr.
getError())
327 return std::make_pair(ArcName, EC);
328 MemberReferenceOffset = MemberReferenceOffsetOrErr.
get();
331 std::vector<unsigned> StringMapIndexes;
335 unsigned MemberNum = 0;
336 unsigned NewMemberNum = 0;
337 std::vector<unsigned>::iterator StringMapIndexIter = StringMapIndexes.begin();
338 std::vector<unsigned> MemberOffset;
342 unsigned Pos = Out.
tell();
343 MemberOffset.push_back(Pos);
354 }
else if (
I.isNewMember()) {
357 UID = Status.getUser();
358 GID = Status.getGroup();
363 UID = OldMember->
getUID();
364 GID = OldMember->
getGID();
368 if (
I.isNewMember()) {
372 StringMapIndexIter, ModTime, UID, GID, Perms,
377 UID, GID, Perms, OldMember->
getSize());
386 if (MemberReferenceOffset) {
387 Out.
seek(MemberReferenceOffset);
388 for (
unsigned MemberNum : MemberOffsetRefs) {
391 print32(Out, Kind, MemberOffset[MemberNum]);
398 return std::make_pair(
"", std::error_code());
std::pair< StringRef, std::error_code > writeArchive(StringRef ArcName, std::vector< NewArchiveIterator > &NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic)
std::error_code getError() const
static ErrorOr< unsigned > writeSymbolTable(raw_fd_ostream &Out, object::Archive::Kind Kind, ArrayRef< NewArchiveIterator > Members, ArrayRef< MemoryBufferRef > Buffers, std::vector< unsigned > &MemberOffsetRefs, bool Deterministic)
Represents either an error or a value T.
static TimeValue now()
This is a static constructor that returns a TimeValue that represents the current time...
size_t size() const
size - Get the string size.
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, unsigned Mode=all_read|all_write)
Create a uniquely named file.
uint64_t seek(uint64_t off)
Flushes the stream and repositions the underlying file descriptor position to the offset specified fr...
llvm::ErrorOr< int > getFD(sys::fs::file_status &NewStatus) const
static void printBSDMemberHeader(raw_fd_ostream &Out, StringRef Name, const sys::TimeValue &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
sys::fs::perms getAccessMode() const
A raw_ostream that writes to an SmallVector or SmallString.
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.
static ErrorOr< std::unique_ptr< SymbolicFile > > createSymbolicFile(MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context)
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)
static void printMemberHeader(raw_fd_ostream &Out, object::Archive::Kind Kind, StringRef Name, std::vector< unsigned >::iterator &StringMapIndexIter, const sys::TimeValue &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
sys::TimeValue getLastModified() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
ErrorOr< MemoryBufferRef > getMemoryBufferRef() const
object::Archive::child_iterator getOld() const
std::error_code make_error_code(BitcodeError E)
NewArchiveIterator(object::Archive::child_iterator I, StringRef Name)
uint64_t tell() const
tell - Return the current offset with the file.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
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.
StringRef filename(StringRef path)
Get filename.
StringRef getName() const
uint64_t toEpochTime() const
Converts the TimeValue into the corresponding number of seconds since the epoch (00:00:00 Jan 1...
This is an important class for using LLVM in a threaded context.
perms permissions() const
raw_ostream & write(unsigned char C)
std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
StringRef getBuffer() const
static void printGNUSmallMemberHeader(raw_fd_ostream &Out, StringRef Name, const sys::TimeValue &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
void fromEpochTime(SecondsType seconds)
Converts the seconds argument from PosixTime to the corresponding TimeValue and assigns that value to...
basic_symbol_iterator_range symbols() const
void write(void *memory, value_type value)
Write a value to memory with a particular endianness.
StringRef str()
Flushes the stream contents to the target vector and return a StringRef for the vector contents...
Adapter to write values to a stream in a particular byte order.
A raw_ostream that writes to a file descriptor.
std::error_code openFileForRead(const Twine &Name, int &ResultFD)
This is a value type class that represents a single symbol in the list of symbols in the object file...
void close()
Manually flush the stream and close the file.
const ARM::ArchExtKind Kind
static void printWithSpacePadding(raw_fd_ostream &OS, T Data, unsigned Size, bool MayTruncate=false)
This class is used where a precise fixed point in time is required.
TimeValue getLastModificationTime() const
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...
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.
static void printRestOfMemberHeader(raw_fd_ostream &Out, const sys::TimeValue &ModTime, unsigned UID, unsigned GID, unsigned Perms, unsigned Size)
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
static sys::TimeValue now(bool Deterministic)
static void writeStringTable(raw_fd_ostream &Out, ArrayRef< NewArchiveIterator > Members, std::vector< unsigned > &StringMapIndexes)