diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/llvm12/include/llvm/Object/Archive.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/Object/Archive.h')
-rw-r--r-- | contrib/libs/llvm12/include/llvm/Object/Archive.h | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/include/llvm/Object/Archive.h b/contrib/libs/llvm12/include/llvm/Object/Archive.h new file mode 100644 index 0000000000..b6b1a126ac --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/Object/Archive.h @@ -0,0 +1,297 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- Archive.h - ar archive file format -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the ar archive file format class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_ARCHIVE_H +#define LLVM_OBJECT_ARCHIVE_H + +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/fallible_iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Object/Binary.h" +#include "llvm/Support/Chrono.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> +#include <vector> + +namespace llvm { +namespace object { + +class Archive; + +class ArchiveMemberHeader { +public: + friend class Archive; + + ArchiveMemberHeader(Archive const *Parent, const char *RawHeaderPtr, + uint64_t Size, Error *Err); + // ArchiveMemberHeader() = default; + + /// Get the name without looking up long names. + Expected<StringRef> getRawName() const; + + /// Get the name looking up long names. + Expected<StringRef> getName(uint64_t Size) const; + + Expected<uint64_t> getSize() const; + + Expected<sys::fs::perms> getAccessMode() const; + Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const; + + StringRef getRawLastModified() const { + return StringRef(ArMemHdr->LastModified, + sizeof(ArMemHdr->LastModified)).rtrim(' '); + } + + Expected<unsigned> getUID() const; + Expected<unsigned> getGID() const; + + // This returns the size of the private struct ArMemHdrType + uint64_t getSizeOf() const { + return sizeof(ArMemHdrType); + } + +private: + struct ArMemHdrType { + char Name[16]; + char LastModified[12]; + char UID[6]; + char GID[6]; + char AccessMode[8]; + char Size[10]; ///< Size of data, not including header or padding. + char Terminator[2]; + }; + Archive const *Parent; + ArMemHdrType const *ArMemHdr; +}; + +class Archive : public Binary { + virtual void anchor(); + +public: + class Child { + friend Archive; + friend ArchiveMemberHeader; + + const Archive *Parent; + ArchiveMemberHeader Header; + /// Includes header but not padding byte. + StringRef Data; + /// Offset from Data to the start of the file. + uint16_t StartOfFile; + + Expected<bool> isThinMember() const; + + public: + Child(const Archive *Parent, const char *Start, Error *Err); + Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile); + + bool operator ==(const Child &other) const { + assert(!Parent || !other.Parent || Parent == other.Parent); + return Data.begin() == other.Data.begin(); + } + + const Archive *getParent() const { return Parent; } + Expected<Child> getNext() const; + + Expected<StringRef> getName() const; + Expected<std::string> getFullName() const; + Expected<StringRef> getRawName() const { return Header.getRawName(); } + + Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const { + return Header.getLastModified(); + } + + StringRef getRawLastModified() const { + return Header.getRawLastModified(); + } + + Expected<unsigned> getUID() const { return Header.getUID(); } + Expected<unsigned> getGID() const { return Header.getGID(); } + + Expected<sys::fs::perms> getAccessMode() const { + return Header.getAccessMode(); + } + + /// \return the size of the archive member without the header or padding. + Expected<uint64_t> getSize() const; + /// \return the size in the archive header for this member. + Expected<uint64_t> getRawSize() const; + + Expected<StringRef> getBuffer() const; + uint64_t getChildOffset() const; + uint64_t getDataOffset() const { return getChildOffset() + StartOfFile; } + + Expected<MemoryBufferRef> getMemoryBufferRef() const; + + Expected<std::unique_ptr<Binary>> + getAsBinary(LLVMContext *Context = nullptr) const; + }; + + class ChildFallibleIterator { + Child C; + + public: + ChildFallibleIterator() : C(Child(nullptr, nullptr, nullptr)) {} + ChildFallibleIterator(const Child &C) : C(C) {} + + const Child *operator->() const { return &C; } + const Child &operator*() const { return C; } + + bool operator==(const ChildFallibleIterator &other) const { + // Ignore errors here: If an error occurred during increment then getNext + // will have been set to child_end(), and the following comparison should + // do the right thing. + return C == other.C; + } + + bool operator!=(const ChildFallibleIterator &other) const { + return !(*this == other); + } + + Error inc() { + auto NextChild = C.getNext(); + if (!NextChild) + return NextChild.takeError(); + C = std::move(*NextChild); + return Error::success(); + } + }; + + using child_iterator = fallible_iterator<ChildFallibleIterator>; + + class Symbol { + const Archive *Parent; + uint32_t SymbolIndex; + uint32_t StringIndex; // Extra index to the string. + + public: + Symbol(const Archive *p, uint32_t symi, uint32_t stri) + : Parent(p) + , SymbolIndex(symi) + , StringIndex(stri) {} + + bool operator ==(const Symbol &other) const { + return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex); + } + + StringRef getName() const; + Expected<Child> getMember() const; + Symbol getNext() const; + }; + + class symbol_iterator { + Symbol symbol; + + public: + symbol_iterator(const Symbol &s) : symbol(s) {} + + const Symbol *operator->() const { return &symbol; } + const Symbol &operator*() const { return symbol; } + + bool operator==(const symbol_iterator &other) const { + return symbol == other.symbol; + } + + bool operator!=(const symbol_iterator &other) const { + return !(*this == other); + } + + symbol_iterator& operator++() { // Preincrement + symbol = symbol.getNext(); + return *this; + } + }; + + Archive(MemoryBufferRef Source, Error &Err); + static Expected<std::unique_ptr<Archive>> create(MemoryBufferRef Source); + + /// Size field is 10 decimal digits long + static const uint64_t MaxMemberSize = 9999999999; + + enum Kind { + K_GNU, + K_GNU64, + K_BSD, + K_DARWIN, + K_DARWIN64, + K_COFF + }; + + Kind kind() const { return (Kind)Format; } + bool isThin() const { return IsThin; } + + child_iterator child_begin(Error &Err, bool SkipInternal = true) const; + child_iterator child_end() const; + iterator_range<child_iterator> children(Error &Err, + bool SkipInternal = true) const { + return make_range(child_begin(Err, SkipInternal), child_end()); + } + + symbol_iterator symbol_begin() const; + symbol_iterator symbol_end() const; + iterator_range<symbol_iterator> symbols() const { + return make_range(symbol_begin(), symbol_end()); + } + + // Cast methods. + static bool classof(Binary const *v) { + return v->isArchive(); + } + + // check if a symbol is in the archive + Expected<Optional<Child>> findSym(StringRef name) const; + + bool isEmpty() const; + bool hasSymbolTable() const; + StringRef getSymbolTable() const { return SymbolTable; } + StringRef getStringTable() const { return StringTable; } + uint32_t getNumberOfSymbols() const; + + std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() { + return std::move(ThinBuffers); + } + +private: + StringRef SymbolTable; + StringRef StringTable; + + StringRef FirstRegularData; + uint16_t FirstRegularStartOfFile = -1; + void setFirstRegular(const Child &C); + + unsigned Format : 3; + unsigned IsThin : 1; + mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers; +}; + +} // end namespace object +} // end namespace llvm + +#endif // LLVM_OBJECT_ARCHIVE_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |