Go to the documentation of this file.
38 #if !defined(_MSC_VER) && !defined(__MINGW32__)
48 MemberName(BufRef.getBufferIdentifier()) {}
51 auto MemBufferRef = this->
Buf->getMemBufferRef();
56 return isa<object::MachOObjectFile>(**OptionalObject)
58 : (isa<object::XCOFFObjectFile>(**OptionalObject)
71 auto &IRObject = cast<object::IRObjectFile>(**ObjOrErr);
93 M.MemberName =
M.Buf->getBufferIdentifier();
97 return ModTimeOrErr.takeError();
98 M.ModTime = ModTimeOrErr.get();
102 M.UID = UIDOrErr.
get();
106 M.GID = GIDOrErr.
get();
108 if (!AccessModeOrErr)
110 M.Perms = AccessModeOrErr.
get();
116 bool Deterministic) {
120 return FDOrErr.takeError();
135 if (!MemberBufferOrErr)
143 M.MemberName =
M.Buf->getBufferIdentifier();
144 if (!Deterministic) {
145 M.ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
146 Status.getLastModificationTime());
149 M.Perms =
Status.permissions();
154 template <
typename T>
158 unsigned SizeSoFar = OS.
tell() - OldPos;
159 assert(SizeSoFar <= Size &&
"Data doesn't fit in Size");
160 OS.
indent(Size - SizeSoFar);
196 unsigned UID,
unsigned GID,
unsigned Perms,
uint64_t Size) {
212 unsigned UID,
unsigned GID,
unsigned Perms,
221 unsigned UID,
unsigned GID,
unsigned Perms,
uint64_t Size) {
222 uint64_t PosAfterHeader = Pos + 60 + Name.size();
225 unsigned NameWithPadding = Name.size() + Pad;
228 NameWithPadding + Size);
231 Out.
write(uint8_t(0));
237 unsigned UID,
unsigned GID,
unsigned Perms,
239 unsigned NextOffset) {
240 unsigned NameLen = Name.size();
254 Out.
write(uint8_t(0));
260 return Thin || Name.size() >= 16 || Name.contains(
'/');
292 NamePos = StringTable.tell();
293 StringTable <<
M.MemberName <<
"/\n";
296 if (Insertion.second) {
297 Insertion.first->second = StringTable.tell();
298 StringTable <<
M.MemberName <<
"/\n";
300 NamePos = Insertion.first->second;
308 std::vector<unsigned> Symbols;
316 unsigned Size = Names.
size();
324 return {{},
std::move(Header), Names, Pad ?
"\n" :
""};
328 using namespace std::chrono;
352 print<uint64_t>(Out, Kind, Val);
354 print<uint32_t>(Out, Kind, Val);
361 assert((OffsetSize == 4 || OffsetSize == 8) &&
"Unsupported OffsetSize");
364 Size += NumSyms * OffsetSize * 2;
366 Size += NumSyms * OffsetSize;
369 Size += StringTable.size();
389 const char *Name =
is64BitKind(Kind) ?
"__.SYMDEF_64" :
"__.SYMDEF";
394 0, Size, PrevMemberOffset, 0);
396 const char *Name =
is64BitKind(Kind) ?
"/SYM64" :
"";
407 if (StringTable.empty() && !
isDarwin(Kind))
410 unsigned NumSyms = 0;
411 for (
const MemberData &
M : Members)
412 NumSyms +=
M.Symbols.size();
423 printNBits(Out, Kind, NumSyms * 2 * OffsetSize);
427 for (
const MemberData &
M : Members) {
428 for (
unsigned StringOffset :
M.Symbols) {
433 Pos +=
M.Header.size() +
M.Data.size() +
M.Padding.size();
442 Out.
write(uint8_t(0));
447 std::vector<unsigned>
Ret;
452 std::unique_ptr<object::SymbolicFile> Obj;
462 return ObjOrErr.takeError();
467 return ObjOrErr.takeError();
475 Ret.push_back(SymNames.
tell());
476 if (
Error E =
S.printName(SymNames))
487 static char PaddingData[8] = {
'\n',
'\n',
'\n',
'\n',
'\n',
'\n',
'\n',
'\n'};
492 std::vector<MemberData>
Ret;
493 bool HasObject =
false;
541 bool UniqueTimestamps = Deterministic &&
isDarwin(Kind);
542 std::map<StringRef, unsigned> FilenameCount;
543 if (UniqueTimestamps) {
545 FilenameCount[
M.MemberName]++;
546 for (
auto &Entry : FilenameCount)
547 Entry.second = Entry.second > 1 ? 1 : 0;
552 unsigned PrevOffset = 0;
564 unsigned MemberPadding =
566 unsigned TailPadding =
571 if (UniqueTimestamps)
579 std::string StringMsg =
580 "File " +
M.MemberName.str() +
" exceeds size limit";
581 return make_error<object::GenericBinaryError>(
589 M.Perms, Size, PrevOffset, NextOffset);
597 std::vector<unsigned> Symbols;
606 Pos += Header.size() +
Data.size() + Padding.size();
612 if (HasObject && SymNames.
tell() == 0)
613 SymNames <<
'\0' <<
'\0' <<
'\0';
632 if (!PathToOrErr || !DirFromOrErr)
646 auto FromI = FromTo.first;
647 auto ToI = FromTo.second;
651 for (
auto FromE =
sys::path::end(DirFrom); FromI != FromE; ++FromI)
657 return std::string(Relative.
str());
663 bool Deterministic,
bool Thin) {
664 assert((!Thin || !
isBSDLike(Kind)) &&
"Only the gnu format has a thin mode");
673 WriteSymtab, NewMembers);
676 std::vector<MemberData> &
Data = *DataOrErr;
684 uint64_t LastMemberHeaderOffset = LastMemberEndOffset;
686 for (
const auto &
M :
Data) {
688 LastMemberHeaderOffset = LastMemberEndOffset;
690 LastMemberEndOffset +=
M.Header.size() +
M.Data.size() +
M.Padding.size();
691 NumSyms +=
M.Symbols.size();
699 auto computeSymbolTableHeaderSize =
704 return TmpBuf.size();
706 LastMemberHeaderOffset += computeSymbolTableHeaderSize() + SymtabSize;
715 uint64_t Sym64Threshold = 1ULL << 32;
716 const char *Sym64Env = std::getenv(
"SYM64_THRESHOLD");
723 if (LastMemberHeaderOffset >= Sym64Threshold) {
741 for (
const MemberData &
M :
Data)
742 Out <<
M.Header <<
M.Data <<
M.Padding;
746 uint64_t MemberTableNameStrTblSize = 0;
747 std::vector<size_t> MemberOffsets;
748 std::vector<StringRef> MemberNames;
751 for (
size_t I = 0, Size = NewMembers.
size();
I != Size; ++
I) {
753 MemberTableNameStrTblSize += Member.MemberName.size() + 1;
754 MemberOffsets.push_back(MemberEndOffset);
755 MemberNames.push_back(Member.MemberName);
760 alignTo(Member.MemberName.size(), 2);
764 unsigned MemberTableSize = 20 +
765 20 * MemberOffsets.size() +
766 MemberTableNameStrTblSize;
768 unsigned GlobalSymbolOffset =
769 (WriteSymtab && NumSyms > 0)
770 ? LastMemberEndOffset +
792 for (
const MemberData &
M :
Data) {
793 Out <<
M.Header <<
M.Data;
794 if (
M.Data.size() % 2)
798 if (NewMembers.
size()) {
801 MemberTableSize, LastMemberHeaderOffset,
804 for (
uint64_t MemberOffset : MemberOffsets)
808 Out << MemberName <<
'\0';
810 if (MemberTableNameStrTblSize % 2)
814 if (WriteSymtab && NumSyms > 0)
816 LastMemberEndOffset);
825 bool Deterministic,
bool Thin,
826 std::unique_ptr<MemoryBuffer> OldArchiveBuf) {
834 Deterministic, Thin)) {
835 if (
Error DiscardError = Temp->discard())
850 OldArchiveBuf.reset();
852 return Temp->keep(ArcName);
863 Kind, Deterministic, Thin))
866 return std::make_unique<SmallVectorMemoryBuffer>(
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
uint64_t tell() const
tell - Return the current offset with the file.
static bool isDarwin(object::Archive::Kind Kind)
This is an optimization pass for GlobalISel generic memory operations.
static Expected< NewArchiveMember > getFile(StringRef FileName, bool Deterministic)
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
static void printRestOfMemberHeader(raw_ostream &Out, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)
static void printWithSpacePadding(raw_ostream &OS, T Data, unsigned Size)
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
A raw_ostream that writes to an std::string.
std::unique_ptr< MemoryBuffer > Buf
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
static ErrorSuccess success()
Create a success value.
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
size_t getBufferSize() const
Expected< unsigned > getGID() const
Tagged union holding either a T or a Error.
static MemberData computeStringTable(StringRef Names)
void consumeError(Error Err)
Consume a Error without doing anything.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
static bool isBSDLike(object::Archive::Kind Kind)
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isOSDarwin() const
Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or DriverKit).
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
This is a value type class that represents a single symbol in the list of symbols in the object file.
static const uint64_t MaxMemberSize
Size field is 10 decimal digits long.
Error writeArchive(StringRef ArcName, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin, std::unique_ptr< MemoryBuffer > OldArchiveBuf=nullptr)
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
static void printBigArchiveMemberHeader(raw_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size, unsigned PrevOffset, unsigned NextOffset)
static bool useStringTable(bool Thin, StringRef Name)
std::error_code getError() const
raw_ostream & write(unsigned char C)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class implements an extremely fast bulk output stream that can only output to a stream.
Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
Expected< sys::TimePoint< std::chrono::seconds > > getLastModified() const
static bool isArchiveSymbol(const object::BasicSymbolRef &S)
This struct is a compact representation of a valid (non-zero power of two) alignment.
static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, uint64_t Size, uint64_t PrevMemberOffset=0)
object::Archive::Kind detectKindFromObject() const
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Expected< unsigned > getUID() const
static bool isSymbolicFile(file_magic Type, const LLVMContext *Context)
Represents the result of a call to sys::fs::status().
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
NewArchiveMember()=default
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
This is an important class for using LLVM in a threaded context.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Expected< sys::fs::perms > getAccessMode() const
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
static ErrorOr< SmallString< 128 > > canonicalizePath(StringRef P)
std::error_code closeFile(file_t &F)
Close the file object.
StringRef getBuffer() const
void make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
const file_t kInvalidFile
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
Expected< std::string > computeArchiveRelativePath(StringRef From, StringRef To)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
StringRef - Represent a constant reference to a string, i.e.
static bool isAIXBigArchive(object::Archive::Kind Kind)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void printGNUSmallMemberHeader(raw_ostream &Out, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)
reference get()
Returns a reference to the stored T value.
static void printMemberHeader(raw_ostream &Out, uint64_t Pos, raw_ostream &StringTable, StringMap< uint64_t > &MemberNames, object::Archive::Kind Kind, bool Thin, const NewArchiveMember &M, sys::TimePoint< std::chrono::seconds > ModTime, uint64_t Size)
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
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
A raw_ostream that writes to a file descriptor.
std::error_code make_error_code(BitcodeError E)
static bool is64BitKind(object::Archive::Kind Kind)
constexpr size_t size() const
size - Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
StringRef root_name(StringRef path, Style style=Style::native)
Get root name.
std::time_t toTimeT(TimePoint<> TP)
Convert a TimePoint to std::time_t.
static Error writeArchiveToStream(raw_ostream &Out, ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin)
Lightweight error class with error context and mandatory checking.
static Expected< std::unique_ptr< SymbolicFile > > createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type, LLVMContext *Context, bool InitContent=true)
static Expected< std::vector< unsigned > > getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject)
StringRef str() const
Explicit conversion to StringRef.
Error takeError()
Take ownership of the stored error.
static object::Archive::Kind getDefaultKindForHost()
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
static uint64_t computeSymbolTableSize(object::Archive::Kind Kind, uint64_t NumSyms, uint64_t OffsetSize, StringRef StringTable, uint32_t *Padding=nullptr)
TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)
Convert a std::time_t to a TimePoint.
Represents either an error or a value T.
size_t size() const
size - Get the array size.
A raw_ostream that writes to an SmallVector or SmallString.
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind, bool Deterministic, ArrayRef< MemberData > Members, StringRef StringTable, uint64_t PrevMemberOffset=0)
static Expected< std::vector< MemberData > > computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, object::Archive::Kind Kind, bool Thin, bool Deterministic, bool NeedSymbols, ArrayRef< NewArchiveMember > NewMembers)
Expected< MemoryBufferRef > getMemoryBufferRef() const
BlockVerifier::State From
static Expected< TempFile > create(const Twine &Model, unsigned Mode=all_read|all_write, OpenFlags ExtraFlags=OF_None)
This creates a temporary file with createUniqueFile and schedules it for deletion with sys::RemoveFil...
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
static Expected< NewArchiveMember > getOldMember(const object::Archive::Child &OldMember, bool Deterministic)
static void printNBits(raw_ostream &Out, object::Archive::Kind Kind, uint64_t Val)
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
static void printBSDMemberHeader(raw_ostream &Out, uint64_t Pos, StringRef Name, const sys::TimePoint< std::chrono::seconds > &ModTime, unsigned UID, unsigned GID, unsigned Perms, uint64_t Size)
Expected< std::unique_ptr< MemoryBuffer > > writeArchiveToBuffer(ArrayRef< NewArchiveMember > NewMembers, bool WriteSymtab, object::Archive::Kind Kind, bool Deterministic, bool Thin)