#include "llvm/Object/ArchiveWriter.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Object/XCOFFObjectFile.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SmallVectorMemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <cerrno>
#include <map>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
#else
#include <io.h>
#endif
usingnamespacellvm;
usingnamespacellvm::object;
struct SymMap { … };
NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
: … { … }
object::Archive::Kind NewArchiveMember::detectKindFromObject() const { … }
Expected<NewArchiveMember>
NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
bool Deterministic) { … }
Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName,
bool Deterministic) { … }
template <typename T>
static void printWithSpacePadding(raw_ostream &OS, T Data, unsigned Size) { … }
static bool isDarwin(object::Archive::Kind Kind) { … }
static bool isAIXBigArchive(object::Archive::Kind Kind) { … }
static bool isCOFFArchive(object::Archive::Kind Kind) { … }
static bool isBSDLike(object::Archive::Kind Kind) { … }
template <class T>
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val) { … }
template <class T> static void printLE(raw_ostream &Out, T Val) { … }
static void printRestOfMemberHeader(
raw_ostream &Out, const sys::TimePoint<std::chrono::seconds> &ModTime,
unsigned UID, unsigned GID, unsigned Perms, uint64_t Size) { … }
static void
printGNUSmallMemberHeader(raw_ostream &Out, StringRef Name,
const sys::TimePoint<std::chrono::seconds> &ModTime,
unsigned UID, unsigned GID, unsigned Perms,
uint64_t Size) { … }
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) { … }
static void
printBigArchiveMemberHeader(raw_ostream &Out, StringRef Name,
const sys::TimePoint<std::chrono::seconds> &ModTime,
unsigned UID, unsigned GID, unsigned Perms,
uint64_t Size, uint64_t PrevOffset,
uint64_t NextOffset) { … }
static bool useStringTable(bool Thin, StringRef Name) { … }
static bool is64BitKind(object::Archive::Kind Kind) { … }
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) { … }
namespace {
struct MemberData { … };
}
static MemberData computeStringTable(StringRef Names) { … }
static sys::TimePoint<std::chrono::seconds> now(bool Deterministic) { … }
static bool isArchiveSymbol(const object::BasicSymbolRef &S) { … }
static void printNBits(raw_ostream &Out, object::Archive::Kind Kind,
uint64_t Val) { … }
static uint64_t computeSymbolTableSize(object::Archive::Kind Kind,
uint64_t NumSyms, uint64_t OffsetSize,
uint64_t StringTableSize,
uint32_t *Padding = nullptr) { … }
static uint64_t computeSymbolMapSize(uint64_t NumObj, SymMap &SymMap,
uint32_t *Padding = nullptr) { … }
static uint64_t computeECSymbolsSize(SymMap &SymMap,
uint32_t *Padding = nullptr) { … }
static void writeSymbolTableHeader(raw_ostream &Out, object::Archive::Kind Kind,
bool Deterministic, uint64_t Size,
uint64_t PrevMemberOffset = 0,
uint64_t NextMemberOffset = 0) { … }
static uint64_t computeHeadersSize(object::Archive::Kind Kind,
uint64_t NumMembers,
uint64_t StringMemberSize, uint64_t NumSyms,
uint64_t SymNamesSize, SymMap *SymMap) { … }
static Expected<std::unique_ptr<SymbolicFile>>
getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context,
object::Archive::Kind Kind, function_ref<void(Error)> Warn) { … }
static bool is64BitSymbolicFile(const SymbolicFile *SymObj) { … }
static const uint32_t Log2OfAIXPageSize = …;
static const uint32_t MinBigArchiveMemDataAlign = …;
template <typename AuxiliaryHeader>
uint16_t getAuxMaxAlignment(uint16_t AuxHeaderSize, AuxiliaryHeader *AuxHeader,
uint16_t Log2OfMaxAlign) { … }
static uint32_t getMemberAlignment(SymbolicFile *SymObj) { … }
static void writeSymbolTable(raw_ostream &Out, object::Archive::Kind Kind,
bool Deterministic, ArrayRef<MemberData> Members,
StringRef StringTable, uint64_t MembersOffset,
unsigned NumSyms, uint64_t PrevMemberOffset = 0,
uint64_t NextMemberOffset = 0,
bool Is64Bit = false) { … }
static void writeSymbolMap(raw_ostream &Out, object::Archive::Kind Kind,
bool Deterministic, ArrayRef<MemberData> Members,
SymMap &SymMap, uint64_t MembersOffset) { … }
static void writeECSymbols(raw_ostream &Out, object::Archive::Kind Kind,
bool Deterministic, ArrayRef<MemberData> Members,
SymMap &SymMap) { … }
static bool isECObject(object::SymbolicFile &Obj) { … }
static bool isAnyArm64COFF(object::SymbolicFile &Obj) { … }
bool isImportDescriptor(StringRef Name) { … }
static Expected<std::vector<unsigned>> getSymbols(SymbolicFile *Obj,
uint16_t Index,
raw_ostream &SymNames,
SymMap *SymMap) { … }
static Expected<std::vector<MemberData>>
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
object::Archive::Kind Kind, bool Thin, bool Deterministic,
SymtabWritingMode NeedSymbols, SymMap *SymMap,
LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers,
std::optional<bool> IsEC, function_ref<void(Error)> Warn) { … }
namespace llvm {
static ErrorOr<SmallString<128>> canonicalizePath(StringRef P) { … }
Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To) { … }
Error writeArchiveToStream(raw_ostream &Out,
ArrayRef<NewArchiveMember> NewMembers,
SymtabWritingMode WriteSymtab,
object::Archive::Kind Kind, bool Deterministic,
bool Thin, std::optional<bool> IsEC,
function_ref<void(Error)> Warn) { … }
void warnToStderr(Error Err) { … }
Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
std::unique_ptr<MemoryBuffer> OldArchiveBuf,
std::optional<bool> IsEC, function_ref<void(Error)> Warn) { … }
Expected<std::unique_ptr<MemoryBuffer>>
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
bool Deterministic, bool Thin,
function_ref<void(Error)> Warn) { … }
}