summaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/include/llvm/Object
diff options
context:
space:
mode:
authororivej <[email protected]>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <[email protected]>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/llvm12/include/llvm/Object
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
Restoring authorship annotation for <[email protected]>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/Object')
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Archive.h594
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h110
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Binary.h488
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/COFF.h2538
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/COFFImportFile.h248
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/COFFModuleDefinition.h126
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/CVDebugRecord.h130
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Decompressor.h154
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ELF.h1256
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h2280
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ELFTypes.h1554
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Error.h210
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/IRObjectFile.h204
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/IRSymtab.h770
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/MachO.h1498
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h350
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Minidump.h454
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ModuleSymbolTable.h168
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/ObjectFile.h1198
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h102
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/StackMapParser.h920
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/SymbolSize.h88
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h442
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/TapiFile.h148
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/TapiUniversal.h264
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/Wasm.h730
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/WindowsMachineFlag.h88
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/WindowsResource.h564
-rw-r--r--contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h816
29 files changed, 9246 insertions, 9246 deletions
diff --git a/contrib/libs/llvm12/include/llvm/Object/Archive.h b/contrib/libs/llvm12/include/llvm/Object/Archive.h
index b6b1a126ac3..07cc0a13524 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Archive.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Archive.h
@@ -1,297 +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
+#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
diff --git a/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h b/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h
index a2c582c4804..777cf2f3337 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ArchiveWriter.h
@@ -1,61 +1,61 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ArchiveWriter.h - ar archive file format writer ----------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Declares the writeArchive function for writing an archive file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_ARCHIVEWRITER_H
-#define LLVM_OBJECT_ARCHIVEWRITER_H
-
-#include "llvm/Object/Archive.h"
-
-namespace llvm {
-
-struct NewArchiveMember {
- std::unique_ptr<MemoryBuffer> Buf;
- StringRef MemberName;
- sys::TimePoint<std::chrono::seconds> ModTime;
- unsigned UID = 0, GID = 0, Perms = 0644;
-
- NewArchiveMember() = default;
- NewArchiveMember(MemoryBufferRef BufRef);
-
- static Expected<NewArchiveMember>
- getOldMember(const object::Archive::Child &OldMember, bool Deterministic);
-
- static Expected<NewArchiveMember> getFile(StringRef FileName,
- bool Deterministic);
-};
-
-Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
-
-Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
- bool WriteSymtab, object::Archive::Kind Kind,
- bool Deterministic, bool Thin,
- std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ArchiveWriter.h - ar archive file format writer ----------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Declares the writeArchive function for writing an archive file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ARCHIVEWRITER_H
+#define LLVM_OBJECT_ARCHIVEWRITER_H
+
+#include "llvm/Object/Archive.h"
+
+namespace llvm {
+
+struct NewArchiveMember {
+ std::unique_ptr<MemoryBuffer> Buf;
+ StringRef MemberName;
+ sys::TimePoint<std::chrono::seconds> ModTime;
+ unsigned UID = 0, GID = 0, Perms = 0644;
+
+ NewArchiveMember() = default;
+ NewArchiveMember(MemoryBufferRef BufRef);
+
+ static Expected<NewArchiveMember>
+ getOldMember(const object::Archive::Child &OldMember, bool Deterministic);
+
+ static Expected<NewArchiveMember> getFile(StringRef FileName,
+ bool Deterministic);
+};
+
+Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
+
+Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
+ bool WriteSymtab, object::Archive::Kind Kind,
+ bool Deterministic, bool Thin,
+ std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr);
// writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
// buffer instead of writing it out to a file.
Expected<std::unique_ptr<MemoryBuffer>>
writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers, bool WriteSymtab,
object::Archive::Kind Kind, bool Deterministic, bool Thin);
-}
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+}
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/Binary.h b/contrib/libs/llvm12/include/llvm/Object/Binary.h
index 0b1ee8456bb..cc0ce62f6d2 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Binary.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Binary.h
@@ -1,253 +1,253 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Binary.h - A generic binary file -------------------------*- 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 Binary class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_BINARY_H
-#define LLVM_OBJECT_BINARY_H
-
-#include "llvm-c/Types.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-namespace llvm {
-
-class LLVMContext;
-class StringRef;
-
-namespace object {
-
-class Binary {
-private:
- unsigned int TypeID;
-
-protected:
- MemoryBufferRef Data;
-
- Binary(unsigned int Type, MemoryBufferRef Source);
-
- enum {
- ID_Archive,
- ID_MachOUniversalBinary,
- ID_COFFImportFile,
- ID_IR, // LLVM IR
- ID_TapiUniversal, // Text-based Dynamic Library Stub file.
- ID_TapiFile, // Text-based Dynamic Library Stub file.
-
- ID_Minidump,
-
- ID_WinRes, // Windows resource (.res) file.
-
- // Object and children.
- ID_StartObjects,
- ID_COFF,
-
- ID_XCOFF32, // AIX XCOFF 32-bit
- ID_XCOFF64, // AIX XCOFF 64-bit
-
- ID_ELF32L, // ELF 32-bit, little endian
- ID_ELF32B, // ELF 32-bit, big endian
- ID_ELF64L, // ELF 64-bit, little endian
- ID_ELF64B, // ELF 64-bit, big endian
-
- ID_MachO32L, // MachO 32-bit, little endian
- ID_MachO32B, // MachO 32-bit, big endian
- ID_MachO64L, // MachO 64-bit, little endian
- ID_MachO64B, // MachO 64-bit, big endian
-
- ID_Wasm,
-
- ID_EndObjects
- };
-
- static inline unsigned int getELFType(bool isLE, bool is64Bits) {
- if (isLE)
- return is64Bits ? ID_ELF64L : ID_ELF32L;
- else
- return is64Bits ? ID_ELF64B : ID_ELF32B;
- }
-
- static unsigned int getMachOType(bool isLE, bool is64Bits) {
- if (isLE)
- return is64Bits ? ID_MachO64L : ID_MachO32L;
- else
- return is64Bits ? ID_MachO64B : ID_MachO32B;
- }
-
-public:
- Binary() = delete;
- Binary(const Binary &other) = delete;
- virtual ~Binary();
-
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Binary.h - A generic binary file -------------------------*- 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 Binary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_BINARY_H
+#define LLVM_OBJECT_BINARY_H
+
+#include "llvm-c/Types.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+namespace llvm {
+
+class LLVMContext;
+class StringRef;
+
+namespace object {
+
+class Binary {
+private:
+ unsigned int TypeID;
+
+protected:
+ MemoryBufferRef Data;
+
+ Binary(unsigned int Type, MemoryBufferRef Source);
+
+ enum {
+ ID_Archive,
+ ID_MachOUniversalBinary,
+ ID_COFFImportFile,
+ ID_IR, // LLVM IR
+ ID_TapiUniversal, // Text-based Dynamic Library Stub file.
+ ID_TapiFile, // Text-based Dynamic Library Stub file.
+
+ ID_Minidump,
+
+ ID_WinRes, // Windows resource (.res) file.
+
+ // Object and children.
+ ID_StartObjects,
+ ID_COFF,
+
+ ID_XCOFF32, // AIX XCOFF 32-bit
+ ID_XCOFF64, // AIX XCOFF 64-bit
+
+ ID_ELF32L, // ELF 32-bit, little endian
+ ID_ELF32B, // ELF 32-bit, big endian
+ ID_ELF64L, // ELF 64-bit, little endian
+ ID_ELF64B, // ELF 64-bit, big endian
+
+ ID_MachO32L, // MachO 32-bit, little endian
+ ID_MachO32B, // MachO 32-bit, big endian
+ ID_MachO64L, // MachO 64-bit, little endian
+ ID_MachO64B, // MachO 64-bit, big endian
+
+ ID_Wasm,
+
+ ID_EndObjects
+ };
+
+ static inline unsigned int getELFType(bool isLE, bool is64Bits) {
+ if (isLE)
+ return is64Bits ? ID_ELF64L : ID_ELF32L;
+ else
+ return is64Bits ? ID_ELF64B : ID_ELF32B;
+ }
+
+ static unsigned int getMachOType(bool isLE, bool is64Bits) {
+ if (isLE)
+ return is64Bits ? ID_MachO64L : ID_MachO32L;
+ else
+ return is64Bits ? ID_MachO64B : ID_MachO32B;
+ }
+
+public:
+ Binary() = delete;
+ Binary(const Binary &other) = delete;
+ virtual ~Binary();
+
virtual Error initContent() { return Error::success(); };
- StringRef getData() const;
- StringRef getFileName() const;
- MemoryBufferRef getMemoryBufferRef() const;
-
- // Cast methods.
- unsigned int getType() const { return TypeID; }
-
- // Convenience methods
- bool isObject() const {
- return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
- }
-
- bool isSymbolic() const {
- return isIR() || isObject() || isCOFFImportFile() || isTapiFile();
- }
-
- bool isArchive() const { return TypeID == ID_Archive; }
-
- bool isMachOUniversalBinary() const {
- return TypeID == ID_MachOUniversalBinary;
- }
-
- bool isTapiUniversal() const { return TypeID == ID_TapiUniversal; }
-
- bool isELF() const {
- return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
- }
-
- bool isMachO() const {
- return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
- }
-
- bool isCOFF() const {
- return TypeID == ID_COFF;
- }
-
- bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
-
- bool isWasm() const { return TypeID == ID_Wasm; }
-
- bool isCOFFImportFile() const {
- return TypeID == ID_COFFImportFile;
- }
-
- bool isIR() const {
- return TypeID == ID_IR;
- }
-
- bool isMinidump() const { return TypeID == ID_Minidump; }
-
- bool isTapiFile() const { return TypeID == ID_TapiFile; }
-
- bool isLittleEndian() const {
- return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
- TypeID == ID_MachO32B || TypeID == ID_MachO64B);
- }
-
- bool isWinRes() const { return TypeID == ID_WinRes; }
-
- Triple::ObjectFormatType getTripleObjectFormat() const {
- if (isCOFF())
- return Triple::COFF;
- if (isMachO())
- return Triple::MachO;
- if (isELF())
- return Triple::ELF;
- return Triple::UnknownObjectFormat;
- }
-
- static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
- const uint64_t Size) {
- if (Addr + Size < Addr || Addr + Size < Size ||
+ StringRef getData() const;
+ StringRef getFileName() const;
+ MemoryBufferRef getMemoryBufferRef() const;
+
+ // Cast methods.
+ unsigned int getType() const { return TypeID; }
+
+ // Convenience methods
+ bool isObject() const {
+ return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
+ }
+
+ bool isSymbolic() const {
+ return isIR() || isObject() || isCOFFImportFile() || isTapiFile();
+ }
+
+ bool isArchive() const { return TypeID == ID_Archive; }
+
+ bool isMachOUniversalBinary() const {
+ return TypeID == ID_MachOUniversalBinary;
+ }
+
+ bool isTapiUniversal() const { return TypeID == ID_TapiUniversal; }
+
+ bool isELF() const {
+ return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
+ }
+
+ bool isMachO() const {
+ return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
+ }
+
+ bool isCOFF() const {
+ return TypeID == ID_COFF;
+ }
+
+ bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
+
+ bool isWasm() const { return TypeID == ID_Wasm; }
+
+ bool isCOFFImportFile() const {
+ return TypeID == ID_COFFImportFile;
+ }
+
+ bool isIR() const {
+ return TypeID == ID_IR;
+ }
+
+ bool isMinidump() const { return TypeID == ID_Minidump; }
+
+ bool isTapiFile() const { return TypeID == ID_TapiFile; }
+
+ bool isLittleEndian() const {
+ return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
+ TypeID == ID_MachO32B || TypeID == ID_MachO64B);
+ }
+
+ bool isWinRes() const { return TypeID == ID_WinRes; }
+
+ Triple::ObjectFormatType getTripleObjectFormat() const {
+ if (isCOFF())
+ return Triple::COFF;
+ if (isMachO())
+ return Triple::MachO;
+ if (isELF())
+ return Triple::ELF;
+ return Triple::UnknownObjectFormat;
+ }
+
+ static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
+ const uint64_t Size) {
+ if (Addr + Size < Addr || Addr + Size < Size ||
Addr + Size > reinterpret_cast<uintptr_t>(M.getBufferEnd()) ||
Addr < reinterpret_cast<uintptr_t>(M.getBufferStart())) {
- return errorCodeToError(object_error::unexpected_eof);
- }
- return Error::success();
- }
-};
-
-// Create wrappers for C Binding types (see CBindingWrapping.h).
-DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
-
-/// Create a Binary from Source, autodetecting the file type.
-///
-/// @param Source The data to create the Binary from.
-Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
+ return errorCodeToError(object_error::unexpected_eof);
+ }
+ return Error::success();
+ }
+};
+
+// Create wrappers for C Binding types (see CBindingWrapping.h).
+DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
+
+/// Create a Binary from Source, autodetecting the file type.
+///
+/// @param Source The data to create the Binary from.
+Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
LLVMContext *Context = nullptr,
bool InitContent = true);
-
-template <typename T> class OwningBinary {
- std::unique_ptr<T> Bin;
- std::unique_ptr<MemoryBuffer> Buf;
-
-public:
- OwningBinary();
- OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
- OwningBinary(OwningBinary<T>&& Other);
- OwningBinary<T> &operator=(OwningBinary<T> &&Other);
-
- std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
-
- T* getBinary();
- const T* getBinary() const;
-};
-
-template <typename T>
-OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
- std::unique_ptr<MemoryBuffer> Buf)
- : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
-
-template <typename T> OwningBinary<T>::OwningBinary() = default;
-
-template <typename T>
-OwningBinary<T>::OwningBinary(OwningBinary &&Other)
- : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
-
-template <typename T>
-OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
- Bin = std::move(Other.Bin);
- Buf = std::move(Other.Buf);
- return *this;
-}
-
-template <typename T>
-std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
-OwningBinary<T>::takeBinary() {
- return std::make_pair(std::move(Bin), std::move(Buf));
-}
-
-template <typename T> T* OwningBinary<T>::getBinary() {
- return Bin.get();
-}
-
-template <typename T> const T* OwningBinary<T>::getBinary() const {
- return Bin.get();
-}
-
+
+template <typename T> class OwningBinary {
+ std::unique_ptr<T> Bin;
+ std::unique_ptr<MemoryBuffer> Buf;
+
+public:
+ OwningBinary();
+ OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
+ OwningBinary(OwningBinary<T>&& Other);
+ OwningBinary<T> &operator=(OwningBinary<T> &&Other);
+
+ std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
+
+ T* getBinary();
+ const T* getBinary() const;
+};
+
+template <typename T>
+OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
+ std::unique_ptr<MemoryBuffer> Buf)
+ : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
+
+template <typename T> OwningBinary<T>::OwningBinary() = default;
+
+template <typename T>
+OwningBinary<T>::OwningBinary(OwningBinary &&Other)
+ : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
+
+template <typename T>
+OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
+ Bin = std::move(Other.Bin);
+ Buf = std::move(Other.Buf);
+ return *this;
+}
+
+template <typename T>
+std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
+OwningBinary<T>::takeBinary() {
+ return std::make_pair(std::move(Bin), std::move(Buf));
+}
+
+template <typename T> T* OwningBinary<T>::getBinary() {
+ return Bin.get();
+}
+
+template <typename T> const T* OwningBinary<T>::getBinary() const {
+ return Bin.get();
+}
+
Expected<OwningBinary<Binary>> createBinary(StringRef Path,
LLVMContext *Context = nullptr,
bool InitContent = true);
-
-} // end namespace object
-
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_BINARY_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_BINARY_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/COFF.h b/contrib/libs/llvm12/include/llvm/Object/COFF.h
index 816a078cfcd..3b7fbb1a991 100644
--- a/contrib/libs/llvm12/include/llvm/Object/COFF.h
+++ b/contrib/libs/llvm12/include/llvm/Object/COFF.h
@@ -1,593 +1,593 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- COFF.h - COFF object file implementation -----------------*- 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 COFFObjectFile class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_COFF_H
-#define LLVM_OBJECT_COFF_H
-
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/CVDebugRecord.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <system_error>
-
-namespace llvm {
-
-template <typename T> class ArrayRef;
-
-namespace object {
-
-class BaseRelocRef;
-class DelayImportDirectoryEntryRef;
-class ExportDirectoryEntryRef;
-class ImportDirectoryEntryRef;
-class ImportedSymbolRef;
-class ResourceSectionRef;
-
-using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
-using delay_import_directory_iterator =
- content_iterator<DelayImportDirectoryEntryRef>;
-using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
-using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
-using base_reloc_iterator = content_iterator<BaseRelocRef>;
-
-/// The DOS compatible header at the front of all PE/COFF executables.
-struct dos_header {
- char Magic[2];
- support::ulittle16_t UsedBytesInTheLastPage;
- support::ulittle16_t FileSizeInPages;
- support::ulittle16_t NumberOfRelocationItems;
- support::ulittle16_t HeaderSizeInParagraphs;
- support::ulittle16_t MinimumExtraParagraphs;
- support::ulittle16_t MaximumExtraParagraphs;
- support::ulittle16_t InitialRelativeSS;
- support::ulittle16_t InitialSP;
- support::ulittle16_t Checksum;
- support::ulittle16_t InitialIP;
- support::ulittle16_t InitialRelativeCS;
- support::ulittle16_t AddressOfRelocationTable;
- support::ulittle16_t OverlayNumber;
- support::ulittle16_t Reserved[4];
- support::ulittle16_t OEMid;
- support::ulittle16_t OEMinfo;
- support::ulittle16_t Reserved2[10];
- support::ulittle32_t AddressOfNewExeHeader;
-};
-
-struct coff_file_header {
- support::ulittle16_t Machine;
- support::ulittle16_t NumberOfSections;
- support::ulittle32_t TimeDateStamp;
- support::ulittle32_t PointerToSymbolTable;
- support::ulittle32_t NumberOfSymbols;
- support::ulittle16_t SizeOfOptionalHeader;
- support::ulittle16_t Characteristics;
-
- bool isImportLibrary() const { return NumberOfSections == 0xffff; }
-};
-
-struct coff_bigobj_file_header {
- support::ulittle16_t Sig1;
- support::ulittle16_t Sig2;
- support::ulittle16_t Version;
- support::ulittle16_t Machine;
- support::ulittle32_t TimeDateStamp;
- uint8_t UUID[16];
- support::ulittle32_t unused1;
- support::ulittle32_t unused2;
- support::ulittle32_t unused3;
- support::ulittle32_t unused4;
- support::ulittle32_t NumberOfSections;
- support::ulittle32_t PointerToSymbolTable;
- support::ulittle32_t NumberOfSymbols;
-};
-
-/// The 32-bit PE header that follows the COFF header.
-struct pe32_header {
- support::ulittle16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- support::ulittle32_t SizeOfCode;
- support::ulittle32_t SizeOfInitializedData;
- support::ulittle32_t SizeOfUninitializedData;
- support::ulittle32_t AddressOfEntryPoint;
- support::ulittle32_t BaseOfCode;
- support::ulittle32_t BaseOfData;
- support::ulittle32_t ImageBase;
- support::ulittle32_t SectionAlignment;
- support::ulittle32_t FileAlignment;
- support::ulittle16_t MajorOperatingSystemVersion;
- support::ulittle16_t MinorOperatingSystemVersion;
- support::ulittle16_t MajorImageVersion;
- support::ulittle16_t MinorImageVersion;
- support::ulittle16_t MajorSubsystemVersion;
- support::ulittle16_t MinorSubsystemVersion;
- support::ulittle32_t Win32VersionValue;
- support::ulittle32_t SizeOfImage;
- support::ulittle32_t SizeOfHeaders;
- support::ulittle32_t CheckSum;
- support::ulittle16_t Subsystem;
- // FIXME: This should be DllCharacteristics.
- support::ulittle16_t DLLCharacteristics;
- support::ulittle32_t SizeOfStackReserve;
- support::ulittle32_t SizeOfStackCommit;
- support::ulittle32_t SizeOfHeapReserve;
- support::ulittle32_t SizeOfHeapCommit;
- support::ulittle32_t LoaderFlags;
- // FIXME: This should be NumberOfRvaAndSizes.
- support::ulittle32_t NumberOfRvaAndSize;
-};
-
-/// The 64-bit PE header that follows the COFF header.
-struct pe32plus_header {
- support::ulittle16_t Magic;
- uint8_t MajorLinkerVersion;
- uint8_t MinorLinkerVersion;
- support::ulittle32_t SizeOfCode;
- support::ulittle32_t SizeOfInitializedData;
- support::ulittle32_t SizeOfUninitializedData;
- support::ulittle32_t AddressOfEntryPoint;
- support::ulittle32_t BaseOfCode;
- support::ulittle64_t ImageBase;
- support::ulittle32_t SectionAlignment;
- support::ulittle32_t FileAlignment;
- support::ulittle16_t MajorOperatingSystemVersion;
- support::ulittle16_t MinorOperatingSystemVersion;
- support::ulittle16_t MajorImageVersion;
- support::ulittle16_t MinorImageVersion;
- support::ulittle16_t MajorSubsystemVersion;
- support::ulittle16_t MinorSubsystemVersion;
- support::ulittle32_t Win32VersionValue;
- support::ulittle32_t SizeOfImage;
- support::ulittle32_t SizeOfHeaders;
- support::ulittle32_t CheckSum;
- support::ulittle16_t Subsystem;
- support::ulittle16_t DLLCharacteristics;
- support::ulittle64_t SizeOfStackReserve;
- support::ulittle64_t SizeOfStackCommit;
- support::ulittle64_t SizeOfHeapReserve;
- support::ulittle64_t SizeOfHeapCommit;
- support::ulittle32_t LoaderFlags;
- support::ulittle32_t NumberOfRvaAndSize;
-};
-
-struct data_directory {
- support::ulittle32_t RelativeVirtualAddress;
- support::ulittle32_t Size;
-};
-
-struct debug_directory {
- support::ulittle32_t Characteristics;
- support::ulittle32_t TimeDateStamp;
- support::ulittle16_t MajorVersion;
- support::ulittle16_t MinorVersion;
- support::ulittle32_t Type;
- support::ulittle32_t SizeOfData;
- support::ulittle32_t AddressOfRawData;
- support::ulittle32_t PointerToRawData;
-};
-
-template <typename IntTy>
-struct import_lookup_table_entry {
- IntTy Data;
-
- bool isOrdinal() const { return Data < 0; }
-
- uint16_t getOrdinal() const {
- assert(isOrdinal() && "ILT entry is not an ordinal!");
- return Data & 0xFFFF;
- }
-
- uint32_t getHintNameRVA() const {
- assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
- return Data & 0xFFFFFFFF;
- }
-};
-
-using import_lookup_table_entry32 =
- import_lookup_table_entry<support::little32_t>;
-using import_lookup_table_entry64 =
- import_lookup_table_entry<support::little64_t>;
-
-struct delay_import_directory_table_entry {
- // dumpbin reports this field as "Characteristics" instead of "Attributes".
- support::ulittle32_t Attributes;
- support::ulittle32_t Name;
- support::ulittle32_t ModuleHandle;
- support::ulittle32_t DelayImportAddressTable;
- support::ulittle32_t DelayImportNameTable;
- support::ulittle32_t BoundDelayImportTable;
- support::ulittle32_t UnloadDelayImportTable;
- support::ulittle32_t TimeStamp;
-};
-
-struct export_directory_table_entry {
- support::ulittle32_t ExportFlags;
- support::ulittle32_t TimeDateStamp;
- support::ulittle16_t MajorVersion;
- support::ulittle16_t MinorVersion;
- support::ulittle32_t NameRVA;
- support::ulittle32_t OrdinalBase;
- support::ulittle32_t AddressTableEntries;
- support::ulittle32_t NumberOfNamePointers;
- support::ulittle32_t ExportAddressTableRVA;
- support::ulittle32_t NamePointerRVA;
- support::ulittle32_t OrdinalTableRVA;
-};
-
-union export_address_table_entry {
- support::ulittle32_t ExportRVA;
- support::ulittle32_t ForwarderRVA;
-};
-
-using export_name_pointer_table_entry = support::ulittle32_t;
-using export_ordinal_table_entry = support::ulittle16_t;
-
-struct StringTableOffset {
- support::ulittle32_t Zeroes;
- support::ulittle32_t Offset;
-};
-
-template <typename SectionNumberType>
-struct coff_symbol {
- union {
- char ShortName[COFF::NameSize];
- StringTableOffset Offset;
- } Name;
-
- support::ulittle32_t Value;
- SectionNumberType SectionNumber;
-
- support::ulittle16_t Type;
-
- uint8_t StorageClass;
- uint8_t NumberOfAuxSymbols;
-};
-
-using coff_symbol16 = coff_symbol<support::ulittle16_t>;
-using coff_symbol32 = coff_symbol<support::ulittle32_t>;
-
-// Contains only common parts of coff_symbol16 and coff_symbol32.
-struct coff_symbol_generic {
- union {
- char ShortName[COFF::NameSize];
- StringTableOffset Offset;
- } Name;
- support::ulittle32_t Value;
-};
-
-struct coff_aux_section_definition;
-struct coff_aux_weak_external;
-
-class COFFSymbolRef {
-public:
- COFFSymbolRef() = default;
- COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
- COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
-
- const void *getRawPtr() const {
- return CS16 ? static_cast<const void *>(CS16) : CS32;
- }
-
- const coff_symbol_generic *getGeneric() const {
- if (CS16)
- return reinterpret_cast<const coff_symbol_generic *>(CS16);
- return reinterpret_cast<const coff_symbol_generic *>(CS32);
- }
-
- friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
- return A.getRawPtr() < B.getRawPtr();
- }
-
- bool isBigObj() const {
- if (CS16)
- return false;
- if (CS32)
- return true;
- llvm_unreachable("COFFSymbolRef points to nothing!");
- }
-
- const char *getShortName() const {
- return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
- }
-
- const StringTableOffset &getStringTableOffset() const {
- assert(isSet() && "COFFSymbolRef points to nothing!");
- return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
- }
-
- uint32_t getValue() const {
- assert(isSet() && "COFFSymbolRef points to nothing!");
- return CS16 ? CS16->Value : CS32->Value;
- }
-
- int32_t getSectionNumber() const {
- assert(isSet() && "COFFSymbolRef points to nothing!");
- if (CS16) {
- // Reserved sections are returned as negative numbers.
- if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
- return CS16->SectionNumber;
- return static_cast<int16_t>(CS16->SectionNumber);
- }
- return static_cast<int32_t>(CS32->SectionNumber);
- }
-
- uint16_t getType() const {
- assert(isSet() && "COFFSymbolRef points to nothing!");
- return CS16 ? CS16->Type : CS32->Type;
- }
-
- uint8_t getStorageClass() const {
- assert(isSet() && "COFFSymbolRef points to nothing!");
- return CS16 ? CS16->StorageClass : CS32->StorageClass;
- }
-
- uint8_t getNumberOfAuxSymbols() const {
- assert(isSet() && "COFFSymbolRef points to nothing!");
- return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
- }
-
- uint8_t getBaseType() const { return getType() & 0x0F; }
-
- uint8_t getComplexType() const {
- return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
- }
-
- template <typename T> const T *getAux() const {
- return CS16 ? reinterpret_cast<const T *>(CS16 + 1)
- : reinterpret_cast<const T *>(CS32 + 1);
- }
-
- const coff_aux_section_definition *getSectionDefinition() const {
- if (!getNumberOfAuxSymbols() ||
- getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC)
- return nullptr;
- return getAux<coff_aux_section_definition>();
- }
-
- const coff_aux_weak_external *getWeakExternal() const {
- if (!getNumberOfAuxSymbols() ||
- getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
- return nullptr;
- return getAux<coff_aux_weak_external>();
- }
-
- bool isAbsolute() const {
- return getSectionNumber() == -1;
- }
-
- bool isExternal() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
- }
-
- bool isCommon() const {
- return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
- getValue() != 0;
- }
-
- bool isUndefined() const {
- return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
- getValue() == 0;
- }
-
- bool isWeakExternal() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- }
-
- bool isFunctionDefinition() const {
- return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
- getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
- !COFF::isReservedSectionNumber(getSectionNumber());
- }
-
- bool isFunctionLineInfo() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
- }
-
- bool isAnyUndefined() const {
- return isUndefined() || isWeakExternal();
- }
-
- bool isFileRecord() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
- }
-
- bool isSection() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
- }
-
- bool isSectionDefinition() const {
- // C++/CLI creates external ABS symbols for non-const appdomain globals.
- // These are also followed by an auxiliary section definition.
- bool isAppdomainGlobal =
- getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
- getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
- bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
- if (!getNumberOfAuxSymbols())
- return false;
- return isAppdomainGlobal || isOrdinarySection;
- }
-
- bool isCLRToken() const {
- return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
- }
-
-private:
- bool isSet() const { return CS16 || CS32; }
-
- const coff_symbol16 *CS16 = nullptr;
- const coff_symbol32 *CS32 = nullptr;
-};
-
-struct coff_section {
- char Name[COFF::NameSize];
- support::ulittle32_t VirtualSize;
- support::ulittle32_t VirtualAddress;
- support::ulittle32_t SizeOfRawData;
- support::ulittle32_t PointerToRawData;
- support::ulittle32_t PointerToRelocations;
- support::ulittle32_t PointerToLinenumbers;
- support::ulittle16_t NumberOfRelocations;
- support::ulittle16_t NumberOfLinenumbers;
- support::ulittle32_t Characteristics;
-
- // Returns true if the actual number of relocations is stored in
- // VirtualAddress field of the first relocation table entry.
- bool hasExtendedRelocations() const {
- return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
- NumberOfRelocations == UINT16_MAX;
- }
-
- uint32_t getAlignment() const {
- // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
- // IMAGE_SCN_ALIGN_1BYTES.
- if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
- return 1;
-
- // Bit [20:24] contains section alignment. 0 means use a default alignment
- // of 16.
- uint32_t Shift = (Characteristics >> 20) & 0xF;
- if (Shift > 0)
- return 1U << (Shift - 1);
- return 16;
- }
-};
-
-struct coff_relocation {
- support::ulittle32_t VirtualAddress;
- support::ulittle32_t SymbolTableIndex;
- support::ulittle16_t Type;
-};
-
-struct coff_aux_function_definition {
- support::ulittle32_t TagIndex;
- support::ulittle32_t TotalSize;
- support::ulittle32_t PointerToLinenumber;
- support::ulittle32_t PointerToNextFunction;
- char Unused1[2];
-};
-
-static_assert(sizeof(coff_aux_function_definition) == 18,
- "auxiliary entry must be 18 bytes");
-
-struct coff_aux_bf_and_ef_symbol {
- char Unused1[4];
- support::ulittle16_t Linenumber;
- char Unused2[6];
- support::ulittle32_t PointerToNextFunction;
- char Unused3[2];
-};
-
-static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
- "auxiliary entry must be 18 bytes");
-
-struct coff_aux_weak_external {
- support::ulittle32_t TagIndex;
- support::ulittle32_t Characteristics;
- char Unused1[10];
-};
-
-static_assert(sizeof(coff_aux_weak_external) == 18,
- "auxiliary entry must be 18 bytes");
-
-struct coff_aux_section_definition {
- support::ulittle32_t Length;
- support::ulittle16_t NumberOfRelocations;
- support::ulittle16_t NumberOfLinenumbers;
- support::ulittle32_t CheckSum;
- support::ulittle16_t NumberLowPart;
- uint8_t Selection;
- uint8_t Unused;
- support::ulittle16_t NumberHighPart;
- int32_t getNumber(bool IsBigObj) const {
- uint32_t Number = static_cast<uint32_t>(NumberLowPart);
- if (IsBigObj)
- Number |= static_cast<uint32_t>(NumberHighPart) << 16;
- return static_cast<int32_t>(Number);
- }
-};
-
-static_assert(sizeof(coff_aux_section_definition) == 18,
- "auxiliary entry must be 18 bytes");
-
-struct coff_aux_clr_token {
- uint8_t AuxType;
- uint8_t Reserved;
- support::ulittle32_t SymbolTableIndex;
- char MBZ[12];
-};
-
-static_assert(sizeof(coff_aux_clr_token) == 18,
- "auxiliary entry must be 18 bytes");
-
-struct coff_import_header {
- support::ulittle16_t Sig1;
- support::ulittle16_t Sig2;
- support::ulittle16_t Version;
- support::ulittle16_t Machine;
- support::ulittle32_t TimeDateStamp;
- support::ulittle32_t SizeOfData;
- support::ulittle16_t OrdinalHint;
- support::ulittle16_t TypeInfo;
-
- int getType() const { return TypeInfo & 0x3; }
- int getNameType() const { return (TypeInfo >> 2) & 0x7; }
-};
-
-struct coff_import_directory_table_entry {
- support::ulittle32_t ImportLookupTableRVA;
- support::ulittle32_t TimeDateStamp;
- support::ulittle32_t ForwarderChain;
- support::ulittle32_t NameRVA;
- support::ulittle32_t ImportAddressTableRVA;
-
- bool isNull() const {
- return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
- ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
- }
-};
-
-template <typename IntTy>
-struct coff_tls_directory {
- IntTy StartAddressOfRawData;
- IntTy EndAddressOfRawData;
- IntTy AddressOfIndex;
- IntTy AddressOfCallBacks;
- support::ulittle32_t SizeOfZeroFill;
- support::ulittle32_t Characteristics;
-
- uint32_t getAlignment() const {
- // Bit [20:24] contains section alignment.
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- COFF.h - COFF object file implementation -----------------*- 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 COFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_H
+#define LLVM_OBJECT_COFF_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/CVDebugRecord.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+
+template <typename T> class ArrayRef;
+
+namespace object {
+
+class BaseRelocRef;
+class DelayImportDirectoryEntryRef;
+class ExportDirectoryEntryRef;
+class ImportDirectoryEntryRef;
+class ImportedSymbolRef;
+class ResourceSectionRef;
+
+using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
+using delay_import_directory_iterator =
+ content_iterator<DelayImportDirectoryEntryRef>;
+using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
+using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
+using base_reloc_iterator = content_iterator<BaseRelocRef>;
+
+/// The DOS compatible header at the front of all PE/COFF executables.
+struct dos_header {
+ char Magic[2];
+ support::ulittle16_t UsedBytesInTheLastPage;
+ support::ulittle16_t FileSizeInPages;
+ support::ulittle16_t NumberOfRelocationItems;
+ support::ulittle16_t HeaderSizeInParagraphs;
+ support::ulittle16_t MinimumExtraParagraphs;
+ support::ulittle16_t MaximumExtraParagraphs;
+ support::ulittle16_t InitialRelativeSS;
+ support::ulittle16_t InitialSP;
+ support::ulittle16_t Checksum;
+ support::ulittle16_t InitialIP;
+ support::ulittle16_t InitialRelativeCS;
+ support::ulittle16_t AddressOfRelocationTable;
+ support::ulittle16_t OverlayNumber;
+ support::ulittle16_t Reserved[4];
+ support::ulittle16_t OEMid;
+ support::ulittle16_t OEMinfo;
+ support::ulittle16_t Reserved2[10];
+ support::ulittle32_t AddressOfNewExeHeader;
+};
+
+struct coff_file_header {
+ support::ulittle16_t Machine;
+ support::ulittle16_t NumberOfSections;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t PointerToSymbolTable;
+ support::ulittle32_t NumberOfSymbols;
+ support::ulittle16_t SizeOfOptionalHeader;
+ support::ulittle16_t Characteristics;
+
+ bool isImportLibrary() const { return NumberOfSections == 0xffff; }
+};
+
+struct coff_bigobj_file_header {
+ support::ulittle16_t Sig1;
+ support::ulittle16_t Sig2;
+ support::ulittle16_t Version;
+ support::ulittle16_t Machine;
+ support::ulittle32_t TimeDateStamp;
+ uint8_t UUID[16];
+ support::ulittle32_t unused1;
+ support::ulittle32_t unused2;
+ support::ulittle32_t unused3;
+ support::ulittle32_t unused4;
+ support::ulittle32_t NumberOfSections;
+ support::ulittle32_t PointerToSymbolTable;
+ support::ulittle32_t NumberOfSymbols;
+};
+
+/// The 32-bit PE header that follows the COFF header.
+struct pe32_header {
+ support::ulittle16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ support::ulittle32_t SizeOfCode;
+ support::ulittle32_t SizeOfInitializedData;
+ support::ulittle32_t SizeOfUninitializedData;
+ support::ulittle32_t AddressOfEntryPoint;
+ support::ulittle32_t BaseOfCode;
+ support::ulittle32_t BaseOfData;
+ support::ulittle32_t ImageBase;
+ support::ulittle32_t SectionAlignment;
+ support::ulittle32_t FileAlignment;
+ support::ulittle16_t MajorOperatingSystemVersion;
+ support::ulittle16_t MinorOperatingSystemVersion;
+ support::ulittle16_t MajorImageVersion;
+ support::ulittle16_t MinorImageVersion;
+ support::ulittle16_t MajorSubsystemVersion;
+ support::ulittle16_t MinorSubsystemVersion;
+ support::ulittle32_t Win32VersionValue;
+ support::ulittle32_t SizeOfImage;
+ support::ulittle32_t SizeOfHeaders;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t Subsystem;
+ // FIXME: This should be DllCharacteristics.
+ support::ulittle16_t DLLCharacteristics;
+ support::ulittle32_t SizeOfStackReserve;
+ support::ulittle32_t SizeOfStackCommit;
+ support::ulittle32_t SizeOfHeapReserve;
+ support::ulittle32_t SizeOfHeapCommit;
+ support::ulittle32_t LoaderFlags;
+ // FIXME: This should be NumberOfRvaAndSizes.
+ support::ulittle32_t NumberOfRvaAndSize;
+};
+
+/// The 64-bit PE header that follows the COFF header.
+struct pe32plus_header {
+ support::ulittle16_t Magic;
+ uint8_t MajorLinkerVersion;
+ uint8_t MinorLinkerVersion;
+ support::ulittle32_t SizeOfCode;
+ support::ulittle32_t SizeOfInitializedData;
+ support::ulittle32_t SizeOfUninitializedData;
+ support::ulittle32_t AddressOfEntryPoint;
+ support::ulittle32_t BaseOfCode;
+ support::ulittle64_t ImageBase;
+ support::ulittle32_t SectionAlignment;
+ support::ulittle32_t FileAlignment;
+ support::ulittle16_t MajorOperatingSystemVersion;
+ support::ulittle16_t MinorOperatingSystemVersion;
+ support::ulittle16_t MajorImageVersion;
+ support::ulittle16_t MinorImageVersion;
+ support::ulittle16_t MajorSubsystemVersion;
+ support::ulittle16_t MinorSubsystemVersion;
+ support::ulittle32_t Win32VersionValue;
+ support::ulittle32_t SizeOfImage;
+ support::ulittle32_t SizeOfHeaders;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t Subsystem;
+ support::ulittle16_t DLLCharacteristics;
+ support::ulittle64_t SizeOfStackReserve;
+ support::ulittle64_t SizeOfStackCommit;
+ support::ulittle64_t SizeOfHeapReserve;
+ support::ulittle64_t SizeOfHeapCommit;
+ support::ulittle32_t LoaderFlags;
+ support::ulittle32_t NumberOfRvaAndSize;
+};
+
+struct data_directory {
+ support::ulittle32_t RelativeVirtualAddress;
+ support::ulittle32_t Size;
+};
+
+struct debug_directory {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t Type;
+ support::ulittle32_t SizeOfData;
+ support::ulittle32_t AddressOfRawData;
+ support::ulittle32_t PointerToRawData;
+};
+
+template <typename IntTy>
+struct import_lookup_table_entry {
+ IntTy Data;
+
+ bool isOrdinal() const { return Data < 0; }
+
+ uint16_t getOrdinal() const {
+ assert(isOrdinal() && "ILT entry is not an ordinal!");
+ return Data & 0xFFFF;
+ }
+
+ uint32_t getHintNameRVA() const {
+ assert(!isOrdinal() && "ILT entry is not a Hint/Name RVA!");
+ return Data & 0xFFFFFFFF;
+ }
+};
+
+using import_lookup_table_entry32 =
+ import_lookup_table_entry<support::little32_t>;
+using import_lookup_table_entry64 =
+ import_lookup_table_entry<support::little64_t>;
+
+struct delay_import_directory_table_entry {
+ // dumpbin reports this field as "Characteristics" instead of "Attributes".
+ support::ulittle32_t Attributes;
+ support::ulittle32_t Name;
+ support::ulittle32_t ModuleHandle;
+ support::ulittle32_t DelayImportAddressTable;
+ support::ulittle32_t DelayImportNameTable;
+ support::ulittle32_t BoundDelayImportTable;
+ support::ulittle32_t UnloadDelayImportTable;
+ support::ulittle32_t TimeStamp;
+};
+
+struct export_directory_table_entry {
+ support::ulittle32_t ExportFlags;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t OrdinalBase;
+ support::ulittle32_t AddressTableEntries;
+ support::ulittle32_t NumberOfNamePointers;
+ support::ulittle32_t ExportAddressTableRVA;
+ support::ulittle32_t NamePointerRVA;
+ support::ulittle32_t OrdinalTableRVA;
+};
+
+union export_address_table_entry {
+ support::ulittle32_t ExportRVA;
+ support::ulittle32_t ForwarderRVA;
+};
+
+using export_name_pointer_table_entry = support::ulittle32_t;
+using export_ordinal_table_entry = support::ulittle16_t;
+
+struct StringTableOffset {
+ support::ulittle32_t Zeroes;
+ support::ulittle32_t Offset;
+};
+
+template <typename SectionNumberType>
+struct coff_symbol {
+ union {
+ char ShortName[COFF::NameSize];
+ StringTableOffset Offset;
+ } Name;
+
+ support::ulittle32_t Value;
+ SectionNumberType SectionNumber;
+
+ support::ulittle16_t Type;
+
+ uint8_t StorageClass;
+ uint8_t NumberOfAuxSymbols;
+};
+
+using coff_symbol16 = coff_symbol<support::ulittle16_t>;
+using coff_symbol32 = coff_symbol<support::ulittle32_t>;
+
+// Contains only common parts of coff_symbol16 and coff_symbol32.
+struct coff_symbol_generic {
+ union {
+ char ShortName[COFF::NameSize];
+ StringTableOffset Offset;
+ } Name;
+ support::ulittle32_t Value;
+};
+
+struct coff_aux_section_definition;
+struct coff_aux_weak_external;
+
+class COFFSymbolRef {
+public:
+ COFFSymbolRef() = default;
+ COFFSymbolRef(const coff_symbol16 *CS) : CS16(CS) {}
+ COFFSymbolRef(const coff_symbol32 *CS) : CS32(CS) {}
+
+ const void *getRawPtr() const {
+ return CS16 ? static_cast<const void *>(CS16) : CS32;
+ }
+
+ const coff_symbol_generic *getGeneric() const {
+ if (CS16)
+ return reinterpret_cast<const coff_symbol_generic *>(CS16);
+ return reinterpret_cast<const coff_symbol_generic *>(CS32);
+ }
+
+ friend bool operator<(COFFSymbolRef A, COFFSymbolRef B) {
+ return A.getRawPtr() < B.getRawPtr();
+ }
+
+ bool isBigObj() const {
+ if (CS16)
+ return false;
+ if (CS32)
+ return true;
+ llvm_unreachable("COFFSymbolRef points to nothing!");
+ }
+
+ const char *getShortName() const {
+ return CS16 ? CS16->Name.ShortName : CS32->Name.ShortName;
+ }
+
+ const StringTableOffset &getStringTableOffset() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Name.Offset : CS32->Name.Offset;
+ }
+
+ uint32_t getValue() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Value : CS32->Value;
+ }
+
+ int32_t getSectionNumber() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ if (CS16) {
+ // Reserved sections are returned as negative numbers.
+ if (CS16->SectionNumber <= COFF::MaxNumberOfSections16)
+ return CS16->SectionNumber;
+ return static_cast<int16_t>(CS16->SectionNumber);
+ }
+ return static_cast<int32_t>(CS32->SectionNumber);
+ }
+
+ uint16_t getType() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->Type : CS32->Type;
+ }
+
+ uint8_t getStorageClass() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->StorageClass : CS32->StorageClass;
+ }
+
+ uint8_t getNumberOfAuxSymbols() const {
+ assert(isSet() && "COFFSymbolRef points to nothing!");
+ return CS16 ? CS16->NumberOfAuxSymbols : CS32->NumberOfAuxSymbols;
+ }
+
+ uint8_t getBaseType() const { return getType() & 0x0F; }
+
+ uint8_t getComplexType() const {
+ return (getType() & 0xF0) >> COFF::SCT_COMPLEX_TYPE_SHIFT;
+ }
+
+ template <typename T> const T *getAux() const {
+ return CS16 ? reinterpret_cast<const T *>(CS16 + 1)
+ : reinterpret_cast<const T *>(CS32 + 1);
+ }
+
+ const coff_aux_section_definition *getSectionDefinition() const {
+ if (!getNumberOfAuxSymbols() ||
+ getStorageClass() != COFF::IMAGE_SYM_CLASS_STATIC)
+ return nullptr;
+ return getAux<coff_aux_section_definition>();
+ }
+
+ const coff_aux_weak_external *getWeakExternal() const {
+ if (!getNumberOfAuxSymbols() ||
+ getStorageClass() != COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL)
+ return nullptr;
+ return getAux<coff_aux_weak_external>();
+ }
+
+ bool isAbsolute() const {
+ return getSectionNumber() == -1;
+ }
+
+ bool isExternal() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL;
+ }
+
+ bool isCommon() const {
+ return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
+ getValue() != 0;
+ }
+
+ bool isUndefined() const {
+ return isExternal() && getSectionNumber() == COFF::IMAGE_SYM_UNDEFINED &&
+ getValue() == 0;
+ }
+
+ bool isWeakExternal() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
+ }
+
+ bool isFunctionDefinition() const {
+ return isExternal() && getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
+ getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
+ !COFF::isReservedSectionNumber(getSectionNumber());
+ }
+
+ bool isFunctionLineInfo() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_FUNCTION;
+ }
+
+ bool isAnyUndefined() const {
+ return isUndefined() || isWeakExternal();
+ }
+
+ bool isFileRecord() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_FILE;
+ }
+
+ bool isSection() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_SECTION;
+ }
+
+ bool isSectionDefinition() const {
+ // C++/CLI creates external ABS symbols for non-const appdomain globals.
+ // These are also followed by an auxiliary section definition.
+ bool isAppdomainGlobal =
+ getStorageClass() == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
+ getSectionNumber() == COFF::IMAGE_SYM_ABSOLUTE;
+ bool isOrdinarySection = getStorageClass() == COFF::IMAGE_SYM_CLASS_STATIC;
+ if (!getNumberOfAuxSymbols())
+ return false;
+ return isAppdomainGlobal || isOrdinarySection;
+ }
+
+ bool isCLRToken() const {
+ return getStorageClass() == COFF::IMAGE_SYM_CLASS_CLR_TOKEN;
+ }
+
+private:
+ bool isSet() const { return CS16 || CS32; }
+
+ const coff_symbol16 *CS16 = nullptr;
+ const coff_symbol32 *CS32 = nullptr;
+};
+
+struct coff_section {
+ char Name[COFF::NameSize];
+ support::ulittle32_t VirtualSize;
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SizeOfRawData;
+ support::ulittle32_t PointerToRawData;
+ support::ulittle32_t PointerToRelocations;
+ support::ulittle32_t PointerToLinenumbers;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t Characteristics;
+
+ // Returns true if the actual number of relocations is stored in
+ // VirtualAddress field of the first relocation table entry.
+ bool hasExtendedRelocations() const {
+ return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
+ NumberOfRelocations == UINT16_MAX;
+ }
+
+ uint32_t getAlignment() const {
+ // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
+ // IMAGE_SCN_ALIGN_1BYTES.
+ if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
+ return 1;
+
+ // Bit [20:24] contains section alignment. 0 means use a default alignment
+ // of 16.
+ uint32_t Shift = (Characteristics >> 20) & 0xF;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 16;
+ }
+};
+
+struct coff_relocation {
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SymbolTableIndex;
+ support::ulittle16_t Type;
+};
+
+struct coff_aux_function_definition {
+ support::ulittle32_t TagIndex;
+ support::ulittle32_t TotalSize;
+ support::ulittle32_t PointerToLinenumber;
+ support::ulittle32_t PointerToNextFunction;
+ char Unused1[2];
+};
+
+static_assert(sizeof(coff_aux_function_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_bf_and_ef_symbol {
+ char Unused1[4];
+ support::ulittle16_t Linenumber;
+ char Unused2[6];
+ support::ulittle32_t PointerToNextFunction;
+ char Unused3[2];
+};
+
+static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_weak_external {
+ support::ulittle32_t TagIndex;
+ support::ulittle32_t Characteristics;
+ char Unused1[10];
+};
+
+static_assert(sizeof(coff_aux_weak_external) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_section_definition {
+ support::ulittle32_t Length;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t CheckSum;
+ support::ulittle16_t NumberLowPart;
+ uint8_t Selection;
+ uint8_t Unused;
+ support::ulittle16_t NumberHighPart;
+ int32_t getNumber(bool IsBigObj) const {
+ uint32_t Number = static_cast<uint32_t>(NumberLowPart);
+ if (IsBigObj)
+ Number |= static_cast<uint32_t>(NumberHighPart) << 16;
+ return static_cast<int32_t>(Number);
+ }
+};
+
+static_assert(sizeof(coff_aux_section_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_aux_clr_token {
+ uint8_t AuxType;
+ uint8_t Reserved;
+ support::ulittle32_t SymbolTableIndex;
+ char MBZ[12];
+};
+
+static_assert(sizeof(coff_aux_clr_token) == 18,
+ "auxiliary entry must be 18 bytes");
+
+struct coff_import_header {
+ support::ulittle16_t Sig1;
+ support::ulittle16_t Sig2;
+ support::ulittle16_t Version;
+ support::ulittle16_t Machine;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t SizeOfData;
+ support::ulittle16_t OrdinalHint;
+ support::ulittle16_t TypeInfo;
+
+ int getType() const { return TypeInfo & 0x3; }
+ int getNameType() const { return (TypeInfo >> 2) & 0x7; }
+};
+
+struct coff_import_directory_table_entry {
+ support::ulittle32_t ImportLookupTableRVA;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t ForwarderChain;
+ support::ulittle32_t NameRVA;
+ support::ulittle32_t ImportAddressTableRVA;
+
+ bool isNull() const {
+ return ImportLookupTableRVA == 0 && TimeDateStamp == 0 &&
+ ForwarderChain == 0 && NameRVA == 0 && ImportAddressTableRVA == 0;
+ }
+};
+
+template <typename IntTy>
+struct coff_tls_directory {
+ IntTy StartAddressOfRawData;
+ IntTy EndAddressOfRawData;
+ IntTy AddressOfIndex;
+ IntTy AddressOfCallBacks;
+ support::ulittle32_t SizeOfZeroFill;
+ support::ulittle32_t Characteristics;
+
+ uint32_t getAlignment() const {
+ // Bit [20:24] contains section alignment.
uint32_t Shift = (Characteristics & COFF::IMAGE_SCN_ALIGN_MASK) >> 20;
- if (Shift > 0)
- return 1U << (Shift - 1);
- return 0;
- }
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 0;
+ }
void setAlignment(uint32_t Align) {
uint32_t AlignBits = 0;
@@ -599,404 +599,404 @@ struct coff_tls_directory {
Characteristics =
(Characteristics & ~COFF::IMAGE_SCN_ALIGN_MASK) | AlignBits;
}
-};
-
-using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
-using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
-
-/// Bits in control flow guard flags as we understand them.
-enum class coff_guard_flags : uint32_t {
- CFInstrumented = 0x00000100,
- HasFidTable = 0x00000400,
- ProtectDelayLoadIAT = 0x00001000,
- DelayLoadIATSection = 0x00002000, // Delay load in separate section
- HasLongJmpTable = 0x00010000,
- FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
-};
-
-enum class frame_type : uint16_t { Fpo = 0, Trap = 1, Tss = 2, NonFpo = 3 };
-
-struct coff_load_config_code_integrity {
- support::ulittle16_t Flags;
- support::ulittle16_t Catalog;
- support::ulittle32_t CatalogOffset;
- support::ulittle32_t Reserved;
-};
-
-/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
-struct coff_load_configuration32 {
- support::ulittle32_t Size;
- support::ulittle32_t TimeDateStamp;
- support::ulittle16_t MajorVersion;
- support::ulittle16_t MinorVersion;
- support::ulittle32_t GlobalFlagsClear;
- support::ulittle32_t GlobalFlagsSet;
- support::ulittle32_t CriticalSectionDefaultTimeout;
- support::ulittle32_t DeCommitFreeBlockThreshold;
- support::ulittle32_t DeCommitTotalFreeThreshold;
- support::ulittle32_t LockPrefixTable;
- support::ulittle32_t MaximumAllocationSize;
- support::ulittle32_t VirtualMemoryThreshold;
- support::ulittle32_t ProcessAffinityMask;
- support::ulittle32_t ProcessHeapFlags;
- support::ulittle16_t CSDVersion;
- support::ulittle16_t DependentLoadFlags;
- support::ulittle32_t EditList;
- support::ulittle32_t SecurityCookie;
- support::ulittle32_t SEHandlerTable;
- support::ulittle32_t SEHandlerCount;
-
- // Added in MSVC 2015 for /guard:cf.
- support::ulittle32_t GuardCFCheckFunction;
- support::ulittle32_t GuardCFCheckDispatch;
- support::ulittle32_t GuardCFFunctionTable;
- support::ulittle32_t GuardCFFunctionCount;
- support::ulittle32_t GuardFlags; // coff_guard_flags
-
- // Added in MSVC 2017
- coff_load_config_code_integrity CodeIntegrity;
- support::ulittle32_t GuardAddressTakenIatEntryTable;
- support::ulittle32_t GuardAddressTakenIatEntryCount;
- support::ulittle32_t GuardLongJumpTargetTable;
- support::ulittle32_t GuardLongJumpTargetCount;
- support::ulittle32_t DynamicValueRelocTable;
- support::ulittle32_t CHPEMetadataPointer;
- support::ulittle32_t GuardRFFailureRoutine;
- support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
- support::ulittle32_t DynamicValueRelocTableOffset;
- support::ulittle16_t DynamicValueRelocTableSection;
- support::ulittle16_t Reserved2;
- support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
- support::ulittle32_t HotPatchTableOffset;
-};
-
-/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
-struct coff_load_configuration64 {
- support::ulittle32_t Size;
- support::ulittle32_t TimeDateStamp;
- support::ulittle16_t MajorVersion;
- support::ulittle16_t MinorVersion;
- support::ulittle32_t GlobalFlagsClear;
- support::ulittle32_t GlobalFlagsSet;
- support::ulittle32_t CriticalSectionDefaultTimeout;
- support::ulittle64_t DeCommitFreeBlockThreshold;
- support::ulittle64_t DeCommitTotalFreeThreshold;
- support::ulittle64_t LockPrefixTable;
- support::ulittle64_t MaximumAllocationSize;
- support::ulittle64_t VirtualMemoryThreshold;
- support::ulittle64_t ProcessAffinityMask;
- support::ulittle32_t ProcessHeapFlags;
- support::ulittle16_t CSDVersion;
- support::ulittle16_t DependentLoadFlags;
- support::ulittle64_t EditList;
- support::ulittle64_t SecurityCookie;
- support::ulittle64_t SEHandlerTable;
- support::ulittle64_t SEHandlerCount;
-
- // Added in MSVC 2015 for /guard:cf.
- support::ulittle64_t GuardCFCheckFunction;
- support::ulittle64_t GuardCFCheckDispatch;
- support::ulittle64_t GuardCFFunctionTable;
- support::ulittle64_t GuardCFFunctionCount;
- support::ulittle32_t GuardFlags;
-
- // Added in MSVC 2017
- coff_load_config_code_integrity CodeIntegrity;
- support::ulittle64_t GuardAddressTakenIatEntryTable;
- support::ulittle64_t GuardAddressTakenIatEntryCount;
- support::ulittle64_t GuardLongJumpTargetTable;
- support::ulittle64_t GuardLongJumpTargetCount;
- support::ulittle64_t DynamicValueRelocTable;
- support::ulittle64_t CHPEMetadataPointer;
- support::ulittle64_t GuardRFFailureRoutine;
- support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
- support::ulittle32_t DynamicValueRelocTableOffset;
- support::ulittle16_t DynamicValueRelocTableSection;
- support::ulittle16_t Reserved2;
- support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
- support::ulittle32_t HotPatchTableOffset;
-};
-
-struct coff_runtime_function_x64 {
- support::ulittle32_t BeginAddress;
- support::ulittle32_t EndAddress;
- support::ulittle32_t UnwindInformation;
-};
-
-struct coff_base_reloc_block_header {
- support::ulittle32_t PageRVA;
- support::ulittle32_t BlockSize;
-};
-
-struct coff_base_reloc_block_entry {
- support::ulittle16_t Data;
-
- int getType() const { return Data >> 12; }
- int getOffset() const { return Data & ((1 << 12) - 1); }
-};
-
-struct coff_resource_dir_entry {
- union {
- support::ulittle32_t NameOffset;
- support::ulittle32_t ID;
- uint32_t getNameOffset() const {
- return maskTrailingOnes<uint32_t>(31) & NameOffset;
- }
- // Even though the PE/COFF spec doesn't mention this, the high bit of a name
- // offset is set.
- void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
- } Identifier;
- union {
- support::ulittle32_t DataEntryOffset;
- support::ulittle32_t SubdirOffset;
-
- bool isSubDir() const { return SubdirOffset >> 31; }
- uint32_t value() const {
- return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
- }
-
- } Offset;
-};
-
-struct coff_resource_data_entry {
- support::ulittle32_t DataRVA;
- support::ulittle32_t DataSize;
- support::ulittle32_t Codepage;
- support::ulittle32_t Reserved;
-};
-
-struct coff_resource_dir_table {
- support::ulittle32_t Characteristics;
- support::ulittle32_t TimeDateStamp;
- support::ulittle16_t MajorVersion;
- support::ulittle16_t MinorVersion;
- support::ulittle16_t NumberOfNameEntries;
- support::ulittle16_t NumberOfIDEntries;
-};
-
-struct debug_h_header {
- support::ulittle32_t Magic;
- support::ulittle16_t Version;
- support::ulittle16_t HashAlgorithm;
-};
-
-class COFFObjectFile : public ObjectFile {
-private:
- COFFObjectFile(MemoryBufferRef Object);
-
- friend class ImportDirectoryEntryRef;
- friend class ExportDirectoryEntryRef;
- const coff_file_header *COFFHeader;
- const coff_bigobj_file_header *COFFBigObjHeader;
- const pe32_header *PE32Header;
- const pe32plus_header *PE32PlusHeader;
- const data_directory *DataDirectory;
- const coff_section *SectionTable;
- const coff_symbol16 *SymbolTable16;
- const coff_symbol32 *SymbolTable32;
- const char *StringTable;
- uint32_t StringTableSize;
- const coff_import_directory_table_entry *ImportDirectory;
- const delay_import_directory_table_entry *DelayImportDirectory;
- uint32_t NumberOfDelayImportDirectory;
- const export_directory_table_entry *ExportDirectory;
- const coff_base_reloc_block_header *BaseRelocHeader;
- const coff_base_reloc_block_header *BaseRelocEnd;
- const debug_directory *DebugDirectoryBegin;
- const debug_directory *DebugDirectoryEnd;
+};
+
+using coff_tls_directory32 = coff_tls_directory<support::little32_t>;
+using coff_tls_directory64 = coff_tls_directory<support::little64_t>;
+
+/// Bits in control flow guard flags as we understand them.
+enum class coff_guard_flags : uint32_t {
+ CFInstrumented = 0x00000100,
+ HasFidTable = 0x00000400,
+ ProtectDelayLoadIAT = 0x00001000,
+ DelayLoadIATSection = 0x00002000, // Delay load in separate section
+ HasLongJmpTable = 0x00010000,
+ FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes
+};
+
+enum class frame_type : uint16_t { Fpo = 0, Trap = 1, Tss = 2, NonFpo = 3 };
+
+struct coff_load_config_code_integrity {
+ support::ulittle16_t Flags;
+ support::ulittle16_t Catalog;
+ support::ulittle32_t CatalogOffset;
+ support::ulittle32_t Reserved;
+};
+
+/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32)
+struct coff_load_configuration32 {
+ support::ulittle32_t Size;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t GlobalFlagsClear;
+ support::ulittle32_t GlobalFlagsSet;
+ support::ulittle32_t CriticalSectionDefaultTimeout;
+ support::ulittle32_t DeCommitFreeBlockThreshold;
+ support::ulittle32_t DeCommitTotalFreeThreshold;
+ support::ulittle32_t LockPrefixTable;
+ support::ulittle32_t MaximumAllocationSize;
+ support::ulittle32_t VirtualMemoryThreshold;
+ support::ulittle32_t ProcessAffinityMask;
+ support::ulittle32_t ProcessHeapFlags;
+ support::ulittle16_t CSDVersion;
+ support::ulittle16_t DependentLoadFlags;
+ support::ulittle32_t EditList;
+ support::ulittle32_t SecurityCookie;
+ support::ulittle32_t SEHandlerTable;
+ support::ulittle32_t SEHandlerCount;
+
+ // Added in MSVC 2015 for /guard:cf.
+ support::ulittle32_t GuardCFCheckFunction;
+ support::ulittle32_t GuardCFCheckDispatch;
+ support::ulittle32_t GuardCFFunctionTable;
+ support::ulittle32_t GuardCFFunctionCount;
+ support::ulittle32_t GuardFlags; // coff_guard_flags
+
+ // Added in MSVC 2017
+ coff_load_config_code_integrity CodeIntegrity;
+ support::ulittle32_t GuardAddressTakenIatEntryTable;
+ support::ulittle32_t GuardAddressTakenIatEntryCount;
+ support::ulittle32_t GuardLongJumpTargetTable;
+ support::ulittle32_t GuardLongJumpTargetCount;
+ support::ulittle32_t DynamicValueRelocTable;
+ support::ulittle32_t CHPEMetadataPointer;
+ support::ulittle32_t GuardRFFailureRoutine;
+ support::ulittle32_t GuardRFFailureRoutineFunctionPointer;
+ support::ulittle32_t DynamicValueRelocTableOffset;
+ support::ulittle16_t DynamicValueRelocTableSection;
+ support::ulittle16_t Reserved2;
+ support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer;
+ support::ulittle32_t HotPatchTableOffset;
+};
+
+/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64)
+struct coff_load_configuration64 {
+ support::ulittle32_t Size;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t GlobalFlagsClear;
+ support::ulittle32_t GlobalFlagsSet;
+ support::ulittle32_t CriticalSectionDefaultTimeout;
+ support::ulittle64_t DeCommitFreeBlockThreshold;
+ support::ulittle64_t DeCommitTotalFreeThreshold;
+ support::ulittle64_t LockPrefixTable;
+ support::ulittle64_t MaximumAllocationSize;
+ support::ulittle64_t VirtualMemoryThreshold;
+ support::ulittle64_t ProcessAffinityMask;
+ support::ulittle32_t ProcessHeapFlags;
+ support::ulittle16_t CSDVersion;
+ support::ulittle16_t DependentLoadFlags;
+ support::ulittle64_t EditList;
+ support::ulittle64_t SecurityCookie;
+ support::ulittle64_t SEHandlerTable;
+ support::ulittle64_t SEHandlerCount;
+
+ // Added in MSVC 2015 for /guard:cf.
+ support::ulittle64_t GuardCFCheckFunction;
+ support::ulittle64_t GuardCFCheckDispatch;
+ support::ulittle64_t GuardCFFunctionTable;
+ support::ulittle64_t GuardCFFunctionCount;
+ support::ulittle32_t GuardFlags;
+
+ // Added in MSVC 2017
+ coff_load_config_code_integrity CodeIntegrity;
+ support::ulittle64_t GuardAddressTakenIatEntryTable;
+ support::ulittle64_t GuardAddressTakenIatEntryCount;
+ support::ulittle64_t GuardLongJumpTargetTable;
+ support::ulittle64_t GuardLongJumpTargetCount;
+ support::ulittle64_t DynamicValueRelocTable;
+ support::ulittle64_t CHPEMetadataPointer;
+ support::ulittle64_t GuardRFFailureRoutine;
+ support::ulittle64_t GuardRFFailureRoutineFunctionPointer;
+ support::ulittle32_t DynamicValueRelocTableOffset;
+ support::ulittle16_t DynamicValueRelocTableSection;
+ support::ulittle16_t Reserved2;
+ support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer;
+ support::ulittle32_t HotPatchTableOffset;
+};
+
+struct coff_runtime_function_x64 {
+ support::ulittle32_t BeginAddress;
+ support::ulittle32_t EndAddress;
+ support::ulittle32_t UnwindInformation;
+};
+
+struct coff_base_reloc_block_header {
+ support::ulittle32_t PageRVA;
+ support::ulittle32_t BlockSize;
+};
+
+struct coff_base_reloc_block_entry {
+ support::ulittle16_t Data;
+
+ int getType() const { return Data >> 12; }
+ int getOffset() const { return Data & ((1 << 12) - 1); }
+};
+
+struct coff_resource_dir_entry {
+ union {
+ support::ulittle32_t NameOffset;
+ support::ulittle32_t ID;
+ uint32_t getNameOffset() const {
+ return maskTrailingOnes<uint32_t>(31) & NameOffset;
+ }
+ // Even though the PE/COFF spec doesn't mention this, the high bit of a name
+ // offset is set.
+ void setNameOffset(uint32_t Offset) { NameOffset = Offset | (1 << 31); }
+ } Identifier;
+ union {
+ support::ulittle32_t DataEntryOffset;
+ support::ulittle32_t SubdirOffset;
+
+ bool isSubDir() const { return SubdirOffset >> 31; }
+ uint32_t value() const {
+ return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
+ }
+
+ } Offset;
+};
+
+struct coff_resource_data_entry {
+ support::ulittle32_t DataRVA;
+ support::ulittle32_t DataSize;
+ support::ulittle32_t Codepage;
+ support::ulittle32_t Reserved;
+};
+
+struct coff_resource_dir_table {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle16_t NumberOfNameEntries;
+ support::ulittle16_t NumberOfIDEntries;
+};
+
+struct debug_h_header {
+ support::ulittle32_t Magic;
+ support::ulittle16_t Version;
+ support::ulittle16_t HashAlgorithm;
+};
+
+class COFFObjectFile : public ObjectFile {
+private:
+ COFFObjectFile(MemoryBufferRef Object);
+
+ friend class ImportDirectoryEntryRef;
+ friend class ExportDirectoryEntryRef;
+ const coff_file_header *COFFHeader;
+ const coff_bigobj_file_header *COFFBigObjHeader;
+ const pe32_header *PE32Header;
+ const pe32plus_header *PE32PlusHeader;
+ const data_directory *DataDirectory;
+ const coff_section *SectionTable;
+ const coff_symbol16 *SymbolTable16;
+ const coff_symbol32 *SymbolTable32;
+ const char *StringTable;
+ uint32_t StringTableSize;
+ const coff_import_directory_table_entry *ImportDirectory;
+ const delay_import_directory_table_entry *DelayImportDirectory;
+ uint32_t NumberOfDelayImportDirectory;
+ const export_directory_table_entry *ExportDirectory;
+ const coff_base_reloc_block_header *BaseRelocHeader;
+ const coff_base_reloc_block_header *BaseRelocEnd;
+ const debug_directory *DebugDirectoryBegin;
+ const debug_directory *DebugDirectoryEnd;
const coff_tls_directory32 *TLSDirectory32;
const coff_tls_directory64 *TLSDirectory64;
- // Either coff_load_configuration32 or coff_load_configuration64.
- const void *LoadConfig = nullptr;
-
- Expected<StringRef> getString(uint32_t offset) const;
-
- template <typename coff_symbol_type>
- const coff_symbol_type *toSymb(DataRefImpl Symb) const;
- const coff_section *toSec(DataRefImpl Sec) const;
- const coff_relocation *toRel(DataRefImpl Rel) const;
-
- // Finish initializing the object and return success or an error.
- Error initialize();
-
- Error initSymbolTablePtr();
- Error initImportTablePtr();
- Error initDelayImportTablePtr();
- Error initExportTablePtr();
- Error initBaseRelocPtr();
- Error initDebugDirectoryPtr();
+ // Either coff_load_configuration32 or coff_load_configuration64.
+ const void *LoadConfig = nullptr;
+
+ Expected<StringRef> getString(uint32_t offset) const;
+
+ template <typename coff_symbol_type>
+ const coff_symbol_type *toSymb(DataRefImpl Symb) const;
+ const coff_section *toSec(DataRefImpl Sec) const;
+ const coff_relocation *toRel(DataRefImpl Rel) const;
+
+ // Finish initializing the object and return success or an error.
+ Error initialize();
+
+ Error initSymbolTablePtr();
+ Error initImportTablePtr();
+ Error initDelayImportTablePtr();
+ Error initExportTablePtr();
+ Error initBaseRelocPtr();
+ Error initDebugDirectoryPtr();
Error initTLSDirectoryPtr();
- Error initLoadConfigPtr();
-
-public:
- static Expected<std::unique_ptr<COFFObjectFile>>
- create(MemoryBufferRef Object);
-
- uintptr_t getSymbolTable() const {
- if (SymbolTable16)
- return reinterpret_cast<uintptr_t>(SymbolTable16);
- if (SymbolTable32)
- return reinterpret_cast<uintptr_t>(SymbolTable32);
- return uintptr_t(0);
- }
-
- uint16_t getMachine() const {
- if (COFFHeader)
- return COFFHeader->Machine;
- if (COFFBigObjHeader)
- return COFFBigObjHeader->Machine;
- llvm_unreachable("no COFF header!");
- }
-
- uint16_t getSizeOfOptionalHeader() const {
- if (COFFHeader)
- return COFFHeader->isImportLibrary() ? 0
- : COFFHeader->SizeOfOptionalHeader;
- // bigobj doesn't have this field.
- if (COFFBigObjHeader)
- return 0;
- llvm_unreachable("no COFF header!");
- }
-
- uint16_t getCharacteristics() const {
- if (COFFHeader)
- return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
- // bigobj doesn't have characteristics to speak of,
- // editbin will silently lie to you if you attempt to set any.
- if (COFFBigObjHeader)
- return 0;
- llvm_unreachable("no COFF header!");
- }
-
- uint32_t getTimeDateStamp() const {
- if (COFFHeader)
- return COFFHeader->TimeDateStamp;
- if (COFFBigObjHeader)
- return COFFBigObjHeader->TimeDateStamp;
- llvm_unreachable("no COFF header!");
- }
-
- uint32_t getNumberOfSections() const {
- if (COFFHeader)
- return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
- if (COFFBigObjHeader)
- return COFFBigObjHeader->NumberOfSections;
- llvm_unreachable("no COFF header!");
- }
-
- uint32_t getPointerToSymbolTable() const {
- if (COFFHeader)
- return COFFHeader->isImportLibrary() ? 0
- : COFFHeader->PointerToSymbolTable;
- if (COFFBigObjHeader)
- return COFFBigObjHeader->PointerToSymbolTable;
- llvm_unreachable("no COFF header!");
- }
-
- uint32_t getRawNumberOfSymbols() const {
- if (COFFHeader)
- return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
- if (COFFBigObjHeader)
- return COFFBigObjHeader->NumberOfSymbols;
- llvm_unreachable("no COFF header!");
- }
-
- uint32_t getNumberOfSymbols() const {
- if (!SymbolTable16 && !SymbolTable32)
- return 0;
- return getRawNumberOfSymbols();
- }
-
- uint32_t getStringTableSize() const { return StringTableSize; }
-
- const coff_load_configuration32 *getLoadConfig32() const {
- assert(!is64());
- return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
- }
-
- const coff_load_configuration64 *getLoadConfig64() const {
- assert(is64());
- return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
- }
- StringRef getRelocationTypeName(uint16_t Type) const;
-
-protected:
- void moveSymbolNext(DataRefImpl &Symb) const override;
- Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
- Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
- uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
- uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
- uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
- Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
- Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
- void moveSectionNext(DataRefImpl &Sec) const override;
- Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
- uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
- uint64_t getSectionSize(DataRefImpl Sec) const override;
- Expected<ArrayRef<uint8_t>>
- getSectionContents(DataRefImpl Sec) const override;
- uint64_t getSectionAlignment(DataRefImpl Sec) const override;
- bool isSectionCompressed(DataRefImpl Sec) const override;
- bool isSectionText(DataRefImpl Sec) const override;
- bool isSectionData(DataRefImpl Sec) const override;
- bool isSectionBSS(DataRefImpl Sec) const override;
- bool isSectionVirtual(DataRefImpl Sec) const override;
- bool isDebugSection(StringRef SectionName) const override;
- relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
- relocation_iterator section_rel_end(DataRefImpl Sec) const override;
-
- void moveRelocationNext(DataRefImpl &Rel) const override;
- uint64_t getRelocationOffset(DataRefImpl Rel) const override;
- symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- uint64_t getRelocationType(DataRefImpl Rel) const override;
- void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
-
-public:
- basic_symbol_iterator symbol_begin() const override;
- basic_symbol_iterator symbol_end() const override;
- section_iterator section_begin() const override;
- section_iterator section_end() const override;
-
- const coff_section *getCOFFSection(const SectionRef &Section) const;
- COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
- COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
- const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
- unsigned getSectionID(SectionRef Sec) const;
- unsigned getSymbolSectionID(SymbolRef Sym) const;
-
- uint8_t getBytesInAddress() const override;
- StringRef getFileFormatName() const override;
- Triple::ArchType getArch() const override;
- Expected<uint64_t> getStartAddress() const override;
- SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
-
- import_directory_iterator import_directory_begin() const;
- import_directory_iterator import_directory_end() const;
- delay_import_directory_iterator delay_import_directory_begin() const;
- delay_import_directory_iterator delay_import_directory_end() const;
- export_directory_iterator export_directory_begin() const;
- export_directory_iterator export_directory_end() const;
- base_reloc_iterator base_reloc_begin() const;
- base_reloc_iterator base_reloc_end() const;
- const debug_directory *debug_directory_begin() const {
- return DebugDirectoryBegin;
- }
- const debug_directory *debug_directory_end() const {
- return DebugDirectoryEnd;
- }
-
- iterator_range<import_directory_iterator> import_directories() const;
- iterator_range<delay_import_directory_iterator>
- delay_import_directories() const;
- iterator_range<export_directory_iterator> export_directories() const;
- iterator_range<base_reloc_iterator> base_relocs() const;
- iterator_range<const debug_directory *> debug_directories() const {
- return make_range(debug_directory_begin(), debug_directory_end());
- }
-
+ Error initLoadConfigPtr();
+
+public:
+ static Expected<std::unique_ptr<COFFObjectFile>>
+ create(MemoryBufferRef Object);
+
+ uintptr_t getSymbolTable() const {
+ if (SymbolTable16)
+ return reinterpret_cast<uintptr_t>(SymbolTable16);
+ if (SymbolTable32)
+ return reinterpret_cast<uintptr_t>(SymbolTable32);
+ return uintptr_t(0);
+ }
+
+ uint16_t getMachine() const {
+ if (COFFHeader)
+ return COFFHeader->Machine;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->Machine;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint16_t getSizeOfOptionalHeader() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0
+ : COFFHeader->SizeOfOptionalHeader;
+ // bigobj doesn't have this field.
+ if (COFFBigObjHeader)
+ return 0;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint16_t getCharacteristics() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->Characteristics;
+ // bigobj doesn't have characteristics to speak of,
+ // editbin will silently lie to you if you attempt to set any.
+ if (COFFBigObjHeader)
+ return 0;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getTimeDateStamp() const {
+ if (COFFHeader)
+ return COFFHeader->TimeDateStamp;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->TimeDateStamp;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getNumberOfSections() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSections;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->NumberOfSections;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getPointerToSymbolTable() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0
+ : COFFHeader->PointerToSymbolTable;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->PointerToSymbolTable;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getRawNumberOfSymbols() const {
+ if (COFFHeader)
+ return COFFHeader->isImportLibrary() ? 0 : COFFHeader->NumberOfSymbols;
+ if (COFFBigObjHeader)
+ return COFFBigObjHeader->NumberOfSymbols;
+ llvm_unreachable("no COFF header!");
+ }
+
+ uint32_t getNumberOfSymbols() const {
+ if (!SymbolTable16 && !SymbolTable32)
+ return 0;
+ return getRawNumberOfSymbols();
+ }
+
+ uint32_t getStringTableSize() const { return StringTableSize; }
+
+ const coff_load_configuration32 *getLoadConfig32() const {
+ assert(!is64());
+ return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
+ }
+
+ const coff_load_configuration64 *getLoadConfig64() const {
+ assert(is64());
+ return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig);
+ }
+ StringRef getRelocationTypeName(uint16_t Type) const;
+
+protected:
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+public:
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ const coff_section *getCOFFSection(const SectionRef &Section) const;
+ COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const;
+ COFFSymbolRef getCOFFSymbol(const SymbolRef &Symbol) const;
+ const coff_relocation *getCOFFRelocation(const RelocationRef &Reloc) const;
+ unsigned getSectionID(SectionRef Sec) const;
+ unsigned getSymbolSectionID(SymbolRef Sym) const;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ Expected<uint64_t> getStartAddress() const override;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
+
+ import_directory_iterator import_directory_begin() const;
+ import_directory_iterator import_directory_end() const;
+ delay_import_directory_iterator delay_import_directory_begin() const;
+ delay_import_directory_iterator delay_import_directory_end() const;
+ export_directory_iterator export_directory_begin() const;
+ export_directory_iterator export_directory_end() const;
+ base_reloc_iterator base_reloc_begin() const;
+ base_reloc_iterator base_reloc_end() const;
+ const debug_directory *debug_directory_begin() const {
+ return DebugDirectoryBegin;
+ }
+ const debug_directory *debug_directory_end() const {
+ return DebugDirectoryEnd;
+ }
+
+ iterator_range<import_directory_iterator> import_directories() const;
+ iterator_range<delay_import_directory_iterator>
+ delay_import_directories() const;
+ iterator_range<export_directory_iterator> export_directories() const;
+ iterator_range<base_reloc_iterator> base_relocs() const;
+ iterator_range<const debug_directory *> debug_directories() const {
+ return make_range(debug_directory_begin(), debug_directory_end());
+ }
+
const coff_tls_directory32 *getTLSDirectory32() const {
return TLSDirectory32;
}
@@ -1004,288 +1004,288 @@ public:
return TLSDirectory64;
}
- const dos_header *getDOSHeader() const {
- if (!PE32Header && !PE32PlusHeader)
- return nullptr;
- return reinterpret_cast<const dos_header *>(base());
- }
-
- const coff_file_header *getCOFFHeader() const { return COFFHeader; }
- const coff_bigobj_file_header *getCOFFBigObjHeader() const {
- return COFFBigObjHeader;
- }
- const pe32_header *getPE32Header() const { return PE32Header; }
- const pe32plus_header *getPE32PlusHeader() const { return PE32PlusHeader; }
-
- const data_directory *getDataDirectory(uint32_t index) const;
- Expected<const coff_section *> getSection(int32_t index) const;
-
- Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
- if (index >= getNumberOfSymbols())
- return errorCodeToError(object_error::parse_failed);
- if (SymbolTable16)
- return COFFSymbolRef(SymbolTable16 + index);
- if (SymbolTable32)
- return COFFSymbolRef(SymbolTable32 + index);
- return errorCodeToError(object_error::parse_failed);
- }
-
- template <typename T>
- Error getAuxSymbol(uint32_t index, const T *&Res) const {
- Expected<COFFSymbolRef> S = getSymbol(index);
- if (Error E = S.takeError())
- return E;
- Res = reinterpret_cast<const T *>(S->getRawPtr());
- return Error::success();
- }
-
- Expected<StringRef> getSymbolName(COFFSymbolRef Symbol) const;
- Expected<StringRef> getSymbolName(const coff_symbol_generic *Symbol) const;
-
- ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
-
- uint32_t getSymbolIndex(COFFSymbolRef Symbol) const;
-
- size_t getSymbolTableEntrySize() const {
- if (COFFHeader)
- return sizeof(coff_symbol16);
- if (COFFBigObjHeader)
- return sizeof(coff_symbol32);
- llvm_unreachable("null symbol table pointer!");
- }
-
- ArrayRef<coff_relocation> getRelocations(const coff_section *Sec) const;
-
- Expected<StringRef> getSectionName(const coff_section *Sec) const;
- uint64_t getSectionSize(const coff_section *Sec) const;
- Error getSectionContents(const coff_section *Sec,
- ArrayRef<uint8_t> &Res) const;
-
- uint64_t getImageBase() const;
- Error getVaPtr(uint64_t VA, uintptr_t &Res) const;
- Error getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
-
- /// Given an RVA base and size, returns a valid array of bytes or an error
- /// code if the RVA and size is not contained completely within a valid
- /// section.
- Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
- ArrayRef<uint8_t> &Contents) const;
-
- Error getHintName(uint32_t Rva, uint16_t &Hint,
- StringRef &Name) const;
-
- /// Get PDB information out of a codeview debug directory entry.
- Error getDebugPDBInfo(const debug_directory *DebugDir,
- const codeview::DebugInfo *&Info,
- StringRef &PDBFileName) const;
-
- /// Get PDB information from an executable. If the information is not present,
- /// Info will be set to nullptr and PDBFileName will be empty. An error is
- /// returned only on corrupt object files. Convenience accessor that can be
- /// used if the debug directory is not already handy.
- Error getDebugPDBInfo(const codeview::DebugInfo *&Info,
- StringRef &PDBFileName) const;
-
- bool isRelocatableObject() const override;
- bool is64() const { return PE32PlusHeader; }
-
- StringRef mapDebugSectionName(StringRef Name) const override;
-
- static bool classof(const Binary *v) { return v->isCOFF(); }
-};
-
-// The iterator for the import directory table.
-class ImportDirectoryEntryRef {
-public:
- ImportDirectoryEntryRef() = default;
- ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
- uint32_t I, const COFFObjectFile *Owner)
- : ImportTable(Table), Index(I), OwningObject(Owner) {}
-
- bool operator==(const ImportDirectoryEntryRef &Other) const;
- void moveNext();
-
- imported_symbol_iterator imported_symbol_begin() const;
- imported_symbol_iterator imported_symbol_end() const;
- iterator_range<imported_symbol_iterator> imported_symbols() const;
-
- imported_symbol_iterator lookup_table_begin() const;
- imported_symbol_iterator lookup_table_end() const;
- iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
-
- Error getName(StringRef &Result) const;
- Error getImportLookupTableRVA(uint32_t &Result) const;
- Error getImportAddressTableRVA(uint32_t &Result) const;
-
- Error
- getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
-
-private:
- const coff_import_directory_table_entry *ImportTable;
- uint32_t Index;
- const COFFObjectFile *OwningObject = nullptr;
-};
-
-class DelayImportDirectoryEntryRef {
-public:
- DelayImportDirectoryEntryRef() = default;
- DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
- uint32_t I, const COFFObjectFile *Owner)
- : Table(T), Index(I), OwningObject(Owner) {}
-
- bool operator==(const DelayImportDirectoryEntryRef &Other) const;
- void moveNext();
-
- imported_symbol_iterator imported_symbol_begin() const;
- imported_symbol_iterator imported_symbol_end() const;
- iterator_range<imported_symbol_iterator> imported_symbols() const;
-
- Error getName(StringRef &Result) const;
- Error getDelayImportTable(
- const delay_import_directory_table_entry *&Result) const;
- Error getImportAddress(int AddrIndex, uint64_t &Result) const;
-
-private:
- const delay_import_directory_table_entry *Table;
- uint32_t Index;
- const COFFObjectFile *OwningObject = nullptr;
-};
-
-// The iterator for the export directory table entry.
-class ExportDirectoryEntryRef {
-public:
- ExportDirectoryEntryRef() = default;
- ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
- const COFFObjectFile *Owner)
- : ExportTable(Table), Index(I), OwningObject(Owner) {}
-
- bool operator==(const ExportDirectoryEntryRef &Other) const;
- void moveNext();
-
- Error getDllName(StringRef &Result) const;
- Error getOrdinalBase(uint32_t &Result) const;
- Error getOrdinal(uint32_t &Result) const;
- Error getExportRVA(uint32_t &Result) const;
- Error getSymbolName(StringRef &Result) const;
-
- Error isForwarder(bool &Result) const;
- Error getForwardTo(StringRef &Result) const;
-
-private:
- const export_directory_table_entry *ExportTable;
- uint32_t Index;
- const COFFObjectFile *OwningObject = nullptr;
-};
-
-class ImportedSymbolRef {
-public:
- ImportedSymbolRef() = default;
- ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
- const COFFObjectFile *Owner)
- : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
- ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
- const COFFObjectFile *Owner)
- : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}
-
- bool operator==(const ImportedSymbolRef &Other) const;
- void moveNext();
-
- Error getSymbolName(StringRef &Result) const;
- Error isOrdinal(bool &Result) const;
- Error getOrdinal(uint16_t &Result) const;
- Error getHintNameRVA(uint32_t &Result) const;
-
-private:
- const import_lookup_table_entry32 *Entry32;
- const import_lookup_table_entry64 *Entry64;
- uint32_t Index;
- const COFFObjectFile *OwningObject = nullptr;
-};
-
-class BaseRelocRef {
-public:
- BaseRelocRef() = default;
- BaseRelocRef(const coff_base_reloc_block_header *Header,
- const COFFObjectFile *Owner)
- : Header(Header), Index(0) {}
-
- bool operator==(const BaseRelocRef &Other) const;
- void moveNext();
-
- Error getType(uint8_t &Type) const;
- Error getRVA(uint32_t &Result) const;
-
-private:
- const coff_base_reloc_block_header *Header;
- uint32_t Index;
-};
-
-class ResourceSectionRef {
-public:
- ResourceSectionRef() = default;
- explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
-
- Error load(const COFFObjectFile *O);
- Error load(const COFFObjectFile *O, const SectionRef &S);
-
- Expected<ArrayRef<UTF16>>
- getEntryNameString(const coff_resource_dir_entry &Entry);
- Expected<const coff_resource_dir_table &>
- getEntrySubDir(const coff_resource_dir_entry &Entry);
- Expected<const coff_resource_data_entry &>
- getEntryData(const coff_resource_dir_entry &Entry);
- Expected<const coff_resource_dir_table &> getBaseTable();
- Expected<const coff_resource_dir_entry &>
- getTableEntry(const coff_resource_dir_table &Table, uint32_t Index);
-
- Expected<StringRef> getContents(const coff_resource_data_entry &Entry);
-
-private:
- BinaryByteStream BBS;
-
- SectionRef Section;
- const COFFObjectFile *Obj;
-
- std::vector<const coff_relocation *> Relocs;
-
- Expected<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
- Expected<const coff_resource_dir_entry &>
- getTableEntryAtOffset(uint32_t Offset);
- Expected<const coff_resource_data_entry &>
- getDataEntryAtOffset(uint32_t Offset);
- Expected<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
-};
-
-// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
-struct FpoData {
- support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
- support::ulittle32_t Size; // cbProcSize: # bytes in function
- support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
- support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
- support::ulittle16_t Attributes;
-
- // cbProlog: # bytes in prolog
- int getPrologSize() const { return Attributes & 0xF; }
-
- // cbRegs: # regs saved
- int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
-
- // fHasSEH: true if seh is func
- bool hasSEH() const { return (Attributes >> 9) & 1; }
-
- // fUseBP: true if EBP has been allocated
- bool useBP() const { return (Attributes >> 10) & 1; }
-
- // cbFrame: frame pointer
- frame_type getFP() const { return static_cast<frame_type>(Attributes >> 14); }
-};
-
-} // end namespace object
-
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_COFF_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+ const dos_header *getDOSHeader() const {
+ if (!PE32Header && !PE32PlusHeader)
+ return nullptr;
+ return reinterpret_cast<const dos_header *>(base());
+ }
+
+ const coff_file_header *getCOFFHeader() const { return COFFHeader; }
+ const coff_bigobj_file_header *getCOFFBigObjHeader() const {
+ return COFFBigObjHeader;
+ }
+ const pe32_header *getPE32Header() const { return PE32Header; }
+ const pe32plus_header *getPE32PlusHeader() const { return PE32PlusHeader; }
+
+ const data_directory *getDataDirectory(uint32_t index) const;
+ Expected<const coff_section *> getSection(int32_t index) const;
+
+ Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
+ if (index >= getNumberOfSymbols())
+ return errorCodeToError(object_error::parse_failed);
+ if (SymbolTable16)
+ return COFFSymbolRef(SymbolTable16 + index);
+ if (SymbolTable32)
+ return COFFSymbolRef(SymbolTable32 + index);
+ return errorCodeToError(object_error::parse_failed);
+ }
+
+ template <typename T>
+ Error getAuxSymbol(uint32_t index, const T *&Res) const {
+ Expected<COFFSymbolRef> S = getSymbol(index);
+ if (Error E = S.takeError())
+ return E;
+ Res = reinterpret_cast<const T *>(S->getRawPtr());
+ return Error::success();
+ }
+
+ Expected<StringRef> getSymbolName(COFFSymbolRef Symbol) const;
+ Expected<StringRef> getSymbolName(const coff_symbol_generic *Symbol) const;
+
+ ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
+
+ uint32_t getSymbolIndex(COFFSymbolRef Symbol) const;
+
+ size_t getSymbolTableEntrySize() const {
+ if (COFFHeader)
+ return sizeof(coff_symbol16);
+ if (COFFBigObjHeader)
+ return sizeof(coff_symbol32);
+ llvm_unreachable("null symbol table pointer!");
+ }
+
+ ArrayRef<coff_relocation> getRelocations(const coff_section *Sec) const;
+
+ Expected<StringRef> getSectionName(const coff_section *Sec) const;
+ uint64_t getSectionSize(const coff_section *Sec) const;
+ Error getSectionContents(const coff_section *Sec,
+ ArrayRef<uint8_t> &Res) const;
+
+ uint64_t getImageBase() const;
+ Error getVaPtr(uint64_t VA, uintptr_t &Res) const;
+ Error getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+
+ /// Given an RVA base and size, returns a valid array of bytes or an error
+ /// code if the RVA and size is not contained completely within a valid
+ /// section.
+ Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const;
+
+ Error getHintName(uint32_t Rva, uint16_t &Hint,
+ StringRef &Name) const;
+
+ /// Get PDB information out of a codeview debug directory entry.
+ Error getDebugPDBInfo(const debug_directory *DebugDir,
+ const codeview::DebugInfo *&Info,
+ StringRef &PDBFileName) const;
+
+ /// Get PDB information from an executable. If the information is not present,
+ /// Info will be set to nullptr and PDBFileName will be empty. An error is
+ /// returned only on corrupt object files. Convenience accessor that can be
+ /// used if the debug directory is not already handy.
+ Error getDebugPDBInfo(const codeview::DebugInfo *&Info,
+ StringRef &PDBFileName) const;
+
+ bool isRelocatableObject() const override;
+ bool is64() const { return PE32PlusHeader; }
+
+ StringRef mapDebugSectionName(StringRef Name) const override;
+
+ static bool classof(const Binary *v) { return v->isCOFF(); }
+};
+
+// The iterator for the import directory table.
+class ImportDirectoryEntryRef {
+public:
+ ImportDirectoryEntryRef() = default;
+ ImportDirectoryEntryRef(const coff_import_directory_table_entry *Table,
+ uint32_t I, const COFFObjectFile *Owner)
+ : ImportTable(Table), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ImportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ imported_symbol_iterator imported_symbol_begin() const;
+ imported_symbol_iterator imported_symbol_end() const;
+ iterator_range<imported_symbol_iterator> imported_symbols() const;
+
+ imported_symbol_iterator lookup_table_begin() const;
+ imported_symbol_iterator lookup_table_end() const;
+ iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
+
+ Error getName(StringRef &Result) const;
+ Error getImportLookupTableRVA(uint32_t &Result) const;
+ Error getImportAddressTableRVA(uint32_t &Result) const;
+
+ Error
+ getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
+
+private:
+ const coff_import_directory_table_entry *ImportTable;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class DelayImportDirectoryEntryRef {
+public:
+ DelayImportDirectoryEntryRef() = default;
+ DelayImportDirectoryEntryRef(const delay_import_directory_table_entry *T,
+ uint32_t I, const COFFObjectFile *Owner)
+ : Table(T), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const DelayImportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ imported_symbol_iterator imported_symbol_begin() const;
+ imported_symbol_iterator imported_symbol_end() const;
+ iterator_range<imported_symbol_iterator> imported_symbols() const;
+
+ Error getName(StringRef &Result) const;
+ Error getDelayImportTable(
+ const delay_import_directory_table_entry *&Result) const;
+ Error getImportAddress(int AddrIndex, uint64_t &Result) const;
+
+private:
+ const delay_import_directory_table_entry *Table;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+// The iterator for the export directory table entry.
+class ExportDirectoryEntryRef {
+public:
+ ExportDirectoryEntryRef() = default;
+ ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I,
+ const COFFObjectFile *Owner)
+ : ExportTable(Table), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ExportDirectoryEntryRef &Other) const;
+ void moveNext();
+
+ Error getDllName(StringRef &Result) const;
+ Error getOrdinalBase(uint32_t &Result) const;
+ Error getOrdinal(uint32_t &Result) const;
+ Error getExportRVA(uint32_t &Result) const;
+ Error getSymbolName(StringRef &Result) const;
+
+ Error isForwarder(bool &Result) const;
+ Error getForwardTo(StringRef &Result) const;
+
+private:
+ const export_directory_table_entry *ExportTable;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class ImportedSymbolRef {
+public:
+ ImportedSymbolRef() = default;
+ ImportedSymbolRef(const import_lookup_table_entry32 *Entry, uint32_t I,
+ const COFFObjectFile *Owner)
+ : Entry32(Entry), Entry64(nullptr), Index(I), OwningObject(Owner) {}
+ ImportedSymbolRef(const import_lookup_table_entry64 *Entry, uint32_t I,
+ const COFFObjectFile *Owner)
+ : Entry32(nullptr), Entry64(Entry), Index(I), OwningObject(Owner) {}
+
+ bool operator==(const ImportedSymbolRef &Other) const;
+ void moveNext();
+
+ Error getSymbolName(StringRef &Result) const;
+ Error isOrdinal(bool &Result) const;
+ Error getOrdinal(uint16_t &Result) const;
+ Error getHintNameRVA(uint32_t &Result) const;
+
+private:
+ const import_lookup_table_entry32 *Entry32;
+ const import_lookup_table_entry64 *Entry64;
+ uint32_t Index;
+ const COFFObjectFile *OwningObject = nullptr;
+};
+
+class BaseRelocRef {
+public:
+ BaseRelocRef() = default;
+ BaseRelocRef(const coff_base_reloc_block_header *Header,
+ const COFFObjectFile *Owner)
+ : Header(Header), Index(0) {}
+
+ bool operator==(const BaseRelocRef &Other) const;
+ void moveNext();
+
+ Error getType(uint8_t &Type) const;
+ Error getRVA(uint32_t &Result) const;
+
+private:
+ const coff_base_reloc_block_header *Header;
+ uint32_t Index;
+};
+
+class ResourceSectionRef {
+public:
+ ResourceSectionRef() = default;
+ explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
+
+ Error load(const COFFObjectFile *O);
+ Error load(const COFFObjectFile *O, const SectionRef &S);
+
+ Expected<ArrayRef<UTF16>>
+ getEntryNameString(const coff_resource_dir_entry &Entry);
+ Expected<const coff_resource_dir_table &>
+ getEntrySubDir(const coff_resource_dir_entry &Entry);
+ Expected<const coff_resource_data_entry &>
+ getEntryData(const coff_resource_dir_entry &Entry);
+ Expected<const coff_resource_dir_table &> getBaseTable();
+ Expected<const coff_resource_dir_entry &>
+ getTableEntry(const coff_resource_dir_table &Table, uint32_t Index);
+
+ Expected<StringRef> getContents(const coff_resource_data_entry &Entry);
+
+private:
+ BinaryByteStream BBS;
+
+ SectionRef Section;
+ const COFFObjectFile *Obj;
+
+ std::vector<const coff_relocation *> Relocs;
+
+ Expected<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
+ Expected<const coff_resource_dir_entry &>
+ getTableEntryAtOffset(uint32_t Offset);
+ Expected<const coff_resource_data_entry &>
+ getDataEntryAtOffset(uint32_t Offset);
+ Expected<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
+};
+
+// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
+struct FpoData {
+ support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
+ support::ulittle32_t Size; // cbProcSize: # bytes in function
+ support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
+ support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
+ support::ulittle16_t Attributes;
+
+ // cbProlog: # bytes in prolog
+ int getPrologSize() const { return Attributes & 0xF; }
+
+ // cbRegs: # regs saved
+ int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
+
+ // fHasSEH: true if seh is func
+ bool hasSEH() const { return (Attributes >> 9) & 1; }
+
+ // fUseBP: true if EBP has been allocated
+ bool useBP() const { return (Attributes >> 10) & 1; }
+
+ // cbFrame: frame pointer
+ frame_type getFP() const { return static_cast<frame_type>(Attributes >> 14); }
+};
+
+} // end namespace object
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_COFF_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/COFFImportFile.h b/contrib/libs/llvm12/include/llvm/Object/COFFImportFile.h
index d5d5a369dff..e45fa29270d 100644
--- a/contrib/libs/llvm12/include/llvm/Object/COFFImportFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/COFFImportFile.h
@@ -1,124 +1,124 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- COFFImportFile.h - COFF short import file implementation -*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// COFF short import file is a special kind of file which contains
-// only symbol names for DLL-exported symbols. This class implements
-// exporting of Symbols to create libraries and a SymbolicFile
-// interface for the file type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H
-#define LLVM_OBJECT_COFF_IMPORT_FILE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/IRObjectFile.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-namespace object {
-
-class COFFImportFile : public SymbolicFile {
-public:
- COFFImportFile(MemoryBufferRef Source)
- : SymbolicFile(ID_COFFImportFile, Source) {}
-
- static bool classof(Binary const *V) { return V->isCOFFImportFile(); }
-
- void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
-
- Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override {
- if (Symb.p == 0)
- OS << "__imp_";
- OS << StringRef(Data.getBufferStart() + sizeof(coff_import_header));
- return Error::success();
- }
-
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override {
- return SymbolRef::SF_Global;
- }
-
- basic_symbol_iterator symbol_begin() const override {
- return BasicSymbolRef(DataRefImpl(), this);
- }
-
- basic_symbol_iterator symbol_end() const override {
- DataRefImpl Symb;
- Symb.p = isData() ? 1 : 2;
- return BasicSymbolRef(Symb, this);
- }
-
- const coff_import_header *getCOFFImportHeader() const {
- return reinterpret_cast<const object::coff_import_header *>(
- Data.getBufferStart());
- }
-
-private:
- bool isData() const {
- return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
- }
-};
-
-struct COFFShortExport {
- /// The name of the export as specified in the .def file or on the command
- /// line, i.e. "foo" in "/EXPORT:foo", and "bar" in "/EXPORT:foo=bar". This
- /// may lack mangling, such as underscore prefixing and stdcall suffixing.
- std::string Name;
-
- /// The external, exported name. Only non-empty when export renaming is in
- /// effect, i.e. "foo" in "/EXPORT:foo=bar".
- std::string ExtName;
-
- /// The real, mangled symbol name from the object file. Given
- /// "/export:foo=bar", this could be "_bar@8" if bar is stdcall.
- std::string SymbolName;
-
- /// Creates a weak alias. This is the name of the weak aliasee. In a .def
- /// file, this is "baz" in "EXPORTS\nfoo = bar == baz".
- std::string AliasTarget;
-
- uint16_t Ordinal = 0;
- bool Noname = false;
- bool Data = false;
- bool Private = false;
- bool Constant = false;
-
- friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
- return L.Name == R.Name && L.ExtName == R.ExtName &&
- L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
- L.Data == R.Data && L.Private == R.Private;
- }
-
- friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
- return !(L == R);
- }
-};
-
-Error writeImportLibrary(StringRef ImportName, StringRef Path,
- ArrayRef<COFFShortExport> Exports,
- COFF::MachineTypes Machine, bool MinGW);
-
-} // namespace object
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- COFFImportFile.h - COFF short import file implementation -*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// COFF short import file is a special kind of file which contains
+// only symbol names for DLL-exported symbols. This class implements
+// exporting of Symbols to create libraries and a SymbolicFile
+// interface for the file type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_IMPORT_FILE_H
+#define LLVM_OBJECT_COFF_IMPORT_FILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace object {
+
+class COFFImportFile : public SymbolicFile {
+public:
+ COFFImportFile(MemoryBufferRef Source)
+ : SymbolicFile(ID_COFFImportFile, Source) {}
+
+ static bool classof(Binary const *V) { return V->isCOFFImportFile(); }
+
+ void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
+
+ Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override {
+ if (Symb.p == 0)
+ OS << "__imp_";
+ OS << StringRef(Data.getBufferStart() + sizeof(coff_import_header));
+ return Error::success();
+ }
+
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override {
+ return SymbolRef::SF_Global;
+ }
+
+ basic_symbol_iterator symbol_begin() const override {
+ return BasicSymbolRef(DataRefImpl(), this);
+ }
+
+ basic_symbol_iterator symbol_end() const override {
+ DataRefImpl Symb;
+ Symb.p = isData() ? 1 : 2;
+ return BasicSymbolRef(Symb, this);
+ }
+
+ const coff_import_header *getCOFFImportHeader() const {
+ return reinterpret_cast<const object::coff_import_header *>(
+ Data.getBufferStart());
+ }
+
+private:
+ bool isData() const {
+ return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
+ }
+};
+
+struct COFFShortExport {
+ /// The name of the export as specified in the .def file or on the command
+ /// line, i.e. "foo" in "/EXPORT:foo", and "bar" in "/EXPORT:foo=bar". This
+ /// may lack mangling, such as underscore prefixing and stdcall suffixing.
+ std::string Name;
+
+ /// The external, exported name. Only non-empty when export renaming is in
+ /// effect, i.e. "foo" in "/EXPORT:foo=bar".
+ std::string ExtName;
+
+ /// The real, mangled symbol name from the object file. Given
+ /// "/export:foo=bar", this could be "_bar@8" if bar is stdcall.
+ std::string SymbolName;
+
+ /// Creates a weak alias. This is the name of the weak aliasee. In a .def
+ /// file, this is "baz" in "EXPORTS\nfoo = bar == baz".
+ std::string AliasTarget;
+
+ uint16_t Ordinal = 0;
+ bool Noname = false;
+ bool Data = false;
+ bool Private = false;
+ bool Constant = false;
+
+ friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
+ return L.Name == R.Name && L.ExtName == R.ExtName &&
+ L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
+ L.Data == R.Data && L.Private == R.Private;
+ }
+
+ friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
+ return !(L == R);
+ }
+};
+
+Error writeImportLibrary(StringRef ImportName, StringRef Path,
+ ArrayRef<COFFShortExport> Exports,
+ COFF::MachineTypes Machine, bool MinGW);
+
+} // namespace object
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/COFFModuleDefinition.h b/contrib/libs/llvm12/include/llvm/Object/COFFModuleDefinition.h
index 3661c193331..3168d9cc9ee 100644
--- a/contrib/libs/llvm12/include/llvm/Object/COFFModuleDefinition.h
+++ b/contrib/libs/llvm12/include/llvm/Object/COFFModuleDefinition.h
@@ -1,63 +1,63 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===--- COFFModuleDefinition.h ---------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Windows-specific.
-// A parser for the module-definition file (.def file).
-// Parsed results are directly written to Config global variable.
-//
-// The format of module-definition files are described in this document:
-// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H
-#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H
-
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/COFFImportFile.h"
-
-namespace llvm {
-namespace object {
-
-struct COFFModuleDefinition {
- std::vector<COFFShortExport> Exports;
- std::string OutputFile;
- std::string ImportName;
- uint64_t ImageBase = 0;
- uint64_t StackReserve = 0;
- uint64_t StackCommit = 0;
- uint64_t HeapReserve = 0;
- uint64_t HeapCommit = 0;
- uint32_t MajorImageVersion = 0;
- uint32_t MinorImageVersion = 0;
- uint32_t MajorOSVersion = 0;
- uint32_t MinorOSVersion = 0;
-};
-
-// mingw and wine def files do not mangle _ for x86 which
-// is a consequence of legacy binutils' dlltool functionality.
-// This MingwDef flag should be removed once mingw stops this pratice.
-Expected<COFFModuleDefinition>
-parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine,
- bool MingwDef = false);
-
-} // End namespace object.
-} // End namespace llvm.
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===--- COFFModuleDefinition.h ---------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Windows-specific.
+// A parser for the module-definition file (.def file).
+// Parsed results are directly written to Config global variable.
+//
+// The format of module-definition files are described in this document:
+// https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_MODULE_DEFINITION_H
+#define LLVM_OBJECT_COFF_MODULE_DEFINITION_H
+
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
+
+namespace llvm {
+namespace object {
+
+struct COFFModuleDefinition {
+ std::vector<COFFShortExport> Exports;
+ std::string OutputFile;
+ std::string ImportName;
+ uint64_t ImageBase = 0;
+ uint64_t StackReserve = 0;
+ uint64_t StackCommit = 0;
+ uint64_t HeapReserve = 0;
+ uint64_t HeapCommit = 0;
+ uint32_t MajorImageVersion = 0;
+ uint32_t MinorImageVersion = 0;
+ uint32_t MajorOSVersion = 0;
+ uint32_t MinorOSVersion = 0;
+};
+
+// mingw and wine def files do not mangle _ for x86 which
+// is a consequence of legacy binutils' dlltool functionality.
+// This MingwDef flag should be removed once mingw stops this pratice.
+Expected<COFFModuleDefinition>
+parseCOFFModuleDefinition(MemoryBufferRef MB, COFF::MachineTypes Machine,
+ bool MingwDef = false);
+
+} // End namespace object.
+} // End namespace llvm.
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/CVDebugRecord.h b/contrib/libs/llvm12/include/llvm/Object/CVDebugRecord.h
index 17685635bfd..973975c4e36 100644
--- a/contrib/libs/llvm12/include/llvm/Object/CVDebugRecord.h
+++ b/contrib/libs/llvm12/include/llvm/Object/CVDebugRecord.h
@@ -1,65 +1,65 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- CVDebugRecord.h ------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_CVDEBUGRECORD_H
-#define LLVM_OBJECT_CVDEBUGRECORD_H
-
-#include "llvm/Support/Endian.h"
-
-namespace llvm {
-namespace OMF {
-struct Signature {
- enum ID : uint32_t {
- PDB70 = 0x53445352, // RSDS
- PDB20 = 0x3031424e, // NB10
- CV50 = 0x3131424e, // NB11
- CV41 = 0x3930424e, // NB09
- };
-
- support::ulittle32_t CVSignature;
- support::ulittle32_t Offset;
-};
-}
-
-namespace codeview {
-struct PDB70DebugInfo {
- support::ulittle32_t CVSignature;
- uint8_t Signature[16];
- support::ulittle32_t Age;
- // char PDBFileName[];
-};
-
-struct PDB20DebugInfo {
- support::ulittle32_t CVSignature;
- support::ulittle32_t Offset;
- support::ulittle32_t Signature;
- support::ulittle32_t Age;
- // char PDBFileName[];
-};
-
-union DebugInfo {
- struct OMF::Signature Signature;
- struct PDB20DebugInfo PDB20;
- struct PDB70DebugInfo PDB70;
-};
-}
-}
-
-#endif
-
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- CVDebugRecord.h ------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_CVDEBUGRECORD_H
+#define LLVM_OBJECT_CVDEBUGRECORD_H
+
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace OMF {
+struct Signature {
+ enum ID : uint32_t {
+ PDB70 = 0x53445352, // RSDS
+ PDB20 = 0x3031424e, // NB10
+ CV50 = 0x3131424e, // NB11
+ CV41 = 0x3930424e, // NB09
+ };
+
+ support::ulittle32_t CVSignature;
+ support::ulittle32_t Offset;
+};
+}
+
+namespace codeview {
+struct PDB70DebugInfo {
+ support::ulittle32_t CVSignature;
+ uint8_t Signature[16];
+ support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+
+struct PDB20DebugInfo {
+ support::ulittle32_t CVSignature;
+ support::ulittle32_t Offset;
+ support::ulittle32_t Signature;
+ support::ulittle32_t Age;
+ // char PDBFileName[];
+};
+
+union DebugInfo {
+ struct OMF::Signature Signature;
+ struct PDB20DebugInfo PDB20;
+ struct PDB70DebugInfo PDB70;
+};
+}
+}
+
+#endif
+
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/Decompressor.h b/contrib/libs/llvm12/include/llvm/Object/Decompressor.h
index 92409641e48..b488ef5b4c5 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Decompressor.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Decompressor.h
@@ -1,77 +1,77 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- Decompressor.h ------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===/
-
-#ifndef LLVM_OBJECT_DECOMPRESSOR_H
-#define LLVM_OBJECT_DECOMPRESSOR_H
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/ObjectFile.h"
-
-namespace llvm {
-namespace object {
-
-/// Decompressor helps to handle decompression of compressed sections.
-class Decompressor {
-public:
- /// Create decompressor object.
- /// @param Name Section name.
- /// @param Data Section content.
- /// @param IsLE Flag determines if Data is in little endian form.
- /// @param Is64Bit Flag determines if object is 64 bit.
- static Expected<Decompressor> create(StringRef Name, StringRef Data,
- bool IsLE, bool Is64Bit);
-
- /// Resize the buffer and uncompress section data into it.
- /// @param Out Destination buffer.
- template <class T> Error resizeAndDecompress(T &Out) {
- Out.resize(DecompressedSize);
- return decompress({Out.data(), (size_t)DecompressedSize});
- }
-
- /// Uncompress section data to raw buffer provided.
- /// @param Buffer Destination buffer.
- Error decompress(MutableArrayRef<char> Buffer);
-
- /// Return memory buffer size required for decompression.
- uint64_t getDecompressedSize() { return DecompressedSize; }
-
- /// Return true if section is compressed, including gnu-styled case.
- static bool isCompressed(const object::SectionRef &Section);
-
- /// Return true if section is a ELF compressed one.
- static bool isCompressedELFSection(uint64_t Flags, StringRef Name);
-
- /// Return true if section name matches gnu style compressed one.
- static bool isGnuStyle(StringRef Name);
-
-private:
- Decompressor(StringRef Data);
-
- Error consumeCompressedGnuHeader();
- Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
-
- StringRef SectionData;
- uint64_t DecompressedSize;
-};
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_DECOMPRESSOR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- Decompressor.h ------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===/
+
+#ifndef LLVM_OBJECT_DECOMPRESSOR_H
+#define LLVM_OBJECT_DECOMPRESSOR_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+namespace object {
+
+/// Decompressor helps to handle decompression of compressed sections.
+class Decompressor {
+public:
+ /// Create decompressor object.
+ /// @param Name Section name.
+ /// @param Data Section content.
+ /// @param IsLE Flag determines if Data is in little endian form.
+ /// @param Is64Bit Flag determines if object is 64 bit.
+ static Expected<Decompressor> create(StringRef Name, StringRef Data,
+ bool IsLE, bool Is64Bit);
+
+ /// Resize the buffer and uncompress section data into it.
+ /// @param Out Destination buffer.
+ template <class T> Error resizeAndDecompress(T &Out) {
+ Out.resize(DecompressedSize);
+ return decompress({Out.data(), (size_t)DecompressedSize});
+ }
+
+ /// Uncompress section data to raw buffer provided.
+ /// @param Buffer Destination buffer.
+ Error decompress(MutableArrayRef<char> Buffer);
+
+ /// Return memory buffer size required for decompression.
+ uint64_t getDecompressedSize() { return DecompressedSize; }
+
+ /// Return true if section is compressed, including gnu-styled case.
+ static bool isCompressed(const object::SectionRef &Section);
+
+ /// Return true if section is a ELF compressed one.
+ static bool isCompressedELFSection(uint64_t Flags, StringRef Name);
+
+ /// Return true if section name matches gnu style compressed one.
+ static bool isGnuStyle(StringRef Name);
+
+private:
+ Decompressor(StringRef Data);
+
+ Error consumeCompressedGnuHeader();
+ Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
+
+ StringRef SectionData;
+ uint64_t DecompressedSize;
+};
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_DECOMPRESSOR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/ELF.h b/contrib/libs/llvm12/include/llvm/Object/ELF.h
index 20e25a9ee28..9d96941ec12 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ELF.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ELF.h
@@ -1,42 +1,42 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ELF.h - ELF object file implementation -------------------*- 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 ELFFile template class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_ELF_H
-#define LLVM_OBJECT_ELF_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Object/ELFTypes.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <utility>
-
-namespace llvm {
-namespace object {
-
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ELF.h - ELF object file implementation -------------------*- 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 ELFFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELF_H
+#define LLVM_OBJECT_ELF_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <utility>
+
+namespace llvm {
+namespace object {
+
struct VerdAux {
unsigned Offset;
std::string Name;
@@ -74,24 +74,24 @@ struct VersionEntry {
bool IsVerDef;
};
-StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
-uint32_t getELFRelativeRelocationType(uint32_t Machine);
-StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
-
-// Subclasses of ELFFile may need this for template instantiation
-inline std::pair<unsigned char, unsigned char>
-getElfArchType(StringRef Object) {
- if (Object.size() < ELF::EI_NIDENT)
- return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
- (uint8_t)ELF::ELFDATANONE);
- return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
- (uint8_t)Object[ELF::EI_DATA]);
-}
-
-static inline Error createError(const Twine &Err) {
- return make_error<StringError>(Err, object_error::parse_failed);
-}
-
+StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type);
+uint32_t getELFRelativeRelocationType(uint32_t Machine);
+StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type);
+
+// Subclasses of ELFFile may need this for template instantiation
+inline std::pair<unsigned char, unsigned char>
+getElfArchType(StringRef Object) {
+ if (Object.size() < ELF::EI_NIDENT)
+ return std::make_pair((uint8_t)ELF::ELFCLASSNONE,
+ (uint8_t)ELF::ELFDATANONE);
+ return std::make_pair((uint8_t)Object[ELF::EI_CLASS],
+ (uint8_t)Object[ELF::EI_DATA]);
+}
+
+static inline Error createError(const Twine &Err) {
+ return make_error<StringError>(Err, object_error::parse_failed);
+}
+
enum PPCInstrMasks : uint64_t {
PADDI_R12_NO_DISP = 0x0610000039800000,
PLD_R12_NO_DISP = 0x04100000E5800000,
@@ -99,8 +99,8 @@ enum PPCInstrMasks : uint64_t {
BCTR = 0x4E800420,
};
-template <class ELFT> class ELFFile;
-
+template <class ELFT> class ELFFile;
+
template <class T> struct DataRegion {
// This constructor is used when we know the start and the size of a data
// region. We assume that Arr does not go past the end of the file.
@@ -131,21 +131,21 @@ template <class T> struct DataRegion {
const uint8_t *BufEnd = nullptr;
};
-template <class ELFT>
+template <class ELFT>
std::string getSecIndexForError(const ELFFile<ELFT> &Obj,
const typename ELFT::Shdr &Sec) {
auto TableOrErr = Obj.sections();
- if (TableOrErr)
+ if (TableOrErr)
return "[index " + std::to_string(&Sec - &TableOrErr->front()) + "]";
- // To make this helper be more convenient for error reporting purposes we
- // drop the error. But really it should never be triggered. Before this point,
- // our code should have called 'sections()' and reported a proper error on
- // failure.
- llvm::consumeError(TableOrErr.takeError());
- return "[unknown index]";
-}
-
-template <class ELFT>
+ // To make this helper be more convenient for error reporting purposes we
+ // drop the error. But really it should never be triggered. Before this point,
+ // our code should have called 'sections()' and reported a proper error on
+ // failure.
+ llvm::consumeError(TableOrErr.takeError());
+ return "[unknown index]";
+}
+
+template <class ELFT>
static std::string describe(const ELFFile<ELFT> &Obj,
const typename ELFT::Shdr &Sec) {
unsigned SecNdx = &Sec - &cantFail(Obj.sections()).front();
@@ -159,436 +159,436 @@ template <class ELFT>
std::string getPhdrIndexForError(const ELFFile<ELFT> &Obj,
const typename ELFT::Phdr &Phdr) {
auto Headers = Obj.program_headers();
- if (Headers)
+ if (Headers)
return ("[index " + Twine(&Phdr - &Headers->front()) + "]").str();
- // See comment in the getSecIndexForError() above.
- llvm::consumeError(Headers.takeError());
- return "[unknown index]";
-}
-
-static inline Error defaultWarningHandler(const Twine &Msg) {
- return createError(Msg);
-}
-
-template <class ELFT>
-class ELFFile {
-public:
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
-
- // This is a callback that can be passed to a number of functions.
- // It can be used to ignore non-critical errors (warnings), which is
- // useful for dumpers, like llvm-readobj.
- // It accepts a warning message string and returns a success
- // when the warning should be ignored or an error otherwise.
- using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
-
- const uint8_t *base() const { return Buf.bytes_begin(); }
+ // See comment in the getSecIndexForError() above.
+ llvm::consumeError(Headers.takeError());
+ return "[unknown index]";
+}
+
+static inline Error defaultWarningHandler(const Twine &Msg) {
+ return createError(Msg);
+}
+
+template <class ELFT>
+class ELFFile {
+public:
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+
+ // This is a callback that can be passed to a number of functions.
+ // It can be used to ignore non-critical errors (warnings), which is
+ // useful for dumpers, like llvm-readobj.
+ // It accepts a warning message string and returns a success
+ // when the warning should be ignored or an error otherwise.
+ using WarningHandler = llvm::function_ref<Error(const Twine &Msg)>;
+
+ const uint8_t *base() const { return Buf.bytes_begin(); }
const uint8_t *end() const { return base() + getBufSize(); }
-
- size_t getBufSize() const { return Buf.size(); }
-
-private:
- StringRef Buf;
-
- ELFFile(StringRef Object);
-
-public:
+
+ size_t getBufSize() const { return Buf.size(); }
+
+private:
+ StringRef Buf;
+
+ ELFFile(StringRef Object);
+
+public:
const Elf_Ehdr &getHeader() const {
return *reinterpret_cast<const Elf_Ehdr *>(base());
- }
-
- template <typename T>
- Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
- template <typename T>
+ }
+
+ template <typename T>
+ Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
+ template <typename T>
Expected<const T *> getEntry(const Elf_Shdr &Section, uint32_t Entry) const;
-
+
Expected<std::vector<VerDef>>
getVersionDefinitions(const Elf_Shdr &Sec) const;
Expected<std::vector<VerNeed>> getVersionDependencies(
const Elf_Shdr &Sec,
WarningHandler WarnHandler = &defaultWarningHandler) const;
- Expected<StringRef>
+ Expected<StringRef>
getSymbolVersionByIndex(uint32_t SymbolVersionIndex, bool &IsDefault,
SmallVector<Optional<VersionEntry>, 0> &VersionMap,
Optional<bool> IsSymHidden) const;
Expected<StringRef>
getStringTable(const Elf_Shdr &Section,
- WarningHandler WarnHandler = &defaultWarningHandler) const;
- Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
- Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
- Elf_Shdr_Range Sections) const;
+ WarningHandler WarnHandler = &defaultWarningHandler) const;
+ Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
+ Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
+ Elf_Shdr_Range Sections) const;
Expected<StringRef> getLinkAsStrtab(const typename ELFT::Shdr &Sec) const;
-
- Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
- Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
- Elf_Shdr_Range Sections) const;
-
+
+ Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
+ Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
+ Elf_Shdr_Range Sections) const;
+
Expected<uint64_t> getDynSymtabSize() const;
- StringRef getRelocationTypeName(uint32_t Type) const;
- void getRelocationTypeName(uint32_t Type,
- SmallVectorImpl<char> &Result) const;
- uint32_t getRelativeRelocationType() const;
-
- std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
- std::string getDynamicTagAsString(uint64_t Type) const;
-
- /// Get the symbol for a given relocation.
+ StringRef getRelocationTypeName(uint32_t Type) const;
+ void getRelocationTypeName(uint32_t Type,
+ SmallVectorImpl<char> &Result) const;
+ uint32_t getRelativeRelocationType() const;
+
+ std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const;
+ std::string getDynamicTagAsString(uint64_t Type) const;
+
+ /// Get the symbol for a given relocation.
Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel &Rel,
- const Elf_Shdr *SymTab) const;
-
+ const Elf_Shdr *SymTab) const;
+
Expected<SmallVector<Optional<VersionEntry>, 0>>
loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const;
- static Expected<ELFFile> create(StringRef Object);
-
- bool isLE() const {
+ static Expected<ELFFile> create(StringRef Object);
+
+ bool isLE() const {
return getHeader().getDataEncoding() == ELF::ELFDATA2LSB;
- }
-
- bool isMipsELF64() const {
+ }
+
+ bool isMipsELF64() const {
return getHeader().e_machine == ELF::EM_MIPS &&
getHeader().getFileClass() == ELF::ELFCLASS64;
- }
-
- bool isMips64EL() const { return isMipsELF64() && isLE(); }
-
- Expected<Elf_Shdr_Range> sections() const;
-
- Expected<Elf_Dyn_Range> dynamicEntries() const;
-
+ }
+
+ bool isMips64EL() const { return isMipsELF64() && isLE(); }
+
+ Expected<Elf_Shdr_Range> sections() const;
+
+ Expected<Elf_Dyn_Range> dynamicEntries() const;
+
Expected<const uint8_t *>
toMappedAddr(uint64_t VAddr,
WarningHandler WarnHandler = &defaultWarningHandler) const;
-
- Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
- if (!Sec)
- return makeArrayRef<Elf_Sym>(nullptr, nullptr);
+
+ Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
+ if (!Sec)
+ return makeArrayRef<Elf_Sym>(nullptr, nullptr);
return getSectionContentsAsArray<Elf_Sym>(*Sec);
- }
-
+ }
+
Expected<Elf_Rela_Range> relas(const Elf_Shdr &Sec) const {
- return getSectionContentsAsArray<Elf_Rela>(Sec);
- }
-
+ return getSectionContentsAsArray<Elf_Rela>(Sec);
+ }
+
Expected<Elf_Rel_Range> rels(const Elf_Shdr &Sec) const {
- return getSectionContentsAsArray<Elf_Rel>(Sec);
- }
-
+ return getSectionContentsAsArray<Elf_Rel>(Sec);
+ }
+
Expected<Elf_Relr_Range> relrs(const Elf_Shdr &Sec) const {
- return getSectionContentsAsArray<Elf_Relr>(Sec);
- }
-
+ return getSectionContentsAsArray<Elf_Relr>(Sec);
+ }
+
std::vector<Elf_Rel> decode_relrs(Elf_Relr_Range relrs) const;
-
+
Expected<std::vector<Elf_Rela>> android_relas(const Elf_Shdr &Sec) const;
-
- /// Iterate over program header table.
- Expected<Elf_Phdr_Range> program_headers() const {
+
+ /// Iterate over program header table.
+ Expected<Elf_Phdr_Range> program_headers() const {
if (getHeader().e_phnum && getHeader().e_phentsize != sizeof(Elf_Phdr))
- return createError("invalid e_phentsize: " +
+ return createError("invalid e_phentsize: " +
Twine(getHeader().e_phentsize));
-
- uint64_t HeadersSize =
+
+ uint64_t HeadersSize =
(uint64_t)getHeader().e_phnum * getHeader().e_phentsize;
uint64_t PhOff = getHeader().e_phoff;
- if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
- return createError("program headers are longer than binary of size " +
- Twine(getBufSize()) + ": e_phoff = 0x" +
+ if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
+ return createError("program headers are longer than binary of size " +
+ Twine(getBufSize()) + ": e_phoff = 0x" +
Twine::utohexstr(getHeader().e_phoff) +
", e_phnum = " + Twine(getHeader().e_phnum) +
", e_phentsize = " + Twine(getHeader().e_phentsize));
-
- auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
+
+ auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
return makeArrayRef(Begin, Begin + getHeader().e_phnum);
- }
-
- /// Get an iterator over notes in a program header.
- ///
- /// The program header must be of type \c PT_NOTE.
- ///
- /// \param Phdr the program header to iterate over.
- /// \param Err [out] an error to support fallible iteration, which should
- /// be checked after iteration ends.
- Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
- assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
- ErrorAsOutParameter ErrAsOutParam(&Err);
- if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
+ }
+
+ /// Get an iterator over notes in a program header.
+ ///
+ /// The program header must be of type \c PT_NOTE.
+ ///
+ /// \param Phdr the program header to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const {
+ assert(Phdr.p_type == ELF::PT_NOTE && "Phdr is not of type PT_NOTE");
+ ErrorAsOutParameter ErrAsOutParam(&Err);
+ if (Phdr.p_offset + Phdr.p_filesz > getBufSize()) {
Err =
createError("invalid offset (0x" + Twine::utohexstr(Phdr.p_offset) +
") or size (0x" + Twine::utohexstr(Phdr.p_filesz) + ")");
- return Elf_Note_Iterator(Err);
- }
- return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
- }
-
- /// Get an iterator over notes in a section.
- ///
- /// The section must be of type \c SHT_NOTE.
- ///
- /// \param Shdr the section to iterate over.
- /// \param Err [out] an error to support fallible iteration, which should
- /// be checked after iteration ends.
- Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
- assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
- ErrorAsOutParameter ErrAsOutParam(&Err);
- if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
+ return Elf_Note_Iterator(Err);
+ }
+ return Elf_Note_Iterator(base() + Phdr.p_offset, Phdr.p_filesz, Err);
+ }
+
+ /// Get an iterator over notes in a section.
+ ///
+ /// The section must be of type \c SHT_NOTE.
+ ///
+ /// \param Shdr the section to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const {
+ assert(Shdr.sh_type == ELF::SHT_NOTE && "Shdr is not of type SHT_NOTE");
+ ErrorAsOutParameter ErrAsOutParam(&Err);
+ if (Shdr.sh_offset + Shdr.sh_size > getBufSize()) {
Err =
createError("invalid offset (0x" + Twine::utohexstr(Shdr.sh_offset) +
") or size (0x" + Twine::utohexstr(Shdr.sh_size) + ")");
- return Elf_Note_Iterator(Err);
- }
- return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
- }
-
- /// Get the end iterator for notes.
- Elf_Note_Iterator notes_end() const {
- return Elf_Note_Iterator();
- }
-
- /// Get an iterator range over notes of a program header.
- ///
- /// The program header must be of type \c PT_NOTE.
- ///
- /// \param Phdr the program header to iterate over.
- /// \param Err [out] an error to support fallible iteration, which should
- /// be checked after iteration ends.
- iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
- Error &Err) const {
- return make_range(notes_begin(Phdr, Err), notes_end());
- }
-
- /// Get an iterator range over notes of a section.
- ///
- /// The section must be of type \c SHT_NOTE.
- ///
- /// \param Shdr the section to iterate over.
- /// \param Err [out] an error to support fallible iteration, which should
- /// be checked after iteration ends.
- iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
- Error &Err) const {
- return make_range(notes_begin(Shdr, Err), notes_end());
- }
-
- Expected<StringRef> getSectionStringTable(
- Elf_Shdr_Range Sections,
- WarningHandler WarnHandler = &defaultWarningHandler) const;
+ return Elf_Note_Iterator(Err);
+ }
+ return Elf_Note_Iterator(base() + Shdr.sh_offset, Shdr.sh_size, Err);
+ }
+
+ /// Get the end iterator for notes.
+ Elf_Note_Iterator notes_end() const {
+ return Elf_Note_Iterator();
+ }
+
+ /// Get an iterator range over notes of a program header.
+ ///
+ /// The program header must be of type \c PT_NOTE.
+ ///
+ /// \param Phdr the program header to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ iterator_range<Elf_Note_Iterator> notes(const Elf_Phdr &Phdr,
+ Error &Err) const {
+ return make_range(notes_begin(Phdr, Err), notes_end());
+ }
+
+ /// Get an iterator range over notes of a section.
+ ///
+ /// The section must be of type \c SHT_NOTE.
+ ///
+ /// \param Shdr the section to iterate over.
+ /// \param Err [out] an error to support fallible iteration, which should
+ /// be checked after iteration ends.
+ iterator_range<Elf_Note_Iterator> notes(const Elf_Shdr &Shdr,
+ Error &Err) const {
+ return make_range(notes_begin(Shdr, Err), notes_end());
+ }
+
+ Expected<StringRef> getSectionStringTable(
+ Elf_Shdr_Range Sections,
+ WarningHandler WarnHandler = &defaultWarningHandler) const;
Expected<uint32_t> getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
DataRegion<Elf_Word> ShndxTable) const;
Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
- const Elf_Shdr *SymTab,
+ const Elf_Shdr *SymTab,
DataRegion<Elf_Word> ShndxTable) const;
Expected<const Elf_Shdr *> getSection(const Elf_Sym &Sym,
- Elf_Sym_Range Symtab,
+ Elf_Sym_Range Symtab,
DataRegion<Elf_Word> ShndxTable) const;
- Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
-
- Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
- uint32_t Index) const;
-
- Expected<StringRef>
+ Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
+
+ Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
+ uint32_t Index) const;
+
+ Expected<StringRef>
getSectionName(const Elf_Shdr &Section,
- WarningHandler WarnHandler = &defaultWarningHandler) const;
+ WarningHandler WarnHandler = &defaultWarningHandler) const;
Expected<StringRef> getSectionName(const Elf_Shdr &Section,
- StringRef DotShstrtab) const;
- template <typename T>
+ StringRef DotShstrtab) const;
+ template <typename T>
Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr &Sec) const;
Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr &Sec) const;
Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr &Phdr) const;
-};
-
-using ELF32LEFile = ELFFile<ELF32LE>;
-using ELF64LEFile = ELFFile<ELF64LE>;
-using ELF32BEFile = ELFFile<ELF32BE>;
-using ELF64BEFile = ELFFile<ELF64BE>;
-
-template <class ELFT>
-inline Expected<const typename ELFT::Shdr *>
-getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
- if (Index >= Sections.size())
- return createError("invalid section index: " + Twine(Index));
- return &Sections[Index];
-}
-
-template <class ELFT>
-inline Expected<uint32_t>
+};
+
+using ELF32LEFile = ELFFile<ELF32LE>;
+using ELF64LEFile = ELFFile<ELF64LE>;
+using ELF32BEFile = ELFFile<ELF32BE>;
+using ELF64BEFile = ELFFile<ELF64BE>;
+
+template <class ELFT>
+inline Expected<const typename ELFT::Shdr *>
+getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
+ if (Index >= Sections.size())
+ return createError("invalid section index: " + Twine(Index));
+ return &Sections[Index];
+}
+
+template <class ELFT>
+inline Expected<uint32_t>
getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex,
DataRegion<typename ELFT::Word> ShndxTable) {
assert(Sym.st_shndx == ELF::SHN_XINDEX);
if (!ShndxTable.First)
- return createError(
+ return createError(
"found an extended symbol index (" + Twine(SymIndex) +
"), but unable to locate the extended symbol index table");
-
+
Expected<typename ELFT::Word> TableOrErr = ShndxTable[SymIndex];
if (!TableOrErr)
return createError("unable to read an extended symbol table at index " +
Twine(SymIndex) + ": " +
toString(TableOrErr.takeError()));
return *TableOrErr;
-}
-
-template <class ELFT>
-Expected<uint32_t>
+}
+
+template <class ELFT>
+Expected<uint32_t>
ELFFile<ELFT>::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms,
DataRegion<Elf_Word> ShndxTable) const {
uint32_t Index = Sym.st_shndx;
- if (Index == ELF::SHN_XINDEX) {
+ if (Index == ELF::SHN_XINDEX) {
Expected<uint32_t> ErrorOrIndex =
getExtendedSymbolTableIndex<ELFT>(Sym, &Sym - Syms.begin(), ShndxTable);
- if (!ErrorOrIndex)
- return ErrorOrIndex.takeError();
- return *ErrorOrIndex;
- }
- if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
- return 0;
- return Index;
-}
-
-template <class ELFT>
-Expected<const typename ELFT::Shdr *>
+ if (!ErrorOrIndex)
+ return ErrorOrIndex.takeError();
+ return *ErrorOrIndex;
+ }
+ if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
+ return 0;
+ return Index;
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab,
DataRegion<Elf_Word> ShndxTable) const {
- auto SymsOrErr = symbols(SymTab);
- if (!SymsOrErr)
- return SymsOrErr.takeError();
- return getSection(Sym, *SymsOrErr, ShndxTable);
-}
-
-template <class ELFT>
-Expected<const typename ELFT::Shdr *>
+ auto SymsOrErr = symbols(SymTab);
+ if (!SymsOrErr)
+ return SymsOrErr.takeError();
+ return getSection(Sym, *SymsOrErr, ShndxTable);
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols,
DataRegion<Elf_Word> ShndxTable) const {
- auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
- if (!IndexOrErr)
- return IndexOrErr.takeError();
- uint32_t Index = *IndexOrErr;
- if (Index == 0)
- return nullptr;
- return getSection(Index);
-}
-
-template <class ELFT>
-Expected<const typename ELFT::Sym *>
-ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
- auto SymsOrErr = symbols(Sec);
- if (!SymsOrErr)
- return SymsOrErr.takeError();
-
- Elf_Sym_Range Symbols = *SymsOrErr;
- if (Index >= Symbols.size())
- return createError("unable to get symbol from section " +
+ auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
+ if (!IndexOrErr)
+ return IndexOrErr.takeError();
+ uint32_t Index = *IndexOrErr;
+ if (Index == 0)
+ return nullptr;
+ return getSection(Index);
+}
+
+template <class ELFT>
+Expected<const typename ELFT::Sym *>
+ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
+ auto SymsOrErr = symbols(Sec);
+ if (!SymsOrErr)
+ return SymsOrErr.takeError();
+
+ Elf_Sym_Range Symbols = *SymsOrErr;
+ if (Index >= Symbols.size())
+ return createError("unable to get symbol from section " +
getSecIndexForError(*this, *Sec) +
- ": invalid symbol index (" + Twine(Index) + ")");
- return &Symbols[Index];
-}
-
-template <class ELFT>
-template <typename T>
-Expected<ArrayRef<T>>
+ ": invalid symbol index (" + Twine(Index) + ")");
+ return &Symbols[Index];
+}
+
+template <class ELFT>
+template <typename T>
+Expected<ArrayRef<T>>
ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr &Sec) const {
if (Sec.sh_entsize != sizeof(T) && sizeof(T) != 1)
return createError("section " + getSecIndexForError(*this, Sec) +
" has invalid sh_entsize: expected " + Twine(sizeof(T)) +
", but got " + Twine(Sec.sh_entsize));
-
+
uintX_t Offset = Sec.sh_offset;
uintX_t Size = Sec.sh_size;
-
- if (Size % sizeof(T))
+
+ if (Size % sizeof(T))
return createError("section " + getSecIndexForError(*this, Sec) +
- " has an invalid sh_size (" + Twine(Size) +
- ") which is not a multiple of its sh_entsize (" +
+ " has an invalid sh_size (" + Twine(Size) +
+ ") which is not a multiple of its sh_entsize (" +
Twine(Sec.sh_entsize) + ")");
- if (std::numeric_limits<uintX_t>::max() - Offset < Size)
+ if (std::numeric_limits<uintX_t>::max() - Offset < Size)
return createError("section " + getSecIndexForError(*this, Sec) +
- " has a sh_offset (0x" + Twine::utohexstr(Offset) +
- ") + sh_size (0x" + Twine::utohexstr(Size) +
- ") that cannot be represented");
- if (Offset + Size > Buf.size())
+ " has a sh_offset (0x" + Twine::utohexstr(Offset) +
+ ") + sh_size (0x" + Twine::utohexstr(Size) +
+ ") that cannot be represented");
+ if (Offset + Size > Buf.size())
return createError("section " + getSecIndexForError(*this, Sec) +
- " has a sh_offset (0x" + Twine::utohexstr(Offset) +
- ") + sh_size (0x" + Twine::utohexstr(Size) +
- ") that is greater than the file size (0x" +
- Twine::utohexstr(Buf.size()) + ")");
-
- if (Offset % alignof(T))
- // TODO: this error is untested.
- return createError("unaligned data");
-
- const T *Start = reinterpret_cast<const T *>(base() + Offset);
- return makeArrayRef(Start, Size / sizeof(T));
-}
-
-template <class ELFT>
-Expected<ArrayRef<uint8_t>>
+ " has a sh_offset (0x" + Twine::utohexstr(Offset) +
+ ") + sh_size (0x" + Twine::utohexstr(Size) +
+ ") that is greater than the file size (0x" +
+ Twine::utohexstr(Buf.size()) + ")");
+
+ if (Offset % alignof(T))
+ // TODO: this error is untested.
+ return createError("unaligned data");
+
+ const T *Start = reinterpret_cast<const T *>(base() + Offset);
+ return makeArrayRef(Start, Size / sizeof(T));
+}
+
+template <class ELFT>
+Expected<ArrayRef<uint8_t>>
ELFFile<ELFT>::getSegmentContents(const Elf_Phdr &Phdr) const {
uintX_t Offset = Phdr.p_offset;
uintX_t Size = Phdr.p_filesz;
-
- if (std::numeric_limits<uintX_t>::max() - Offset < Size)
+
+ if (std::numeric_limits<uintX_t>::max() - Offset < Size)
return createError("program header " + getPhdrIndexForError(*this, Phdr) +
- " has a p_offset (0x" + Twine::utohexstr(Offset) +
- ") + p_filesz (0x" + Twine::utohexstr(Size) +
- ") that cannot be represented");
- if (Offset + Size > Buf.size())
+ " has a p_offset (0x" + Twine::utohexstr(Offset) +
+ ") + p_filesz (0x" + Twine::utohexstr(Size) +
+ ") that cannot be represented");
+ if (Offset + Size > Buf.size())
return createError("program header " + getPhdrIndexForError(*this, Phdr) +
- " has a p_offset (0x" + Twine::utohexstr(Offset) +
- ") + p_filesz (0x" + Twine::utohexstr(Size) +
- ") that is greater than the file size (0x" +
- Twine::utohexstr(Buf.size()) + ")");
- return makeArrayRef(base() + Offset, Size);
-}
-
-template <class ELFT>
-Expected<ArrayRef<uint8_t>>
+ " has a p_offset (0x" + Twine::utohexstr(Offset) +
+ ") + p_filesz (0x" + Twine::utohexstr(Size) +
+ ") that is greater than the file size (0x" +
+ Twine::utohexstr(Buf.size()) + ")");
+ return makeArrayRef(base() + Offset, Size);
+}
+
+template <class ELFT>
+Expected<ArrayRef<uint8_t>>
ELFFile<ELFT>::getSectionContents(const Elf_Shdr &Sec) const {
- return getSectionContentsAsArray<uint8_t>(Sec);
-}
-
-template <class ELFT>
-StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
+ return getSectionContentsAsArray<uint8_t>(Sec);
+}
+
+template <class ELFT>
+StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
return getELFRelocationTypeName(getHeader().e_machine, Type);
-}
-
-template <class ELFT>
-void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
- SmallVectorImpl<char> &Result) const {
- if (!isMipsELF64()) {
- StringRef Name = getRelocationTypeName(Type);
- Result.append(Name.begin(), Name.end());
- } else {
- // The Mips N64 ABI allows up to three operations to be specified per
- // relocation record. Unfortunately there's no easy way to test for the
- // presence of N64 ELFs as they have no special flag that identifies them
- // as being N64. We can safely assume at the moment that all Mips
- // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
- // information to disambiguate between old vs new ABIs.
- uint8_t Type1 = (Type >> 0) & 0xFF;
- uint8_t Type2 = (Type >> 8) & 0xFF;
- uint8_t Type3 = (Type >> 16) & 0xFF;
-
- // Concat all three relocation type names.
- StringRef Name = getRelocationTypeName(Type1);
- Result.append(Name.begin(), Name.end());
-
- Name = getRelocationTypeName(Type2);
- Result.append(1, '/');
- Result.append(Name.begin(), Name.end());
-
- Name = getRelocationTypeName(Type3);
- Result.append(1, '/');
- Result.append(Name.begin(), Name.end());
- }
-}
-
-template <class ELFT>
-uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
+}
+
+template <class ELFT>
+void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
+ SmallVectorImpl<char> &Result) const {
+ if (!isMipsELF64()) {
+ StringRef Name = getRelocationTypeName(Type);
+ Result.append(Name.begin(), Name.end());
+ } else {
+ // The Mips N64 ABI allows up to three operations to be specified per
+ // relocation record. Unfortunately there's no easy way to test for the
+ // presence of N64 ELFs as they have no special flag that identifies them
+ // as being N64. We can safely assume at the moment that all Mips
+ // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough
+ // information to disambiguate between old vs new ABIs.
+ uint8_t Type1 = (Type >> 0) & 0xFF;
+ uint8_t Type2 = (Type >> 8) & 0xFF;
+ uint8_t Type3 = (Type >> 16) & 0xFF;
+
+ // Concat all three relocation type names.
+ StringRef Name = getRelocationTypeName(Type1);
+ Result.append(Name.begin(), Name.end());
+
+ Name = getRelocationTypeName(Type2);
+ Result.append(1, '/');
+ Result.append(Name.begin(), Name.end());
+
+ Name = getRelocationTypeName(Type3);
+ Result.append(1, '/');
+ Result.append(Name.begin(), Name.end());
+ }
+}
+
+template <class ELFT>
+uint32_t ELFFile<ELFT>::getRelativeRelocationType() const {
return getELFRelativeRelocationType(getHeader().e_machine);
-}
-
-template <class ELFT>
+}
+
+template <class ELFT>
Expected<SmallVector<Optional<VersionEntry>, 0>>
ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
const Elf_Shdr *VerDefSec) const {
@@ -626,40 +626,40 @@ ELFFile<ELFT>::loadVersionMap(const Elf_Shdr *VerNeedSec,
}
template <class ELFT>
-Expected<const typename ELFT::Sym *>
+Expected<const typename ELFT::Sym *>
ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel &Rel,
- const Elf_Shdr *SymTab) const {
+ const Elf_Shdr *SymTab) const {
uint32_t Index = Rel.getSymbol(isMips64EL());
- if (Index == 0)
- return nullptr;
+ if (Index == 0)
+ return nullptr;
return getEntry<Elf_Sym>(*SymTab, Index);
-}
-
-template <class ELFT>
-Expected<StringRef>
-ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
- WarningHandler WarnHandler) const {
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
+ WarningHandler WarnHandler) const {
uint32_t Index = getHeader().e_shstrndx;
- if (Index == ELF::SHN_XINDEX) {
- // If the section name string table section index is greater than
- // or equal to SHN_LORESERVE, then the actual index of the section name
- // string table section is contained in the sh_link field of the section
- // header at index 0.
- if (Sections.empty())
- return createError(
- "e_shstrndx == SHN_XINDEX, but the section header table is empty");
-
- Index = Sections[0].sh_link;
- }
-
- if (!Index) // no section string table.
- return "";
- if (Index >= Sections.size())
- return createError("section header string table index " + Twine(Index) +
- " does not exist");
+ if (Index == ELF::SHN_XINDEX) {
+ // If the section name string table section index is greater than
+ // or equal to SHN_LORESERVE, then the actual index of the section name
+ // string table section is contained in the sh_link field of the section
+ // header at index 0.
+ if (Sections.empty())
+ return createError(
+ "e_shstrndx == SHN_XINDEX, but the section header table is empty");
+
+ Index = Sections[0].sh_link;
+ }
+
+ if (!Index) // no section string table.
+ return "";
+ if (Index >= Sections.size())
+ return createError("section header string table index " + Twine(Index) +
+ " does not exist");
return getStringTable(Sections[Index], WarnHandler);
-}
-
+}
+
/// This function finds the number of dynamic symbols using a GNU hash table.
///
/// @param Table The GNU hash table for .dynsym.
@@ -753,80 +753,80 @@ Expected<uint64_t> ELFFile<ELFT>::getDynSymtabSize() const {
return 0;
}
-template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
-
-template <class ELFT>
-Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
- if (sizeof(Elf_Ehdr) > Object.size())
- return createError("invalid buffer: the size (" + Twine(Object.size()) +
- ") is smaller than an ELF header (" +
- Twine(sizeof(Elf_Ehdr)) + ")");
- return ELFFile(Object);
-}
-
-template <class ELFT>
-Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
+template <class ELFT> ELFFile<ELFT>::ELFFile(StringRef Object) : Buf(Object) {}
+
+template <class ELFT>
+Expected<ELFFile<ELFT>> ELFFile<ELFT>::create(StringRef Object) {
+ if (sizeof(Elf_Ehdr) > Object.size())
+ return createError("invalid buffer: the size (" + Twine(Object.size()) +
+ ") is smaller than an ELF header (" +
+ Twine(sizeof(Elf_Ehdr)) + ")");
+ return ELFFile(Object);
+}
+
+template <class ELFT>
+Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
const uintX_t SectionTableOffset = getHeader().e_shoff;
- if (SectionTableOffset == 0)
- return ArrayRef<Elf_Shdr>();
-
+ if (SectionTableOffset == 0)
+ return ArrayRef<Elf_Shdr>();
+
if (getHeader().e_shentsize != sizeof(Elf_Shdr))
- return createError("invalid e_shentsize in ELF header: " +
+ return createError("invalid e_shentsize in ELF header: " +
Twine(getHeader().e_shentsize));
-
- const uint64_t FileSize = Buf.size();
- if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
- SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
- return createError(
- "section header table goes past the end of the file: e_shoff = 0x" +
- Twine::utohexstr(SectionTableOffset));
-
- // Invalid address alignment of section headers
- if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
- // TODO: this error is untested.
- return createError("invalid alignment of section headers");
-
- const Elf_Shdr *First =
- reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
-
+
+ const uint64_t FileSize = Buf.size();
+ if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize ||
+ SectionTableOffset + (uintX_t)sizeof(Elf_Shdr) < SectionTableOffset)
+ return createError(
+ "section header table goes past the end of the file: e_shoff = 0x" +
+ Twine::utohexstr(SectionTableOffset));
+
+ // Invalid address alignment of section headers
+ if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
+ // TODO: this error is untested.
+ return createError("invalid alignment of section headers");
+
+ const Elf_Shdr *First =
+ reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
+
uintX_t NumSections = getHeader().e_shnum;
- if (NumSections == 0)
- NumSections = First->sh_size;
-
- if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
- return createError("invalid number of sections specified in the NULL "
- "section's sh_size field (" +
- Twine(NumSections) + ")");
-
- const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
- if (SectionTableOffset + SectionTableSize < SectionTableOffset)
- return createError(
- "invalid section header table offset (e_shoff = 0x" +
- Twine::utohexstr(SectionTableOffset) +
- ") or invalid number of sections specified in the first section "
- "header's sh_size field (0x" +
- Twine::utohexstr(NumSections) + ")");
-
- // Section table goes past end of file!
- if (SectionTableOffset + SectionTableSize > FileSize)
- return createError("section table goes past the end of file");
- return makeArrayRef(First, NumSections);
-}
-
-template <class ELFT>
-template <typename T>
-Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
- uint32_t Entry) const {
- auto SecOrErr = getSection(Section);
- if (!SecOrErr)
- return SecOrErr.takeError();
+ if (NumSections == 0)
+ NumSections = First->sh_size;
+
+ if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
+ return createError("invalid number of sections specified in the NULL "
+ "section's sh_size field (" +
+ Twine(NumSections) + ")");
+
+ const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
+ if (SectionTableOffset + SectionTableSize < SectionTableOffset)
+ return createError(
+ "invalid section header table offset (e_shoff = 0x" +
+ Twine::utohexstr(SectionTableOffset) +
+ ") or invalid number of sections specified in the first section "
+ "header's sh_size field (0x" +
+ Twine::utohexstr(NumSections) + ")");
+
+ // Section table goes past end of file!
+ if (SectionTableOffset + SectionTableSize > FileSize)
+ return createError("section table goes past the end of file");
+ return makeArrayRef(First, NumSections);
+}
+
+template <class ELFT>
+template <typename T>
+Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
+ uint32_t Entry) const {
+ auto SecOrErr = getSection(Section);
+ if (!SecOrErr)
+ return SecOrErr.takeError();
return getEntry<T>(**SecOrErr, Entry);
-}
-
-template <class ELFT>
-template <typename T>
+}
+
+template <class ELFT>
+template <typename T>
Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
- uint32_t Entry) const {
+ uint32_t Entry) const {
Expected<ArrayRef<T>> EntriesOrErr = getSectionContentsAsArray<T>(Section);
if (!EntriesOrErr)
return EntriesOrErr.takeError();
@@ -839,8 +839,8 @@ Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr &Section,
": it goes past the end of the section (0x" +
Twine::utohexstr(Section.sh_size) + ")");
return &Arr[Entry];
-}
-
+}
+
template <typename ELFT>
Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
uint32_t SymbolVersionIndex, bool &IsDefault,
@@ -869,7 +869,7 @@ Expected<StringRef> ELFFile<ELFT>::getSymbolVersionByIndex(
return Entry.Name.c_str();
}
-template <class ELFT>
+template <class ELFT>
Expected<std::vector<VerDef>>
ELFFile<ELFT>::getVersionDefinitions(const Elf_Shdr &Sec) const {
Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Sec);
@@ -1045,104 +1045,104 @@ ELFFile<ELFT>::getVersionDependencies(const Elf_Shdr &Sec,
}
template <class ELFT>
-Expected<const typename ELFT::Shdr *>
-ELFFile<ELFT>::getSection(uint32_t Index) const {
- auto TableOrErr = sections();
- if (!TableOrErr)
- return TableOrErr.takeError();
- return object::getSection<ELFT>(*TableOrErr, Index);
-}
-
-template <class ELFT>
-Expected<StringRef>
+Expected<const typename ELFT::Shdr *>
+ELFFile<ELFT>::getSection(uint32_t Index) const {
+ auto TableOrErr = sections();
+ if (!TableOrErr)
+ return TableOrErr.takeError();
+ return object::getSection<ELFT>(*TableOrErr, Index);
+}
+
+template <class ELFT>
+Expected<StringRef>
ELFFile<ELFT>::getStringTable(const Elf_Shdr &Section,
- WarningHandler WarnHandler) const {
+ WarningHandler WarnHandler) const {
if (Section.sh_type != ELF::SHT_STRTAB)
- if (Error E = WarnHandler("invalid sh_type for string table section " +
+ if (Error E = WarnHandler("invalid sh_type for string table section " +
getSecIndexForError(*this, Section) +
- ": expected SHT_STRTAB, but got " +
- object::getELFSectionTypeName(
+ ": expected SHT_STRTAB, but got " +
+ object::getELFSectionTypeName(
getHeader().e_machine, Section.sh_type)))
- return std::move(E);
-
- auto V = getSectionContentsAsArray<char>(Section);
- if (!V)
- return V.takeError();
- ArrayRef<char> Data = *V;
- if (Data.empty())
- return createError("SHT_STRTAB string table section " +
+ return std::move(E);
+
+ auto V = getSectionContentsAsArray<char>(Section);
+ if (!V)
+ return V.takeError();
+ ArrayRef<char> Data = *V;
+ if (Data.empty())
+ return createError("SHT_STRTAB string table section " +
getSecIndexForError(*this, Section) + " is empty");
- if (Data.back() != '\0')
- return createError("SHT_STRTAB string table section " +
+ if (Data.back() != '\0')
+ return createError("SHT_STRTAB string table section " +
getSecIndexForError(*this, Section) +
- " is non-null terminated");
- return StringRef(Data.begin(), Data.size());
-}
-
-template <class ELFT>
-Expected<ArrayRef<typename ELFT::Word>>
-ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
- auto SectionsOrErr = sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
- return getSHNDXTable(Section, *SectionsOrErr);
-}
-
-template <class ELFT>
-Expected<ArrayRef<typename ELFT::Word>>
-ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
- Elf_Shdr_Range Sections) const {
- assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
+ " is non-null terminated");
+ return StringRef(Data.begin(), Data.size());
+}
+
+template <class ELFT>
+Expected<ArrayRef<typename ELFT::Word>>
+ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
+ auto SectionsOrErr = sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+ return getSHNDXTable(Section, *SectionsOrErr);
+}
+
+template <class ELFT>
+Expected<ArrayRef<typename ELFT::Word>>
+ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
+ Elf_Shdr_Range Sections) const {
+ assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
auto VOrErr = getSectionContentsAsArray<Elf_Word>(Section);
- if (!VOrErr)
- return VOrErr.takeError();
- ArrayRef<Elf_Word> V = *VOrErr;
- auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
- if (!SymTableOrErr)
- return SymTableOrErr.takeError();
- const Elf_Shdr &SymTable = **SymTableOrErr;
- if (SymTable.sh_type != ELF::SHT_SYMTAB &&
- SymTable.sh_type != ELF::SHT_DYNSYM)
+ if (!VOrErr)
+ return VOrErr.takeError();
+ ArrayRef<Elf_Word> V = *VOrErr;
+ auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
+ if (!SymTableOrErr)
+ return SymTableOrErr.takeError();
+ const Elf_Shdr &SymTable = **SymTableOrErr;
+ if (SymTable.sh_type != ELF::SHT_SYMTAB &&
+ SymTable.sh_type != ELF::SHT_DYNSYM)
return createError(
"SHT_SYMTAB_SHNDX section is linked with " +
object::getELFSectionTypeName(getHeader().e_machine, SymTable.sh_type) +
" section (expected SHT_SYMTAB/SHT_DYNSYM)");
-
- uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
- if (V.size() != Syms)
- return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +
- " entries, but the symbol table associated has " +
- Twine(Syms));
-
- return V;
-}
-
-template <class ELFT>
-Expected<StringRef>
-ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
- auto SectionsOrErr = sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
- return getStringTableForSymtab(Sec, *SectionsOrErr);
-}
-
-template <class ELFT>
-Expected<StringRef>
-ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
- Elf_Shdr_Range Sections) const {
-
- if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
- return createError(
- "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
+
+ uint64_t Syms = SymTable.sh_size / sizeof(Elf_Sym);
+ if (V.size() != Syms)
+ return createError("SHT_SYMTAB_SHNDX has " + Twine(V.size()) +
+ " entries, but the symbol table associated has " +
+ Twine(Syms));
+
+ return V;
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
+ auto SectionsOrErr = sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+ return getStringTableForSymtab(Sec, *SectionsOrErr);
+}
+
+template <class ELFT>
+Expected<StringRef>
+ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
+ Elf_Shdr_Range Sections) const {
+
+ if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
+ return createError(
+ "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
Expected<const Elf_Shdr *> SectionOrErr =
object::getSection<ELFT>(Sections, Sec.sh_link);
- if (!SectionOrErr)
- return SectionOrErr.takeError();
+ if (!SectionOrErr)
+ return SectionOrErr.takeError();
return getStringTable(**SectionOrErr);
-}
-
-template <class ELFT>
-Expected<StringRef>
+}
+
+template <class ELFT>
+Expected<StringRef>
ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
Expected<const typename ELFT::Shdr *> StrTabSecOrErr =
getSection(Sec.sh_link);
@@ -1161,51 +1161,51 @@ ELFFile<ELFT>::getLinkAsStrtab(const typename ELFT::Shdr &Sec) const {
template <class ELFT>
Expected<StringRef>
ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
- WarningHandler WarnHandler) const {
- auto SectionsOrErr = sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
- auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
- if (!Table)
- return Table.takeError();
- return getSectionName(Section, *Table);
-}
-
-template <class ELFT>
+ WarningHandler WarnHandler) const {
+ auto SectionsOrErr = sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+ auto Table = getSectionStringTable(*SectionsOrErr, WarnHandler);
+ if (!Table)
+ return Table.takeError();
+ return getSectionName(Section, *Table);
+}
+
+template <class ELFT>
Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr &Section,
- StringRef DotShstrtab) const {
+ StringRef DotShstrtab) const {
uint32_t Offset = Section.sh_name;
- if (Offset == 0)
- return StringRef();
- if (Offset >= DotShstrtab.size())
+ if (Offset == 0)
+ return StringRef();
+ if (Offset >= DotShstrtab.size())
return createError("a section " + getSecIndexForError(*this, Section) +
- " has an invalid sh_name (0x" +
- Twine::utohexstr(Offset) +
- ") offset which goes past the end of the "
- "section name string table");
- return StringRef(DotShstrtab.data() + Offset);
-}
-
-/// This function returns the hash value for a symbol in the .dynsym section
-/// Name of the API remains consistent as specified in the libelf
-/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
-inline unsigned hashSysV(StringRef SymbolName) {
- unsigned h = 0, g;
- for (char C : SymbolName) {
- h = (h << 4) + C;
- g = h & 0xf0000000L;
- if (g != 0)
- h ^= g >> 24;
- h &= ~g;
- }
- return h;
-}
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_ELF_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+ " has an invalid sh_name (0x" +
+ Twine::utohexstr(Offset) +
+ ") offset which goes past the end of the "
+ "section name string table");
+ return StringRef(DotShstrtab.data() + Offset);
+}
+
+/// This function returns the hash value for a symbol in the .dynsym section
+/// Name of the API remains consistent as specified in the libelf
+/// REF : http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#hash
+inline unsigned hashSysV(StringRef SymbolName) {
+ unsigned h = 0, g;
+ for (char C : SymbolName) {
+ h = (h << 4) + C;
+ g = h & 0xf0000000L;
+ if (g != 0)
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ return h;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_ELF_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h
index 28c6ec9bfc8..40bd4150202 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ELFObjectFile.h
@@ -1,415 +1,415 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ELFObjectFile.h - ELF object file implementation ---------*- 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 ELFObjectFile template class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_ELFOBJECTFILE_H
-#define LLVM_OBJECT_ELFOBJECTFILE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Object/ELFTypes.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/ARMAttributeParser.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ELFAttributes.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cassert>
-#include <cstdint>
-#include <system_error>
-
-namespace llvm {
-namespace object {
-
-constexpr int NumElfSymbolTypes = 16;
-extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
-
-class elf_symbol_iterator;
-
-class ELFObjectFileBase : public ObjectFile {
- friend class ELFRelocationRef;
- friend class ELFSectionRef;
- friend class ELFSymbolRef;
-
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ELFObjectFile.h - ELF object file implementation ---------*- 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 ELFObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELFOBJECTFILE_H
+#define LLVM_OBJECT_ELFOBJECTFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ELFTypes.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/ARMAttributeParser.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ELFAttributes.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+constexpr int NumElfSymbolTypes = 16;
+extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
+
+class elf_symbol_iterator;
+
+class ELFObjectFileBase : public ObjectFile {
+ friend class ELFRelocationRef;
+ friend class ELFSectionRef;
+ friend class ELFSymbolRef;
+
SubtargetFeatures getMIPSFeatures() const;
SubtargetFeatures getARMFeatures() const;
SubtargetFeatures getRISCVFeatures() const;
StringRef getAMDGPUCPUName() const;
-protected:
- ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
-
- virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
- virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0;
- virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
- virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
-
- virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
-
- virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
- virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0;
-
-public:
- using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
-
- virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
-
- /// Returns platform-specific object flags, if any.
- virtual unsigned getPlatformFlags() const = 0;
-
- elf_symbol_iterator_range symbols() const;
-
- static bool classof(const Binary *v) { return v->isELF(); }
-
- SubtargetFeatures getFeatures() const override;
-
+protected:
+ ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
+
+ virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
+ virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0;
+ virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0;
+ virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0;
+
+ virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
+
+ virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
+ virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0;
+
+public:
+ using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
+
+ virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
+
+ /// Returns platform-specific object flags, if any.
+ virtual unsigned getPlatformFlags() const = 0;
+
+ elf_symbol_iterator_range symbols() const;
+
+ static bool classof(const Binary *v) { return v->isELF(); }
+
+ SubtargetFeatures getFeatures() const override;
+
Optional<StringRef> tryGetCPUName() const override;
-
- void setARMSubArch(Triple &TheTriple) const override;
-
- virtual uint16_t getEType() const = 0;
-
- virtual uint16_t getEMachine() const = 0;
-
+
+ void setARMSubArch(Triple &TheTriple) const override;
+
+ virtual uint16_t getEType() const = 0;
+
+ virtual uint16_t getEMachine() const = 0;
+
std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
getPltAddresses() const;
-};
-
-class ELFSectionRef : public SectionRef {
-public:
- ELFSectionRef(const SectionRef &B) : SectionRef(B) {
- assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
- }
-
- const ELFObjectFileBase *getObject() const {
- return cast<ELFObjectFileBase>(SectionRef::getObject());
- }
-
- uint32_t getType() const {
- return getObject()->getSectionType(getRawDataRefImpl());
- }
-
- uint64_t getFlags() const {
- return getObject()->getSectionFlags(getRawDataRefImpl());
- }
-
- uint64_t getOffset() const {
- return getObject()->getSectionOffset(getRawDataRefImpl());
- }
-};
-
-class elf_section_iterator : public section_iterator {
-public:
- elf_section_iterator(const section_iterator &B) : section_iterator(B) {
- assert(isa<ELFObjectFileBase>(B->getObject()));
- }
-
- const ELFSectionRef *operator->() const {
- return static_cast<const ELFSectionRef *>(section_iterator::operator->());
- }
-
- const ELFSectionRef &operator*() const {
- return static_cast<const ELFSectionRef &>(section_iterator::operator*());
- }
-};
-
-class ELFSymbolRef : public SymbolRef {
-public:
- ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
- assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
- }
-
- const ELFObjectFileBase *getObject() const {
- return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
- }
-
- uint64_t getSize() const {
- return getObject()->getSymbolSize(getRawDataRefImpl());
- }
-
- uint8_t getBinding() const {
- return getObject()->getSymbolBinding(getRawDataRefImpl());
- }
-
- uint8_t getOther() const {
- return getObject()->getSymbolOther(getRawDataRefImpl());
- }
-
- uint8_t getELFType() const {
- return getObject()->getSymbolELFType(getRawDataRefImpl());
- }
-
- StringRef getELFTypeName() const {
- uint8_t Type = getELFType();
- for (auto &EE : ElfSymbolTypes) {
- if (EE.Value == Type) {
- return EE.AltName;
- }
- }
- return "";
- }
-};
-
-class elf_symbol_iterator : public symbol_iterator {
-public:
- elf_symbol_iterator(const basic_symbol_iterator &B)
- : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
- cast<ELFObjectFileBase>(B->getObject()))) {}
-
- const ELFSymbolRef *operator->() const {
- return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
- }
-
- const ELFSymbolRef &operator*() const {
- return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
- }
-};
-
-class ELFRelocationRef : public RelocationRef {
-public:
- ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
- assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
- }
-
- const ELFObjectFileBase *getObject() const {
- return cast<ELFObjectFileBase>(RelocationRef::getObject());
- }
-
- Expected<int64_t> getAddend() const {
- return getObject()->getRelocationAddend(getRawDataRefImpl());
- }
-};
-
-class elf_relocation_iterator : public relocation_iterator {
-public:
- elf_relocation_iterator(const relocation_iterator &B)
- : relocation_iterator(RelocationRef(
- B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
-
- const ELFRelocationRef *operator->() const {
- return static_cast<const ELFRelocationRef *>(
- relocation_iterator::operator->());
- }
-
- const ELFRelocationRef &operator*() const {
- return static_cast<const ELFRelocationRef &>(
- relocation_iterator::operator*());
- }
-};
-
-inline ELFObjectFileBase::elf_symbol_iterator_range
-ELFObjectFileBase::symbols() const {
- return elf_symbol_iterator_range(symbol_begin(), symbol_end());
-}
-
-template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
- uint16_t getEMachine() const override;
- uint16_t getEType() const override;
- uint64_t getSymbolSize(DataRefImpl Sym) const override;
-
-public:
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
-
- SectionRef toSectionRef(const Elf_Shdr *Sec) const {
- return SectionRef(toDRI(Sec), this);
- }
-
+};
+
+class ELFSectionRef : public SectionRef {
+public:
+ ELFSectionRef(const SectionRef &B) : SectionRef(B) {
+ assert(isa<ELFObjectFileBase>(SectionRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(SectionRef::getObject());
+ }
+
+ uint32_t getType() const {
+ return getObject()->getSectionType(getRawDataRefImpl());
+ }
+
+ uint64_t getFlags() const {
+ return getObject()->getSectionFlags(getRawDataRefImpl());
+ }
+
+ uint64_t getOffset() const {
+ return getObject()->getSectionOffset(getRawDataRefImpl());
+ }
+};
+
+class elf_section_iterator : public section_iterator {
+public:
+ elf_section_iterator(const section_iterator &B) : section_iterator(B) {
+ assert(isa<ELFObjectFileBase>(B->getObject()));
+ }
+
+ const ELFSectionRef *operator->() const {
+ return static_cast<const ELFSectionRef *>(section_iterator::operator->());
+ }
+
+ const ELFSectionRef &operator*() const {
+ return static_cast<const ELFSectionRef &>(section_iterator::operator*());
+ }
+};
+
+class ELFSymbolRef : public SymbolRef {
+public:
+ ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
+ assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
+ }
+
+ uint64_t getSize() const {
+ return getObject()->getSymbolSize(getRawDataRefImpl());
+ }
+
+ uint8_t getBinding() const {
+ return getObject()->getSymbolBinding(getRawDataRefImpl());
+ }
+
+ uint8_t getOther() const {
+ return getObject()->getSymbolOther(getRawDataRefImpl());
+ }
+
+ uint8_t getELFType() const {
+ return getObject()->getSymbolELFType(getRawDataRefImpl());
+ }
+
+ StringRef getELFTypeName() const {
+ uint8_t Type = getELFType();
+ for (auto &EE : ElfSymbolTypes) {
+ if (EE.Value == Type) {
+ return EE.AltName;
+ }
+ }
+ return "";
+ }
+};
+
+class elf_symbol_iterator : public symbol_iterator {
+public:
+ elf_symbol_iterator(const basic_symbol_iterator &B)
+ : symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+ cast<ELFObjectFileBase>(B->getObject()))) {}
+
+ const ELFSymbolRef *operator->() const {
+ return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
+ }
+
+ const ELFSymbolRef &operator*() const {
+ return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
+ }
+};
+
+class ELFRelocationRef : public RelocationRef {
+public:
+ ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
+ assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(RelocationRef::getObject());
+ }
+
+ Expected<int64_t> getAddend() const {
+ return getObject()->getRelocationAddend(getRawDataRefImpl());
+ }
+};
+
+class elf_relocation_iterator : public relocation_iterator {
+public:
+ elf_relocation_iterator(const relocation_iterator &B)
+ : relocation_iterator(RelocationRef(
+ B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
+
+ const ELFRelocationRef *operator->() const {
+ return static_cast<const ELFRelocationRef *>(
+ relocation_iterator::operator->());
+ }
+
+ const ELFRelocationRef &operator*() const {
+ return static_cast<const ELFRelocationRef &>(
+ relocation_iterator::operator*());
+ }
+};
+
+inline ELFObjectFileBase::elf_symbol_iterator_range
+ELFObjectFileBase::symbols() const {
+ return elf_symbol_iterator_range(symbol_begin(), symbol_end());
+}
+
+template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
+ uint16_t getEMachine() const override;
+ uint16_t getEType() const override;
+ uint64_t getSymbolSize(DataRefImpl Sym) const override;
+
+public:
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+
+ SectionRef toSectionRef(const Elf_Shdr *Sec) const {
+ return SectionRef(toDRI(Sec), this);
+ }
+
ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
}
bool IsContentValid() const { return ContentValid; }
-private:
- ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
- const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
+private:
+ ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
+ const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
const Elf_Shdr *DotSymtabShndxSec);
-
+
bool ContentValid = false;
-protected:
- ELFFile<ELFT> EF;
-
- const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
- const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
+protected:
+ ELFFile<ELFT> EF;
+
+ const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
+ const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
-
+
Error initContent() override;
- void moveSymbolNext(DataRefImpl &Symb) const override;
- Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
- Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
- uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
- uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
- uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
- uint8_t getSymbolBinding(DataRefImpl Symb) const override;
- uint8_t getSymbolOther(DataRefImpl Symb) const override;
- uint8_t getSymbolELFType(DataRefImpl Symb) const override;
- Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
- Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
- const Elf_Shdr *SymTab) const;
- Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
-
- void moveSectionNext(DataRefImpl &Sec) const override;
- Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
- uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
- uint64_t getSectionSize(DataRefImpl Sec) const override;
- Expected<ArrayRef<uint8_t>>
- getSectionContents(DataRefImpl Sec) const override;
- uint64_t getSectionAlignment(DataRefImpl Sec) const override;
- bool isSectionCompressed(DataRefImpl Sec) const override;
- bool isSectionText(DataRefImpl Sec) const override;
- bool isSectionData(DataRefImpl Sec) const override;
- bool isSectionBSS(DataRefImpl Sec) const override;
- bool isSectionVirtual(DataRefImpl Sec) const override;
- bool isBerkeleyText(DataRefImpl Sec) const override;
- bool isBerkeleyData(DataRefImpl Sec) const override;
- bool isDebugSection(StringRef SectionName) const override;
- relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
- relocation_iterator section_rel_end(DataRefImpl Sec) const override;
- std::vector<SectionRef> dynamic_relocation_sections() const override;
- Expected<section_iterator>
- getRelocatedSection(DataRefImpl Sec) const override;
-
- void moveRelocationNext(DataRefImpl &Rel) const override;
- uint64_t getRelocationOffset(DataRefImpl Rel) const override;
- symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- uint64_t getRelocationType(DataRefImpl Rel) const override;
- void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
-
- uint32_t getSectionType(DataRefImpl Sec) const override;
- uint64_t getSectionFlags(DataRefImpl Sec) const override;
- uint64_t getSectionOffset(DataRefImpl Sec) const override;
- StringRef getRelocationTypeName(uint32_t Type) const;
-
- DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
- DataRefImpl DRI;
- if (!SymTable) {
- DRI.d.a = 0;
- DRI.d.b = 0;
- return DRI;
- }
- assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
- SymTable->sh_type == ELF::SHT_DYNSYM);
-
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr) {
- DRI.d.a = 0;
- DRI.d.b = 0;
- return DRI;
- }
- uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
- unsigned SymTableIndex =
- (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
-
- DRI.d.a = SymTableIndex;
- DRI.d.b = SymbolNum;
- return DRI;
- }
-
- const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
- return reinterpret_cast<const Elf_Shdr *>(Sec.p);
- }
-
- DataRefImpl toDRI(const Elf_Shdr *Sec) const {
- DataRefImpl DRI;
- DRI.p = reinterpret_cast<uintptr_t>(Sec);
- return DRI;
- }
-
- DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
- DataRefImpl DRI;
- DRI.p = reinterpret_cast<uintptr_t>(Dyn);
- return DRI;
- }
-
- bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
- unsigned char Binding = ESym->getBinding();
- unsigned char Visibility = ESym->getVisibility();
-
- // A symbol is exported if its binding is either GLOBAL or WEAK, and its
- // visibility is either DEFAULT or PROTECTED. All other symbols are not
- // exported.
- return (
- (Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK ||
- Binding == ELF::STB_GNU_UNIQUE) &&
- (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
- }
-
- Error getBuildAttributes(ELFAttributeParser &Attributes) const override {
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
-
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
- Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+ uint8_t getSymbolBinding(DataRefImpl Symb) const override;
+ uint8_t getSymbolOther(DataRefImpl Symb) const override;
+ uint8_t getSymbolELFType(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb,
+ const Elf_Shdr *SymTab) const;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool isBerkeleyText(DataRefImpl Sec) const override;
+ bool isBerkeleyData(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+ std::vector<SectionRef> dynamic_relocation_sections() const override;
+ Expected<section_iterator>
+ getRelocatedSection(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ uint32_t getSectionType(DataRefImpl Sec) const override;
+ uint64_t getSectionFlags(DataRefImpl Sec) const override;
+ uint64_t getSectionOffset(DataRefImpl Sec) const override;
+ StringRef getRelocationTypeName(uint32_t Type) const;
+
+ DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
+ DataRefImpl DRI;
+ if (!SymTable) {
+ DRI.d.a = 0;
+ DRI.d.b = 0;
+ return DRI;
+ }
+ assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
+ SymTable->sh_type == ELF::SHT_DYNSYM);
+
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr) {
+ DRI.d.a = 0;
+ DRI.d.b = 0;
+ return DRI;
+ }
+ uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
+ unsigned SymTableIndex =
+ (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
+
+ DRI.d.a = SymTableIndex;
+ DRI.d.b = SymbolNum;
+ return DRI;
+ }
+
+ const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const {
+ return reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ }
+
+ DataRefImpl toDRI(const Elf_Shdr *Sec) const {
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(Sec);
+ return DRI;
+ }
+
+ DataRefImpl toDRI(const Elf_Dyn *Dyn) const {
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(Dyn);
+ return DRI;
+ }
+
+ bool isExportedToOtherDSO(const Elf_Sym *ESym) const {
+ unsigned char Binding = ESym->getBinding();
+ unsigned char Visibility = ESym->getVisibility();
+
+ // A symbol is exported if its binding is either GLOBAL or WEAK, and its
+ // visibility is either DEFAULT or PROTECTED. All other symbols are not
+ // exported.
+ return (
+ (Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK ||
+ Binding == ELF::STB_GNU_UNIQUE) &&
+ (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
+ }
+
+ Error getBuildAttributes(ELFAttributeParser &Attributes) const override {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
+ Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
auto ErrorOrContents = EF.getSectionContents(Sec);
- if (!ErrorOrContents)
- return ErrorOrContents.takeError();
-
- auto Contents = ErrorOrContents.get();
- if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1)
- return Error::success();
-
- if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
- return E;
- break;
- }
- }
- return Error::success();
- }
-
- // This flag is used for classof, to distinguish ELFObjectFile from
- // its subclass. If more subclasses will be created, this flag will
- // have to become an enum.
- bool isDyldELFObject;
-
-public:
- ELFObjectFile(ELFObjectFile<ELFT> &&Other);
+ if (!ErrorOrContents)
+ return ErrorOrContents.takeError();
+
+ auto Contents = ErrorOrContents.get();
+ if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1)
+ return Error::success();
+
+ if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
+ return E;
+ break;
+ }
+ }
+ return Error::success();
+ }
+
+ // This flag is used for classof, to distinguish ELFObjectFile from
+ // its subclass. If more subclasses will be created, this flag will
+ // have to become an enum.
+ bool isDyldELFObject;
+
+public:
+ ELFObjectFile(ELFObjectFile<ELFT> &&Other);
static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object,
bool InitContent = true);
-
- const Elf_Rel *getRel(DataRefImpl Rel) const;
- const Elf_Rela *getRela(DataRefImpl Rela) const;
-
+
+ const Elf_Rel *getRel(DataRefImpl Rel) const;
+ const Elf_Rela *getRela(DataRefImpl Rela) const;
+
Expected<const Elf_Sym *> getSymbol(DataRefImpl Sym) const {
return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
- }
-
+ }
+
/// Get the relocation section that contains \a Rel.
const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
auto RelSecOrErr = EF.getSection(Rel.d.a);
@@ -418,51 +418,51 @@ public:
return *RelSecOrErr;
}
- const Elf_Shdr *getSection(DataRefImpl Sec) const {
- return reinterpret_cast<const Elf_Shdr *>(Sec.p);
- }
-
- basic_symbol_iterator symbol_begin() const override;
- basic_symbol_iterator symbol_end() const override;
-
- elf_symbol_iterator dynamic_symbol_begin() const;
- elf_symbol_iterator dynamic_symbol_end() const;
-
- section_iterator section_begin() const override;
- section_iterator section_end() const override;
-
- Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
-
- uint8_t getBytesInAddress() const override;
- StringRef getFileFormatName() const override;
- Triple::ArchType getArch() const override;
- Expected<uint64_t> getStartAddress() const override;
-
+ const Elf_Shdr *getSection(DataRefImpl Sec) const {
+ return reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ }
+
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ elf_symbol_iterator dynamic_symbol_begin() const;
+ elf_symbol_iterator dynamic_symbol_end() const;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
+
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ Expected<uint64_t> getStartAddress() const override;
+
unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; }
-
+
const ELFFile<ELFT> &getELFFile() const { return EF; }
-
- bool isDyldType() const { return isDyldELFObject; }
- static bool classof(const Binary *v) {
- return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
- ELFT::Is64Bits);
- }
-
- elf_symbol_iterator_range getDynamicSymbolIterators() const override;
-
- bool isRelocatableObject() const override;
-};
-
-using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
-using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
-using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
-using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
-
-template <class ELFT>
-void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
- ++Sym.d.b;
-}
-
+
+ bool isDyldType() const { return isDyldELFObject; }
+ static bool classof(const Binary *v) {
+ return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
+ ELFT::Is64Bits);
+ }
+
+ elf_symbol_iterator_range getDynamicSymbolIterators() const override;
+
+ bool isRelocatableObject() const override;
+};
+
+using ELF32LEObjectFile = ELFObjectFile<ELF32LE>;
+using ELF64LEObjectFile = ELFObjectFile<ELF64LE>;
+using ELF32BEObjectFile = ELFObjectFile<ELF32BE>;
+using ELF64BEObjectFile = ELFObjectFile<ELF64BE>;
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
+ ++Sym.d.b;
+}
+
template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
@@ -492,94 +492,94 @@ template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
return Error::success();
}
-template <class ELFT>
-Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
+template <class ELFT>
+Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
if (!SymOrErr)
return SymOrErr.takeError();
- auto SymTabOrErr = EF.getSection(Sym.d.a);
- if (!SymTabOrErr)
- return SymTabOrErr.takeError();
- const Elf_Shdr *SymTableSec = *SymTabOrErr;
- auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
- if (!StrTabOrErr)
- return StrTabOrErr.takeError();
- const Elf_Shdr *StringTableSec = *StrTabOrErr;
+ auto SymTabOrErr = EF.getSection(Sym.d.a);
+ if (!SymTabOrErr)
+ return SymTabOrErr.takeError();
+ const Elf_Shdr *SymTableSec = *SymTabOrErr;
+ auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
+ if (!StrTabOrErr)
+ return StrTabOrErr.takeError();
+ const Elf_Shdr *StringTableSec = *StrTabOrErr;
auto SymStrTabOrErr = EF.getStringTable(*StringTableSec);
- if (!SymStrTabOrErr)
- return SymStrTabOrErr.takeError();
+ if (!SymStrTabOrErr)
+ return SymStrTabOrErr.takeError();
Expected<StringRef> Name = (*SymOrErr)->getName(*SymStrTabOrErr);
- if (Name && !Name->empty())
- return Name;
-
- // If the symbol name is empty use the section name.
+ if (Name && !Name->empty())
+ return Name;
+
+ // If the symbol name is empty use the section name.
if ((*SymOrErr)->getType() == ELF::STT_SECTION) {
- if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) {
- consumeError(Name.takeError());
- return (*SecOrErr)->getName();
- }
- }
- return Name;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
- return getSection(Sec)->sh_flags;
-}
-
-template <class ELFT>
-uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
- return getSection(Sec)->sh_type;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
- return getSection(Sec)->sh_offset;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
+ if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) {
+ consumeError(Name.takeError());
+ return (*SecOrErr)->getName();
+ }
+ }
+ return Name;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags;
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_type;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_offset;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
report_fatal_error(SymOrErr.takeError());
uint64_t Ret = (*SymOrErr)->st_value;
if ((*SymOrErr)->st_shndx == ELF::SHN_ABS)
- return Ret;
-
+ return Ret;
+
const Elf_Ehdr &Header = EF.getHeader();
- // Clear the ARM/Thumb or microMIPS indicator flag.
+ // Clear the ARM/Thumb or microMIPS indicator flag.
if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) &&
(*SymOrErr)->getType() == ELF::STT_FUNC)
- Ret &= ~1;
-
- return Ret;
-}
-
-template <class ELFT>
-Expected<uint64_t>
-ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
- Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb);
- if (!SymbolValueOrErr)
- // TODO: Test this error.
- return SymbolValueOrErr.takeError();
-
- uint64_t Result = *SymbolValueOrErr;
+ Ret &= ~1;
+
+ return Ret;
+}
+
+template <class ELFT>
+Expected<uint64_t>
+ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
+ Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb);
+ if (!SymbolValueOrErr)
+ // TODO: Test this error.
+ return SymbolValueOrErr.takeError();
+
+ uint64_t Result = *SymbolValueOrErr;
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
return SymOrErr.takeError();
switch ((*SymOrErr)->st_shndx) {
- case ELF::SHN_COMMON:
- case ELF::SHN_UNDEF:
- case ELF::SHN_ABS:
- return Result;
- }
-
- auto SymTabOrErr = EF.getSection(Symb.d.a);
- if (!SymTabOrErr)
- return SymTabOrErr.takeError();
-
+ case ELF::SHN_COMMON:
+ case ELF::SHN_UNDEF:
+ case ELF::SHN_ABS:
+ return Result;
+ }
+
+ auto SymTabOrErr = EF.getSection(Symb.d.a);
+ if (!SymTabOrErr)
+ return SymTabOrErr.takeError();
+
if (EF.getHeader().e_type == ELF::ET_REL) {
ArrayRef<Elf_Word> ShndxTable;
if (DotSymtabShndxSec) {
@@ -593,169 +593,169 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
Expected<const Elf_Shdr *> SectionOrErr =
EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable);
- if (!SectionOrErr)
- return SectionOrErr.takeError();
- const Elf_Shdr *Section = *SectionOrErr;
- if (Section)
- Result += Section->sh_addr;
- }
-
- return Result;
-}
-
-template <class ELFT>
-uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
+ if (!SectionOrErr)
+ return SectionOrErr.takeError();
+ const Elf_Shdr *Section = *SectionOrErr;
+ if (Section)
+ Result += Section->sh_addr;
+ }
+
+ return Result;
+}
+
+template <class ELFT>
+uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
report_fatal_error(SymOrErr.takeError());
if ((*SymOrErr)->st_shndx == ELF::SHN_COMMON)
return (*SymOrErr)->st_value;
- return 0;
-}
-
-template <class ELFT>
-uint16_t ELFObjectFile<ELFT>::getEMachine() const {
+ return 0;
+}
+
+template <class ELFT>
+uint16_t ELFObjectFile<ELFT>::getEMachine() const {
return EF.getHeader().e_machine;
-}
-
-template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
+}
+
+template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
return EF.getHeader().e_type;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
if (!SymOrErr)
report_fatal_error(SymOrErr.takeError());
return (*SymOrErr)->st_size;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
return getSymbolSize(Symb);
-}
-
-template <class ELFT>
-uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
report_fatal_error(SymOrErr.takeError());
return (*SymOrErr)->getBinding();
-}
-
-template <class ELFT>
-uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
report_fatal_error(SymOrErr.takeError());
return (*SymOrErr)->st_other;
-}
-
-template <class ELFT>
-uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
report_fatal_error(SymOrErr.takeError());
return (*SymOrErr)->getType();
-}
-
-template <class ELFT>
-Expected<SymbolRef::Type>
-ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
+}
+
+template <class ELFT>
+Expected<SymbolRef::Type>
+ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
return SymOrErr.takeError();
-
+
switch ((*SymOrErr)->getType()) {
- case ELF::STT_NOTYPE:
- return SymbolRef::ST_Unknown;
- case ELF::STT_SECTION:
- return SymbolRef::ST_Debug;
- case ELF::STT_FILE:
- return SymbolRef::ST_File;
- case ELF::STT_FUNC:
- return SymbolRef::ST_Function;
- case ELF::STT_OBJECT:
- case ELF::STT_COMMON:
- case ELF::STT_TLS:
- return SymbolRef::ST_Data;
- default:
- return SymbolRef::ST_Other;
- }
-}
-
-template <class ELFT>
-Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
+ case ELF::STT_NOTYPE:
+ return SymbolRef::ST_Unknown;
+ case ELF::STT_SECTION:
+ return SymbolRef::ST_Debug;
+ case ELF::STT_FILE:
+ return SymbolRef::ST_File;
+ case ELF::STT_FUNC:
+ return SymbolRef::ST_Function;
+ case ELF::STT_OBJECT:
+ case ELF::STT_COMMON:
+ case ELF::STT_TLS:
+ return SymbolRef::ST_Data;
+ default:
+ return SymbolRef::ST_Other;
+ }
+}
+
+template <class ELFT>
+Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
if (!SymOrErr)
return SymOrErr.takeError();
-
+
const Elf_Sym *ESym = *SymOrErr;
- uint32_t Result = SymbolRef::SF_None;
-
- if (ESym->getBinding() != ELF::STB_LOCAL)
- Result |= SymbolRef::SF_Global;
-
- if (ESym->getBinding() == ELF::STB_WEAK)
- Result |= SymbolRef::SF_Weak;
-
- if (ESym->st_shndx == ELF::SHN_ABS)
- Result |= SymbolRef::SF_Absolute;
-
- if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
- Result |= SymbolRef::SF_FormatSpecific;
-
- if (Expected<typename ELFT::SymRange> SymbolsOrErr =
- EF.symbols(DotSymtabSec)) {
- // Set the SF_FormatSpecific flag for the 0-index null symbol.
- if (ESym == SymbolsOrErr->begin())
- Result |= SymbolRef::SF_FormatSpecific;
- } else
- // TODO: Test this error.
- return SymbolsOrErr.takeError();
-
- if (Expected<typename ELFT::SymRange> SymbolsOrErr =
- EF.symbols(DotDynSymSec)) {
- // Set the SF_FormatSpecific flag for the 0-index null symbol.
- if (ESym == SymbolsOrErr->begin())
- Result |= SymbolRef::SF_FormatSpecific;
- } else
- // TODO: Test this error.
- return SymbolsOrErr.takeError();
-
+ uint32_t Result = SymbolRef::SF_None;
+
+ if (ESym->getBinding() != ELF::STB_LOCAL)
+ Result |= SymbolRef::SF_Global;
+
+ if (ESym->getBinding() == ELF::STB_WEAK)
+ Result |= SymbolRef::SF_Weak;
+
+ if (ESym->st_shndx == ELF::SHN_ABS)
+ Result |= SymbolRef::SF_Absolute;
+
+ if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
+ Result |= SymbolRef::SF_FormatSpecific;
+
+ if (Expected<typename ELFT::SymRange> SymbolsOrErr =
+ EF.symbols(DotSymtabSec)) {
+ // Set the SF_FormatSpecific flag for the 0-index null symbol.
+ if (ESym == SymbolsOrErr->begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else
+ // TODO: Test this error.
+ return SymbolsOrErr.takeError();
+
+ if (Expected<typename ELFT::SymRange> SymbolsOrErr =
+ EF.symbols(DotDynSymSec)) {
+ // Set the SF_FormatSpecific flag for the 0-index null symbol.
+ if (ESym == SymbolsOrErr->begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else
+ // TODO: Test this error.
+ return SymbolsOrErr.takeError();
+
if (EF.getHeader().e_machine == ELF::EM_ARM) {
- if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
- StringRef Name = *NameOrErr;
- if (Name.startswith("$d") || Name.startswith("$t") ||
- Name.startswith("$a"))
- Result |= SymbolRef::SF_FormatSpecific;
- } else {
- // TODO: Actually report errors helpfully.
- consumeError(NameOrErr.takeError());
- }
- if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
- Result |= SymbolRef::SF_Thumb;
- }
-
- if (ESym->st_shndx == ELF::SHN_UNDEF)
- Result |= SymbolRef::SF_Undefined;
-
- if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
- Result |= SymbolRef::SF_Common;
-
- if (isExportedToOtherDSO(ESym))
- Result |= SymbolRef::SF_Exported;
-
- if (ESym->getVisibility() == ELF::STV_HIDDEN)
- Result |= SymbolRef::SF_Hidden;
-
- return Result;
-}
-
-template <class ELFT>
-Expected<section_iterator>
-ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
- const Elf_Shdr *SymTab) const {
+ if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
+ StringRef Name = *NameOrErr;
+ if (Name.startswith("$d") || Name.startswith("$t") ||
+ Name.startswith("$a"))
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else {
+ // TODO: Actually report errors helpfully.
+ consumeError(NameOrErr.takeError());
+ }
+ if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1)
+ Result |= SymbolRef::SF_Thumb;
+ }
+
+ if (ESym->st_shndx == ELF::SHN_UNDEF)
+ Result |= SymbolRef::SF_Undefined;
+
+ if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON)
+ Result |= SymbolRef::SF_Common;
+
+ if (isExportedToOtherDSO(ESym))
+ Result |= SymbolRef::SF_Exported;
+
+ if (ESym->getVisibility() == ELF::STV_HIDDEN)
+ Result |= SymbolRef::SF_Hidden;
+
+ return Result;
+}
+
+template <class ELFT>
+Expected<section_iterator>
+ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
+ const Elf_Shdr *SymTab) const {
ArrayRef<Elf_Word> ShndxTable;
if (DotSymtabShndxSec) {
// TODO: Test this error.
@@ -767,550 +767,550 @@ ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
}
auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
- if (!ESecOrErr)
- return ESecOrErr.takeError();
-
- const Elf_Shdr *ESec = *ESecOrErr;
- if (!ESec)
- return section_end();
-
- DataRefImpl Sec;
- Sec.p = reinterpret_cast<intptr_t>(ESec);
- return section_iterator(SectionRef(Sec, this));
-}
-
-template <class ELFT>
-Expected<section_iterator>
-ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
+ if (!ESecOrErr)
+ return ESecOrErr.takeError();
+
+ const Elf_Shdr *ESec = *ESecOrErr;
+ if (!ESec)
+ return section_end();
+
+ DataRefImpl Sec;
+ Sec.p = reinterpret_cast<intptr_t>(ESec);
+ return section_iterator(SectionRef(Sec, this));
+}
+
+template <class ELFT>
+Expected<section_iterator>
+ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
if (!SymOrErr)
return SymOrErr.takeError();
- auto SymTabOrErr = EF.getSection(Symb.d.a);
- if (!SymTabOrErr)
- return SymTabOrErr.takeError();
+ auto SymTabOrErr = EF.getSection(Symb.d.a);
+ if (!SymTabOrErr)
+ return SymTabOrErr.takeError();
return getSymbolSection(*SymOrErr, *SymTabOrErr);
-}
-
-template <class ELFT>
-void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
- const Elf_Shdr *ESec = getSection(Sec);
- Sec = toDRI(++ESec);
-}
-
-template <class ELFT>
-Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
+}
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
+ const Elf_Shdr *ESec = getSection(Sec);
+ Sec = toDRI(++ESec);
+}
+
+template <class ELFT>
+Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
return EF.getSectionName(*getSection(Sec));
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
- return getSection(Sec)->sh_addr;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
- auto SectionsOrErr = EF.sections();
- handleAllErrors(std::move(SectionsOrErr.takeError()),
- [](const ErrorInfoBase &) {
- llvm_unreachable("unable to get section index");
- });
- const Elf_Shdr *First = SectionsOrErr->begin();
- return getSection(Sec) - First;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
- return getSection(Sec)->sh_size;
-}
-
-template <class ELFT>
-Expected<ArrayRef<uint8_t>>
-ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
- const Elf_Shdr *EShdr = getSection(Sec);
- if (EShdr->sh_type == ELF::SHT_NOBITS)
- return makeArrayRef((const uint8_t *)base(), 0);
- if (Error E =
- checkOffset(getMemoryBufferRef(),
- (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
- return std::move(E);
- return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
- EShdr->sh_size);
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
- return getSection(Sec)->sh_addralign;
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
- return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
- return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
- const Elf_Shdr *EShdr = getSection(Sec);
- return EShdr->sh_type == ELF::SHT_PROGBITS &&
- EShdr->sh_flags & ELF::SHF_ALLOC &&
- !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
- const Elf_Shdr *EShdr = getSection(Sec);
- return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
- EShdr->sh_type == ELF::SHT_NOBITS;
-}
-
-template <class ELFT>
-std::vector<SectionRef>
-ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
- std::vector<SectionRef> Res;
- std::vector<uintptr_t> Offsets;
-
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return Res;
-
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (Sec.sh_type != ELF::SHT_DYNAMIC)
- continue;
- Elf_Dyn *Dynamic =
- reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
- for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
- if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
- Dynamic->d_tag == ELF::DT_JMPREL) {
- Offsets.push_back(Dynamic->d_un.d_val);
- }
- }
- }
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (is_contained(Offsets, Sec.sh_addr))
- Res.emplace_back(toDRI(&Sec), this);
- }
- return Res;
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
- return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const {
- return getSection(Sec)->sh_flags & ELF::SHF_ALLOC &&
- (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR ||
- !(getSection(Sec)->sh_flags & ELF::SHF_WRITE));
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
- const Elf_Shdr *EShdr = getSection(Sec);
- return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
- EShdr->sh_flags & ELF::SHF_ALLOC;
-}
-
-template <class ELFT>
-bool ELFObjectFile<ELFT>::isDebugSection(StringRef SectionName) const {
- return SectionName.startswith(".debug") ||
- SectionName.startswith(".zdebug") || SectionName == ".gdb_index";
-}
-
-template <class ELFT>
-relocation_iterator
-ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
- DataRefImpl RelData;
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return relocation_iterator(RelocationRef());
- uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_addr;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const {
+ auto SectionsOrErr = EF.sections();
+ handleAllErrors(std::move(SectionsOrErr.takeError()),
+ [](const ErrorInfoBase &) {
+ llvm_unreachable("unable to get section index");
+ });
+ const Elf_Shdr *First = SectionsOrErr->begin();
+ return getSection(Sec) - First;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_size;
+}
+
+template <class ELFT>
+Expected<ArrayRef<uint8_t>>
+ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ if (EShdr->sh_type == ELF::SHT_NOBITS)
+ return makeArrayRef((const uint8_t *)base(), 0);
+ if (Error E =
+ checkOffset(getMemoryBufferRef(),
+ (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
+ return std::move(E);
+ return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
+ EShdr->sh_size);
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_addralign;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ return EShdr->sh_type == ELF::SHT_PROGBITS &&
+ EShdr->sh_flags & ELF::SHF_ALLOC &&
+ !(EShdr->sh_flags & ELF::SHF_EXECINSTR);
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) &&
+ EShdr->sh_type == ELF::SHT_NOBITS;
+}
+
+template <class ELFT>
+std::vector<SectionRef>
+ELFObjectFile<ELFT>::dynamic_relocation_sections() const {
+ std::vector<SectionRef> Res;
+ std::vector<uintptr_t> Offsets;
+
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return Res;
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (Sec.sh_type != ELF::SHT_DYNAMIC)
+ continue;
+ Elf_Dyn *Dynamic =
+ reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset);
+ for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) {
+ if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA ||
+ Dynamic->d_tag == ELF::DT_JMPREL) {
+ Offsets.push_back(Dynamic->d_un.d_val);
+ }
+ }
+ }
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ if (is_contained(Offsets, Sec.sh_addr))
+ Res.emplace_back(toDRI(&Sec), this);
+ }
+ return Res;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_type == ELF::SHT_NOBITS;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const {
+ return getSection(Sec)->sh_flags & ELF::SHF_ALLOC &&
+ (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR ||
+ !(getSection(Sec)->sh_flags & ELF::SHF_WRITE));
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
+ const Elf_Shdr *EShdr = getSection(Sec);
+ return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS &&
+ EShdr->sh_flags & ELF::SHF_ALLOC;
+}
+
+template <class ELFT>
+bool ELFObjectFile<ELFT>::isDebugSection(StringRef SectionName) const {
+ return SectionName.startswith(".debug") ||
+ SectionName.startswith(".zdebug") || SectionName == ".gdb_index";
+}
+
+template <class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
+ DataRefImpl RelData;
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return relocation_iterator(RelocationRef());
+ uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize;
- RelData.d.b = 0;
- return relocation_iterator(RelocationRef(RelData, this));
-}
-
-template <class ELFT>
-relocation_iterator
-ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
- const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
- relocation_iterator Begin = section_rel_begin(Sec);
- if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
- return Begin;
- DataRefImpl RelData = Begin->getRawDataRefImpl();
- const Elf_Shdr *RelSec = getRelSection(RelData);
-
- // Error check sh_link here so that getRelocationSymbol can just use it.
- auto SymSecOrErr = EF.getSection(RelSec->sh_link);
- if (!SymSecOrErr)
- report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
-
- RelData.d.b += S->sh_size / S->sh_entsize;
- return relocation_iterator(RelocationRef(RelData, this));
-}
-
-template <class ELFT>
-Expected<section_iterator>
-ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
+ RelData.d.b = 0;
+ return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template <class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
+ const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
+ relocation_iterator Begin = section_rel_begin(Sec);
+ if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL)
+ return Begin;
+ DataRefImpl RelData = Begin->getRawDataRefImpl();
+ const Elf_Shdr *RelSec = getRelSection(RelData);
+
+ // Error check sh_link here so that getRelocationSymbol can just use it.
+ auto SymSecOrErr = EF.getSection(RelSec->sh_link);
+ if (!SymSecOrErr)
+ report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
+
+ RelData.d.b += S->sh_size / S->sh_entsize;
+ return relocation_iterator(RelocationRef(RelData, this));
+}
+
+template <class ELFT>
+Expected<section_iterator>
+ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
if (EF.getHeader().e_type != ELF::ET_REL)
- return section_end();
-
- const Elf_Shdr *EShdr = getSection(Sec);
- uintX_t Type = EShdr->sh_type;
- if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
- return section_end();
-
- Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
- if (!SecOrErr)
- return SecOrErr.takeError();
- return section_iterator(SectionRef(toDRI(*SecOrErr), this));
-}
-
-// Relocations
-template <class ELFT>
-void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
- ++Rel.d.b;
-}
-
-template <class ELFT>
-symbol_iterator
-ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
- uint32_t symbolIdx;
- const Elf_Shdr *sec = getRelSection(Rel);
- if (sec->sh_type == ELF::SHT_REL)
- symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
- else
- symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
- if (!symbolIdx)
- return symbol_end();
-
- // FIXME: error check symbolIdx
- DataRefImpl SymbolData;
- SymbolData.d.a = sec->sh_link;
- SymbolData.d.b = symbolIdx;
- return symbol_iterator(SymbolRef(SymbolData, this));
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
- const Elf_Shdr *sec = getRelSection(Rel);
- if (sec->sh_type == ELF::SHT_REL)
- return getRel(Rel)->r_offset;
-
- return getRela(Rel)->r_offset;
-}
-
-template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
- const Elf_Shdr *sec = getRelSection(Rel);
- if (sec->sh_type == ELF::SHT_REL)
- return getRel(Rel)->getType(EF.isMips64EL());
- else
- return getRela(Rel)->getType(EF.isMips64EL());
-}
-
-template <class ELFT>
-StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
+ return section_end();
+
+ const Elf_Shdr *EShdr = getSection(Sec);
+ uintX_t Type = EShdr->sh_type;
+ if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
+ return section_end();
+
+ Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
+ if (!SecOrErr)
+ return SecOrErr.takeError();
+ return section_iterator(SectionRef(toDRI(*SecOrErr), this));
+}
+
+// Relocations
+template <class ELFT>
+void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const {
+ ++Rel.d.b;
+}
+
+template <class ELFT>
+symbol_iterator
+ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
+ uint32_t symbolIdx;
+ const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_REL)
+ symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL());
+ else
+ symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL());
+ if (!symbolIdx)
+ return symbol_end();
+
+ // FIXME: error check symbolIdx
+ DataRefImpl SymbolData;
+ SymbolData.d.a = sec->sh_link;
+ SymbolData.d.b = symbolIdx;
+ return symbol_iterator(SymbolRef(SymbolData, this));
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
+ const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_REL)
+ return getRel(Rel)->r_offset;
+
+ return getRela(Rel)->r_offset;
+}
+
+template <class ELFT>
+uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const {
+ const Elf_Shdr *sec = getRelSection(Rel);
+ if (sec->sh_type == ELF::SHT_REL)
+ return getRel(Rel)->getType(EF.isMips64EL());
+ else
+ return getRela(Rel)->getType(EF.isMips64EL());
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
return getELFRelocationTypeName(EF.getHeader().e_machine, Type);
-}
-
-template <class ELFT>
-void ELFObjectFile<ELFT>::getRelocationTypeName(
- DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
- uint32_t type = getRelocationType(Rel);
- EF.getRelocationTypeName(type, Result);
-}
-
-template <class ELFT>
-Expected<int64_t>
-ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
- if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
- return createError("Section is not SHT_RELA");
- return (int64_t)getRela(Rel)->r_addend;
-}
-
-template <class ELFT>
-const typename ELFObjectFile<ELFT>::Elf_Rel *
-ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
- assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
- auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
- if (!Ret)
- report_fatal_error(errorToErrorCode(Ret.takeError()).message());
- return *Ret;
-}
-
-template <class ELFT>
-const typename ELFObjectFile<ELFT>::Elf_Rela *
-ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
- assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
- auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
- if (!Ret)
- report_fatal_error(errorToErrorCode(Ret.takeError()).message());
- return *Ret;
-}
-
-template <class ELFT>
-Expected<ELFObjectFile<ELFT>>
+}
+
+template <class ELFT>
+void ELFObjectFile<ELFT>::getRelocationTypeName(
+ DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
+ uint32_t type = getRelocationType(Rel);
+ EF.getRelocationTypeName(type, Result);
+}
+
+template <class ELFT>
+Expected<int64_t>
+ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const {
+ if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
+ return createError("Section is not SHT_RELA");
+ return (int64_t)getRela(Rel)->r_addend;
+}
+
+template <class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rel *
+ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
+ assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
+ auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
+ if (!Ret)
+ report_fatal_error(errorToErrorCode(Ret.takeError()).message());
+ return *Ret;
+}
+
+template <class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rela *
+ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
+ assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
+ auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
+ if (!Ret)
+ report_fatal_error(errorToErrorCode(Ret.takeError()).message());
+ return *Ret;
+}
+
+template <class ELFT>
+Expected<ELFObjectFile<ELFT>>
ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
- auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
- if (Error E = EFOrErr.takeError())
- return std::move(E);
-
+ auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
+ if (Error E = EFOrErr.takeError())
+ return std::move(E);
+
ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr,
nullptr};
if (InitContent)
if (Error E = Obj.initContent())
return std::move(E);
return std::move(Obj);
-}
-
-template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
- const Elf_Shdr *DotDynSymSec,
- const Elf_Shdr *DotSymtabSec,
+}
+
+template <class ELFT>
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
+ const Elf_Shdr *DotDynSymSec,
+ const Elf_Shdr *DotSymtabSec,
const Elf_Shdr *DotSymtabShndx)
- : ELFObjectFileBase(
- getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
- Object),
- EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
+ : ELFObjectFileBase(
+ getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
+ Object),
+ EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
DotSymtabShndxSec(DotSymtabShndx) {}
-
-template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
- : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
+
+template <class ELFT>
+ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
+ : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
Other.DotSymtabSec, Other.DotSymtabShndxSec) {}
-
-template <class ELFT>
-basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
- DataRefImpl Sym =
- toDRI(DotSymtabSec,
- DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
- return basic_symbol_iterator(SymbolRef(Sym, this));
-}
-
-template <class ELFT>
-basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
- const Elf_Shdr *SymTab = DotSymtabSec;
- if (!SymTab)
- return symbol_begin();
- DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
- return basic_symbol_iterator(SymbolRef(Sym, this));
-}
-
-template <class ELFT>
-elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
- if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym))
- // Ignore errors here where the dynsym is empty or sh_size less than the
- // size of one symbol. These should be handled elsewhere.
- return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this));
- // Skip 0-index NULL symbol.
- return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this));
-}
-
-template <class ELFT>
-elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
- const Elf_Shdr *SymTab = DotDynSymSec;
- if (!SymTab)
- return dynamic_symbol_begin();
- DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
- return basic_symbol_iterator(SymbolRef(Sym, this));
-}
-
-template <class ELFT>
-section_iterator ELFObjectFile<ELFT>::section_begin() const {
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return section_iterator(SectionRef());
- return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
-}
-
-template <class ELFT>
-section_iterator ELFObjectFile<ELFT>::section_end() const {
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return section_iterator(SectionRef());
- return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
-}
-
-template <class ELFT>
-uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
- return ELFT::Is64Bits ? 8 : 4;
-}
-
-template <class ELFT>
-StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
- bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+
+template <class ELFT>
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
+ DataRefImpl Sym =
+ toDRI(DotSymtabSec,
+ DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0);
+ return basic_symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
+ const Elf_Shdr *SymTab = DotSymtabSec;
+ if (!SymTab)
+ return symbol_begin();
+ DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
+ return basic_symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
+ if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym))
+ // Ignore errors here where the dynsym is empty or sh_size less than the
+ // size of one symbol. These should be handled elsewhere.
+ return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this));
+ // Skip 0-index NULL symbol.
+ return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this));
+}
+
+template <class ELFT>
+elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
+ const Elf_Shdr *SymTab = DotDynSymSec;
+ if (!SymTab)
+ return dynamic_symbol_begin();
+ DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym));
+ return basic_symbol_iterator(SymbolRef(Sym, this));
+}
+
+template <class ELFT>
+section_iterator ELFObjectFile<ELFT>::section_begin() const {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return section_iterator(SectionRef());
+ return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
+}
+
+template <class ELFT>
+section_iterator ELFObjectFile<ELFT>::section_end() const {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return section_iterator(SectionRef());
+ return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
+}
+
+template <class ELFT>
+uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
+ return ELFT::Is64Bits ? 8 : 4;
+}
+
+template <class ELFT>
+StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
- case ELF::ELFCLASS32:
+ case ELF::ELFCLASS32:
switch (EF.getHeader().e_machine) {
- case ELF::EM_386:
- return "elf32-i386";
- case ELF::EM_IAMCU:
- return "elf32-iamcu";
- case ELF::EM_X86_64:
- return "elf32-x86-64";
- case ELF::EM_ARM:
- return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm");
- case ELF::EM_AVR:
- return "elf32-avr";
- case ELF::EM_HEXAGON:
- return "elf32-hexagon";
- case ELF::EM_LANAI:
- return "elf32-lanai";
- case ELF::EM_MIPS:
- return "elf32-mips";
- case ELF::EM_MSP430:
- return "elf32-msp430";
- case ELF::EM_PPC:
+ case ELF::EM_386:
+ return "elf32-i386";
+ case ELF::EM_IAMCU:
+ return "elf32-iamcu";
+ case ELF::EM_X86_64:
+ return "elf32-x86-64";
+ case ELF::EM_ARM:
+ return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm");
+ case ELF::EM_AVR:
+ return "elf32-avr";
+ case ELF::EM_HEXAGON:
+ return "elf32-hexagon";
+ case ELF::EM_LANAI:
+ return "elf32-lanai";
+ case ELF::EM_MIPS:
+ return "elf32-mips";
+ case ELF::EM_MSP430:
+ return "elf32-msp430";
+ case ELF::EM_PPC:
return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
- case ELF::EM_RISCV:
- return "elf32-littleriscv";
+ case ELF::EM_RISCV:
+ return "elf32-littleriscv";
case ELF::EM_CSKY:
return "elf32-csky";
- case ELF::EM_SPARC:
- case ELF::EM_SPARC32PLUS:
- return "elf32-sparc";
- case ELF::EM_AMDGPU:
- return "elf32-amdgpu";
- default:
- return "elf32-unknown";
- }
- case ELF::ELFCLASS64:
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return "elf32-sparc";
+ case ELF::EM_AMDGPU:
+ return "elf32-amdgpu";
+ default:
+ return "elf32-unknown";
+ }
+ case ELF::ELFCLASS64:
switch (EF.getHeader().e_machine) {
- case ELF::EM_386:
- return "elf64-i386";
- case ELF::EM_X86_64:
- return "elf64-x86-64";
- case ELF::EM_AARCH64:
- return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64");
- case ELF::EM_PPC64:
- return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
- case ELF::EM_RISCV:
- return "elf64-littleriscv";
- case ELF::EM_S390:
- return "elf64-s390";
- case ELF::EM_SPARCV9:
- return "elf64-sparc";
- case ELF::EM_MIPS:
- return "elf64-mips";
- case ELF::EM_AMDGPU:
- return "elf64-amdgpu";
- case ELF::EM_BPF:
- return "elf64-bpf";
- case ELF::EM_VE:
- return "elf64-ve";
- default:
- return "elf64-unknown";
- }
- default:
- // FIXME: Proper error handling.
- report_fatal_error("Invalid ELFCLASS!");
- }
-}
-
-template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
- bool IsLittleEndian = ELFT::TargetEndianness == support::little;
+ case ELF::EM_386:
+ return "elf64-i386";
+ case ELF::EM_X86_64:
+ return "elf64-x86-64";
+ case ELF::EM_AARCH64:
+ return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64");
+ case ELF::EM_PPC64:
+ return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
+ case ELF::EM_RISCV:
+ return "elf64-littleriscv";
+ case ELF::EM_S390:
+ return "elf64-s390";
+ case ELF::EM_SPARCV9:
+ return "elf64-sparc";
+ case ELF::EM_MIPS:
+ return "elf64-mips";
+ case ELF::EM_AMDGPU:
+ return "elf64-amdgpu";
+ case ELF::EM_BPF:
+ return "elf64-bpf";
+ case ELF::EM_VE:
+ return "elf64-ve";
+ default:
+ return "elf64-unknown";
+ }
+ default:
+ // FIXME: Proper error handling.
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+}
+
+template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
+ bool IsLittleEndian = ELFT::TargetEndianness == support::little;
switch (EF.getHeader().e_machine) {
- case ELF::EM_386:
- case ELF::EM_IAMCU:
- return Triple::x86;
- case ELF::EM_X86_64:
- return Triple::x86_64;
- case ELF::EM_AARCH64:
- return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
- case ELF::EM_ARM:
- return Triple::arm;
- case ELF::EM_AVR:
- return Triple::avr;
- case ELF::EM_HEXAGON:
- return Triple::hexagon;
- case ELF::EM_LANAI:
- return Triple::lanai;
- case ELF::EM_MIPS:
+ case ELF::EM_386:
+ case ELF::EM_IAMCU:
+ return Triple::x86;
+ case ELF::EM_X86_64:
+ return Triple::x86_64;
+ case ELF::EM_AARCH64:
+ return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be;
+ case ELF::EM_ARM:
+ return Triple::arm;
+ case ELF::EM_AVR:
+ return Triple::avr;
+ case ELF::EM_HEXAGON:
+ return Triple::hexagon;
+ case ELF::EM_LANAI:
+ return Triple::lanai;
+ case ELF::EM_MIPS:
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
- case ELF::ELFCLASS32:
- return IsLittleEndian ? Triple::mipsel : Triple::mips;
- case ELF::ELFCLASS64:
- return IsLittleEndian ? Triple::mips64el : Triple::mips64;
- default:
- report_fatal_error("Invalid ELFCLASS!");
- }
- case ELF::EM_MSP430:
- return Triple::msp430;
- case ELF::EM_PPC:
+ case ELF::ELFCLASS32:
+ return IsLittleEndian ? Triple::mipsel : Triple::mips;
+ case ELF::ELFCLASS64:
+ return IsLittleEndian ? Triple::mips64el : Triple::mips64;
+ default:
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+ case ELF::EM_MSP430:
+ return Triple::msp430;
+ case ELF::EM_PPC:
return IsLittleEndian ? Triple::ppcle : Triple::ppc;
- case ELF::EM_PPC64:
- return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
- case ELF::EM_RISCV:
+ case ELF::EM_PPC64:
+ return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
+ case ELF::EM_RISCV:
switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
- case ELF::ELFCLASS32:
- return Triple::riscv32;
- case ELF::ELFCLASS64:
- return Triple::riscv64;
- default:
- report_fatal_error("Invalid ELFCLASS!");
- }
- case ELF::EM_S390:
- return Triple::systemz;
-
- case ELF::EM_SPARC:
- case ELF::EM_SPARC32PLUS:
- return IsLittleEndian ? Triple::sparcel : Triple::sparc;
- case ELF::EM_SPARCV9:
- return Triple::sparcv9;
-
- case ELF::EM_AMDGPU: {
- if (!IsLittleEndian)
- return Triple::UnknownArch;
-
+ case ELF::ELFCLASS32:
+ return Triple::riscv32;
+ case ELF::ELFCLASS64:
+ return Triple::riscv64;
+ default:
+ report_fatal_error("Invalid ELFCLASS!");
+ }
+ case ELF::EM_S390:
+ return Triple::systemz;
+
+ case ELF::EM_SPARC:
+ case ELF::EM_SPARC32PLUS:
+ return IsLittleEndian ? Triple::sparcel : Triple::sparc;
+ case ELF::EM_SPARCV9:
+ return Triple::sparcv9;
+
+ case ELF::EM_AMDGPU: {
+ if (!IsLittleEndian)
+ return Triple::UnknownArch;
+
unsigned MACH = EF.getHeader().e_flags & ELF::EF_AMDGPU_MACH;
- if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
- MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
- return Triple::r600;
- if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
- MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
- return Triple::amdgcn;
-
- return Triple::UnknownArch;
- }
-
- case ELF::EM_BPF:
- return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
-
- case ELF::EM_VE:
- return Triple::ve;
+ if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
+ MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
+ return Triple::r600;
+ if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST &&
+ MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST)
+ return Triple::amdgcn;
+
+ return Triple::UnknownArch;
+ }
+
+ case ELF::EM_BPF:
+ return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
+
+ case ELF::EM_VE:
+ return Triple::ve;
case ELF::EM_CSKY:
return Triple::csky;
- default:
- return Triple::UnknownArch;
- }
-}
-
-template <class ELFT>
-Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
+ default:
+ return Triple::UnknownArch;
+ }
+}
+
+template <class ELFT>
+Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
return EF.getHeader().e_entry;
-}
-
-template <class ELFT>
-ELFObjectFileBase::elf_symbol_iterator_range
-ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
- return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
-}
-
-template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
+}
+
+template <class ELFT>
+ELFObjectFileBase::elf_symbol_iterator_range
+ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
+ return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
+}
+
+template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
return EF.getHeader().e_type == ELF::ET_REL;
-}
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_ELFOBJECTFILE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_ELFOBJECTFILE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h b/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h
index 320dfaa573e..501ba000cfb 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ELFTypes.h
@@ -1,119 +1,119 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ELFTypes.h - Endian specific types for ELF ---------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_ELFTYPES_H
-#define LLVM_OBJECT_ELFTYPES_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-#include <type_traits>
-
-namespace llvm {
-namespace object {
-
-using support::endianness;
-
-template <class ELFT> struct Elf_Ehdr_Impl;
-template <class ELFT> struct Elf_Shdr_Impl;
-template <class ELFT> struct Elf_Sym_Impl;
-template <class ELFT> struct Elf_Dyn_Impl;
-template <class ELFT> struct Elf_Phdr_Impl;
-template <class ELFT, bool isRela> struct Elf_Rel_Impl;
-template <class ELFT> struct Elf_Verdef_Impl;
-template <class ELFT> struct Elf_Verdaux_Impl;
-template <class ELFT> struct Elf_Verneed_Impl;
-template <class ELFT> struct Elf_Vernaux_Impl;
-template <class ELFT> struct Elf_Versym_Impl;
-template <class ELFT> struct Elf_Hash_Impl;
-template <class ELFT> struct Elf_GnuHash_Impl;
-template <class ELFT> struct Elf_Chdr_Impl;
-template <class ELFT> struct Elf_Nhdr_Impl;
-template <class ELFT> class Elf_Note_Impl;
-template <class ELFT> class Elf_Note_Iterator_Impl;
-template <class ELFT> struct Elf_CGProfile_Impl;
-
-template <endianness E, bool Is64> struct ELFType {
-private:
- template <typename Ty>
- using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
-
-public:
- static const endianness TargetEndianness = E;
- static const bool Is64Bits = Is64;
-
- using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
- using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
- using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
- using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
- using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
- using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
- using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
- using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
- using Relr = packed<uint>;
- using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
- using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
- using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
- using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
- using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
- using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
- using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
- using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
- using Nhdr = Elf_Nhdr_Impl<ELFType<E, Is64>>;
- using Note = Elf_Note_Impl<ELFType<E, Is64>>;
- using NoteIterator = Elf_Note_Iterator_Impl<ELFType<E, Is64>>;
- using CGProfile = Elf_CGProfile_Impl<ELFType<E, Is64>>;
- using DynRange = ArrayRef<Dyn>;
- using ShdrRange = ArrayRef<Shdr>;
- using SymRange = ArrayRef<Sym>;
- using RelRange = ArrayRef<Rel>;
- using RelaRange = ArrayRef<Rela>;
- using RelrRange = ArrayRef<Relr>;
- using PhdrRange = ArrayRef<Phdr>;
-
- using Half = packed<uint16_t>;
- using Word = packed<uint32_t>;
- using Sword = packed<int32_t>;
- using Xword = packed<uint64_t>;
- using Sxword = packed<int64_t>;
- using Addr = packed<uint>;
- using Off = packed<uint>;
-};
-
-using ELF32LE = ELFType<support::little, false>;
-using ELF32BE = ELFType<support::big, false>;
-using ELF64LE = ELFType<support::little, true>;
-using ELF64BE = ELFType<support::big, true>;
-
-// Use an alignment of 2 for the typedefs since that is the worst case for
-// ELF files in archives.
-
-// I really don't like doing this, but the alternative is copypasta.
-#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
- using Elf_Addr = typename ELFT::Addr; \
- using Elf_Off = typename ELFT::Off; \
- using Elf_Half = typename ELFT::Half; \
- using Elf_Word = typename ELFT::Word; \
- using Elf_Sword = typename ELFT::Sword; \
- using Elf_Xword = typename ELFT::Xword; \
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ELFTypes.h - Endian specific types for ELF ---------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ELFTYPES_H
+#define LLVM_OBJECT_ELFTYPES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <type_traits>
+
+namespace llvm {
+namespace object {
+
+using support::endianness;
+
+template <class ELFT> struct Elf_Ehdr_Impl;
+template <class ELFT> struct Elf_Shdr_Impl;
+template <class ELFT> struct Elf_Sym_Impl;
+template <class ELFT> struct Elf_Dyn_Impl;
+template <class ELFT> struct Elf_Phdr_Impl;
+template <class ELFT, bool isRela> struct Elf_Rel_Impl;
+template <class ELFT> struct Elf_Verdef_Impl;
+template <class ELFT> struct Elf_Verdaux_Impl;
+template <class ELFT> struct Elf_Verneed_Impl;
+template <class ELFT> struct Elf_Vernaux_Impl;
+template <class ELFT> struct Elf_Versym_Impl;
+template <class ELFT> struct Elf_Hash_Impl;
+template <class ELFT> struct Elf_GnuHash_Impl;
+template <class ELFT> struct Elf_Chdr_Impl;
+template <class ELFT> struct Elf_Nhdr_Impl;
+template <class ELFT> class Elf_Note_Impl;
+template <class ELFT> class Elf_Note_Iterator_Impl;
+template <class ELFT> struct Elf_CGProfile_Impl;
+
+template <endianness E, bool Is64> struct ELFType {
+private:
+ template <typename Ty>
+ using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
+
+public:
+ static const endianness TargetEndianness = E;
+ static const bool Is64Bits = Is64;
+
+ using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
+ using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
+ using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
+ using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
+ using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
+ using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
+ using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
+ using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
+ using Relr = packed<uint>;
+ using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
+ using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
+ using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
+ using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
+ using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
+ using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
+ using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
+ using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
+ using Nhdr = Elf_Nhdr_Impl<ELFType<E, Is64>>;
+ using Note = Elf_Note_Impl<ELFType<E, Is64>>;
+ using NoteIterator = Elf_Note_Iterator_Impl<ELFType<E, Is64>>;
+ using CGProfile = Elf_CGProfile_Impl<ELFType<E, Is64>>;
+ using DynRange = ArrayRef<Dyn>;
+ using ShdrRange = ArrayRef<Shdr>;
+ using SymRange = ArrayRef<Sym>;
+ using RelRange = ArrayRef<Rel>;
+ using RelaRange = ArrayRef<Rela>;
+ using RelrRange = ArrayRef<Relr>;
+ using PhdrRange = ArrayRef<Phdr>;
+
+ using Half = packed<uint16_t>;
+ using Word = packed<uint32_t>;
+ using Sword = packed<int32_t>;
+ using Xword = packed<uint64_t>;
+ using Sxword = packed<int64_t>;
+ using Addr = packed<uint>;
+ using Off = packed<uint>;
+};
+
+using ELF32LE = ELFType<support::little, false>;
+using ELF32BE = ELFType<support::big, false>;
+using ELF64LE = ELFType<support::little, true>;
+using ELF64BE = ELFType<support::big, true>;
+
+// Use an alignment of 2 for the typedefs since that is the worst case for
+// ELF files in archives.
+
+// I really don't like doing this, but the alternative is copypasta.
+#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
+ using Elf_Addr = typename ELFT::Addr; \
+ using Elf_Off = typename ELFT::Off; \
+ using Elf_Half = typename ELFT::Half; \
+ using Elf_Word = typename ELFT::Word; \
+ using Elf_Sword = typename ELFT::Sword; \
+ using Elf_Xword = typename ELFT::Xword; \
using Elf_Sxword = typename ELFT::Sxword; \
using uintX_t = typename ELFT::uint; \
using Elf_Ehdr = typename ELFT::Ehdr; \
@@ -142,664 +142,664 @@ using ELF64BE = ELFType<support::big, true>;
using Elf_Rela_Range = typename ELFT::RelaRange; \
using Elf_Relr_Range = typename ELFT::RelrRange; \
using Elf_Phdr_Range = typename ELFT::PhdrRange; \
-
-#define LLVM_ELF_COMMA ,
-#define LLVM_ELF_IMPORT_TYPES(E, W) \
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
-
-// Section header.
-template <class ELFT> struct Elf_Shdr_Base;
-
-template <endianness TargetEndianness>
-struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Word sh_name; // Section name (index into string table)
- Elf_Word sh_type; // Section type (SHT_*)
- Elf_Word sh_flags; // Section flags (SHF_*)
- Elf_Addr sh_addr; // Address where section is to be loaded
- Elf_Off sh_offset; // File offset of section data, in bytes
- Elf_Word sh_size; // Size of section, in bytes
- Elf_Word sh_link; // Section type-specific header table index link
- Elf_Word sh_info; // Section type-specific extra information
- Elf_Word sh_addralign; // Section address alignment
- Elf_Word sh_entsize; // Size of records contained within the section
-};
-
-template <endianness TargetEndianness>
-struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Word sh_name; // Section name (index into string table)
- Elf_Word sh_type; // Section type (SHT_*)
- Elf_Xword sh_flags; // Section flags (SHF_*)
- Elf_Addr sh_addr; // Address where section is to be loaded
- Elf_Off sh_offset; // File offset of section data, in bytes
- Elf_Xword sh_size; // Size of section, in bytes
- Elf_Word sh_link; // Section type-specific header table index link
- Elf_Word sh_info; // Section type-specific extra information
- Elf_Xword sh_addralign; // Section address alignment
- Elf_Xword sh_entsize; // Size of records contained within the section
-};
-
-template <class ELFT>
-struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
- using Elf_Shdr_Base<ELFT>::sh_entsize;
- using Elf_Shdr_Base<ELFT>::sh_size;
-
- /// Get the number of entities this section contains if it has any.
- unsigned getEntityCount() const {
- if (sh_entsize == 0)
- return 0;
- return sh_size / sh_entsize;
- }
-};
-
-template <class ELFT> struct Elf_Sym_Base;
-
-template <endianness TargetEndianness>
-struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Word st_name; // Symbol name (index into string table)
- Elf_Addr st_value; // Value or address associated with the symbol
- Elf_Word st_size; // Size of the symbol
- unsigned char st_info; // Symbol's type and binding attributes
- unsigned char st_other; // Must be zero; reserved
- Elf_Half st_shndx; // Which section (header table index) it's defined in
-};
-
-template <endianness TargetEndianness>
-struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Word st_name; // Symbol name (index into string table)
- unsigned char st_info; // Symbol's type and binding attributes
- unsigned char st_other; // Must be zero; reserved
- Elf_Half st_shndx; // Which section (header table index) it's defined in
- Elf_Addr st_value; // Value or address associated with the symbol
- Elf_Xword st_size; // Size of the symbol
-};
-
-template <class ELFT>
-struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
- using Elf_Sym_Base<ELFT>::st_info;
- using Elf_Sym_Base<ELFT>::st_shndx;
- using Elf_Sym_Base<ELFT>::st_other;
- using Elf_Sym_Base<ELFT>::st_value;
-
- // These accessors and mutators correspond to the ELF32_ST_BIND,
- // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
- unsigned char getBinding() const { return st_info >> 4; }
- unsigned char getType() const { return st_info & 0x0f; }
- uint64_t getValue() const { return st_value; }
- void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
- void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
-
- void setBindingAndType(unsigned char b, unsigned char t) {
- st_info = (b << 4) + (t & 0x0f);
- }
-
- /// Access to the STV_xxx flag stored in the first two bits of st_other.
- /// STV_DEFAULT: 0
- /// STV_INTERNAL: 1
- /// STV_HIDDEN: 2
- /// STV_PROTECTED: 3
- unsigned char getVisibility() const { return st_other & 0x3; }
- void setVisibility(unsigned char v) {
- assert(v < 4 && "Invalid value for visibility");
- st_other = (st_other & ~0x3) | v;
- }
-
- bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
-
- bool isCommon() const {
- return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
- }
-
- bool isDefined() const { return !isUndefined(); }
-
- bool isProcessorSpecific() const {
- return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
- }
-
- bool isOSSpecific() const {
- return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
- }
-
- bool isReserved() const {
- // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
- // true and some compilers warn about it.
- return st_shndx >= ELF::SHN_LORESERVE;
- }
-
- bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
-
- bool isExternal() const {
- return getBinding() != ELF::STB_LOCAL;
- }
-
- Expected<StringRef> getName(StringRef StrTab) const;
-};
-
-template <class ELFT>
-Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
- uint32_t Offset = this->st_name;
- if (Offset >= StrTab.size())
- return createStringError(object_error::parse_failed,
- "st_name (0x%" PRIx32
- ") is past the end of the string table"
- " of size 0x%zx",
- Offset, StrTab.size());
- return StringRef(StrTab.data() + Offset);
-}
-
-/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
-/// (.gnu.version). This structure is identical for ELF32 and ELF64.
-template <class ELFT>
-struct Elf_Versym_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
-};
-
-/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
-/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template <class ELFT>
-struct Elf_Verdef_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
- Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
- Elf_Half vd_ndx; // Version index, used in .gnu.version entries
- Elf_Half vd_cnt; // Number of Verdaux entries
- Elf_Word vd_hash; // Hash of name
- Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes)
- Elf_Word vd_next; // Offset to the next Verdef entry (in bytes)
-
- /// Get the first Verdaux entry for this Verdef.
- const Elf_Verdaux *getAux() const {
- return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
- }
-};
-
-/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
-/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template <class ELFT>
-struct Elf_Verdaux_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Word vda_name; // Version name (offset in string table)
- Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
-};
-
-/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
-/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template <class ELFT>
-struct Elf_Verneed_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
- Elf_Half vn_cnt; // Number of associated Vernaux entries
- Elf_Word vn_file; // Library name (string table offset)
- Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes)
- Elf_Word vn_next; // Offset to next Verneed entry (in bytes)
-};
-
-/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
-/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template <class ELFT>
-struct Elf_Vernaux_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Word vna_hash; // Hash of dependency name
- Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
- Elf_Half vna_other; // Version index, used in .gnu.version entries
- Elf_Word vna_name; // Dependency name
- Elf_Word vna_next; // Offset to next Vernaux entry (in bytes)
-};
-
-/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
-/// table section (.dynamic) look like.
-template <class ELFT> struct Elf_Dyn_Base;
-
-template <endianness TargetEndianness>
-struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Sword d_tag;
- union {
- Elf_Word d_val;
- Elf_Addr d_ptr;
- } d_un;
-};
-
-template <endianness TargetEndianness>
-struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Sxword d_tag;
- union {
- Elf_Xword d_val;
- Elf_Addr d_ptr;
- } d_un;
-};
-
-/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
-template <class ELFT>
-struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
- using Elf_Dyn_Base<ELFT>::d_tag;
- using Elf_Dyn_Base<ELFT>::d_un;
- using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
- using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
- intX_t getTag() const { return d_tag; }
- uintX_t getVal() const { return d_un.d_val; }
- uintX_t getPtr() const { return d_un.d_ptr; }
-};
-
-template <endianness TargetEndianness>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- static const bool IsRela = false;
- Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
- Elf_Word r_info; // Symbol table index and type of relocation to apply
-
- uint32_t getRInfo(bool isMips64EL) const {
- assert(!isMips64EL);
- return r_info;
- }
- void setRInfo(uint32_t R, bool IsMips64EL) {
- assert(!IsMips64EL);
- r_info = R;
- }
-
- // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
- // and ELF32_R_INFO macros defined in the ELF specification:
- uint32_t getSymbol(bool isMips64EL) const {
- return this->getRInfo(isMips64EL) >> 8;
- }
- unsigned char getType(bool isMips64EL) const {
- return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
- }
- void setSymbol(uint32_t s, bool IsMips64EL) {
- setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
- }
- void setType(unsigned char t, bool IsMips64EL) {
- setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
- }
- void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
- this->setRInfo((s << 8) + t, IsMips64EL);
- }
-};
-
-template <endianness TargetEndianness>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
- : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- static const bool IsRela = true;
- Elf_Sword r_addend; // Compute value for relocatable field by adding this
-};
-
-template <endianness TargetEndianness>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- static const bool IsRela = false;
- Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
- Elf_Xword r_info; // Symbol table index and type of relocation to apply
-
- uint64_t getRInfo(bool isMips64EL) const {
- uint64_t t = r_info;
- if (!isMips64EL)
- return t;
- // Mips64 little endian has a "special" encoding of r_info. Instead of one
- // 64 bit little endian number, it is a little endian 32 bit number followed
- // by a 32 bit big endian number.
- return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
- ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
- }
-
- void setRInfo(uint64_t R, bool IsMips64EL) {
- if (IsMips64EL)
- r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
- ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
- else
- r_info = R;
- }
-
- // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
- // and ELF64_R_INFO macros defined in the ELF specification:
- uint32_t getSymbol(bool isMips64EL) const {
- return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
- }
- uint32_t getType(bool isMips64EL) const {
- return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
- }
- void setSymbol(uint32_t s, bool IsMips64EL) {
- setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
- }
- void setType(uint32_t t, bool IsMips64EL) {
- setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
- }
- void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
- this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
- }
-};
-
-template <endianness TargetEndianness>
-struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
- : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- static const bool IsRela = true;
- Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
-};
-
-template <class ELFT>
-struct Elf_Ehdr_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
- Elf_Half e_type; // Type of file (see ET_*)
- Elf_Half e_machine; // Required architecture for this file (see EM_*)
- Elf_Word e_version; // Must be equal to 1
- Elf_Addr e_entry; // Address to jump to in order to start program
- Elf_Off e_phoff; // Program header table's file offset, in bytes
- Elf_Off e_shoff; // Section header table's file offset, in bytes
- Elf_Word e_flags; // Processor-specific flags
- Elf_Half e_ehsize; // Size of ELF header, in bytes
- Elf_Half e_phentsize; // Size of an entry in the program header table
- Elf_Half e_phnum; // Number of entries in the program header table
- Elf_Half e_shentsize; // Size of an entry in the section header table
- Elf_Half e_shnum; // Number of entries in the section header table
- Elf_Half e_shstrndx; // Section header table index of section name
- // string table
-
- bool checkMagic() const {
- return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
- }
-
- unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
- unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
-};
-
-template <endianness TargetEndianness>
-struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Word p_type; // Type of segment
- Elf_Off p_offset; // FileOffset where segment is located, in bytes
- Elf_Addr p_vaddr; // Virtual Address of beginning of segment
- Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
- Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
- Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
- Elf_Word p_flags; // Segment flags
- Elf_Word p_align; // Segment alignment constraint
-};
-
-template <endianness TargetEndianness>
-struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Word p_type; // Type of segment
- Elf_Word p_flags; // Segment flags
- Elf_Off p_offset; // FileOffset where segment is located, in bytes
- Elf_Addr p_vaddr; // Virtual Address of beginning of segment
- Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
- Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
- Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
- Elf_Xword p_align; // Segment alignment constraint
-};
-
-// ELFT needed for endianness.
-template <class ELFT>
-struct Elf_Hash_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Word nbucket;
- Elf_Word nchain;
-
- ArrayRef<Elf_Word> buckets() const {
- return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
- }
-
- ArrayRef<Elf_Word> chains() const {
- return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
- &nbucket + 2 + nbucket + nchain);
- }
-};
-
-// .gnu.hash section
-template <class ELFT>
-struct Elf_GnuHash_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Word nbuckets;
- Elf_Word symndx;
- Elf_Word maskwords;
- Elf_Word shift2;
-
- ArrayRef<Elf_Off> filter() const {
- return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
- maskwords);
- }
-
- ArrayRef<Elf_Word> buckets() const {
- return ArrayRef<Elf_Word>(
- reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
- }
-
- ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
- assert(DynamicSymCount >= symndx);
- return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
- }
-};
-
-// Compressed section headers.
-// http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
-template <endianness TargetEndianness>
-struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Word ch_type;
- Elf_Word ch_size;
- Elf_Word ch_addralign;
-};
-
-template <endianness TargetEndianness>
-struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Word ch_type;
- Elf_Word ch_reserved;
- Elf_Xword ch_size;
- Elf_Xword ch_addralign;
-};
-
-/// Note header
-template <class ELFT>
-struct Elf_Nhdr_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Word n_namesz;
- Elf_Word n_descsz;
- Elf_Word n_type;
-
- /// The alignment of the name and descriptor.
- ///
- /// Implementations differ from the specification here: in practice all
- /// variants align both the name and descriptor to 4-bytes.
- static const unsigned int Align = 4;
-
- /// Get the size of the note, including name, descriptor, and padding.
- size_t getSize() const {
- return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
- }
-};
-
-/// An ELF note.
-///
-/// Wraps a note header, providing methods for accessing the name and
-/// descriptor safely.
-template <class ELFT>
-class Elf_Note_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
-
- const Elf_Nhdr_Impl<ELFT> &Nhdr;
-
- template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
-
-public:
- Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
-
- /// Get the note's name, excluding the terminating null byte.
- StringRef getName() const {
- if (!Nhdr.n_namesz)
- return StringRef();
- return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
- Nhdr.n_namesz - 1);
- }
-
- /// Get the note's descriptor.
- ArrayRef<uint8_t> getDesc() const {
- if (!Nhdr.n_descsz)
- return ArrayRef<uint8_t>();
- return ArrayRef<uint8_t>(
- reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
- alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz),
- Nhdr.n_descsz);
- }
-
- /// Get the note's descriptor as StringRef
- StringRef getDescAsStringRef() const {
- ArrayRef<uint8_t> Desc = getDesc();
- return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
- }
-
- /// Get the note's type.
- Elf_Word getType() const { return Nhdr.n_type; }
-};
-
-template <class ELFT>
-class Elf_Note_Iterator_Impl
- : std::iterator<std::forward_iterator_tag, Elf_Note_Impl<ELFT>> {
- // Nhdr being a nullptr marks the end of iteration.
- const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
- size_t RemainingSize = 0u;
- Error *Err = nullptr;
-
- template <class ELFFileELFT> friend class ELFFile;
-
- // Stop iteration and indicate an overflow.
- void stopWithOverflowError() {
- Nhdr = nullptr;
- *Err = make_error<StringError>("ELF note overflows container",
- object_error::parse_failed);
- }
-
- // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
- //
- // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
- // upon returning. Handles stopping iteration when reaching the end of the
- // container, either cleanly or with an overflow error.
- void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
- RemainingSize -= NoteSize;
- if (RemainingSize == 0u) {
- // Ensure that if the iterator walks to the end, the error is checked
- // afterwards.
- *Err = Error::success();
- Nhdr = nullptr;
- } else if (sizeof(*Nhdr) > RemainingSize)
- stopWithOverflowError();
- else {
- Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
- if (Nhdr->getSize() > RemainingSize)
- stopWithOverflowError();
- else
- *Err = Error::success();
- }
- }
-
- Elf_Note_Iterator_Impl() {}
- explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
- Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, Error &Err)
- : RemainingSize(Size), Err(&Err) {
- consumeError(std::move(Err));
- assert(Start && "ELF note iterator starting at NULL");
- advanceNhdr(Start, 0u);
- }
-
-public:
- Elf_Note_Iterator_Impl &operator++() {
- assert(Nhdr && "incremented ELF note end iterator");
- const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
- size_t NoteSize = Nhdr->getSize();
- advanceNhdr(NhdrPos, NoteSize);
- return *this;
- }
- bool operator==(Elf_Note_Iterator_Impl Other) const {
- if (!Nhdr && Other.Err)
- (void)(bool)(*Other.Err);
- if (!Other.Nhdr && Err)
- (void)(bool)(*Err);
- return Nhdr == Other.Nhdr;
- }
- bool operator!=(Elf_Note_Iterator_Impl Other) const {
- return !(*this == Other);
- }
- Elf_Note_Impl<ELFT> operator*() const {
- assert(Nhdr && "dereferenced ELF note end iterator");
- return Elf_Note_Impl<ELFT>(*Nhdr);
- }
-};
-
-template <class ELFT> struct Elf_CGProfile_Impl {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Word cgp_from;
- Elf_Word cgp_to;
- Elf_Xword cgp_weight;
-};
-
-// MIPS .reginfo section
-template <class ELFT>
-struct Elf_Mips_RegInfo;
-
-template <support::endianness TargetEndianness>
-struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
- Elf_Word ri_gprmask; // bit-mask of used general registers
- Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
- Elf_Addr ri_gp_value; // gp register value
-};
-
-template <support::endianness TargetEndianness>
-struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
- LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
- Elf_Word ri_gprmask; // bit-mask of used general registers
- Elf_Word ri_pad; // unused padding field
- Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
- Elf_Addr ri_gp_value; // gp register value
-};
-
-// .MIPS.options section
-template <class ELFT> struct Elf_Mips_Options {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- uint8_t kind; // Determines interpretation of variable part of descriptor
- uint8_t size; // Byte size of descriptor, including this header
- Elf_Half section; // Section header index of section affected,
- // or 0 for global options
- Elf_Word info; // Kind-specific information
-
- Elf_Mips_RegInfo<ELFT> &getRegInfo() {
- assert(kind == ELF::ODK_REGINFO);
- return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
- (uint8_t *)this + sizeof(Elf_Mips_Options));
- }
- const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
- return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
- }
-};
-
-// .MIPS.abiflags section content
-template <class ELFT> struct Elf_Mips_ABIFlags {
- LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- Elf_Half version; // Version of the structure
- uint8_t isa_level; // ISA level: 1-5, 32, and 64
- uint8_t isa_rev; // ISA revision (0 for MIPS I - MIPS V)
- uint8_t gpr_size; // General purpose registers size
- uint8_t cpr1_size; // Co-processor 1 registers size
- uint8_t cpr2_size; // Co-processor 2 registers size
- uint8_t fp_abi; // Floating-point ABI flag
- Elf_Word isa_ext; // Processor-specific extension
- Elf_Word ases; // ASEs flags
- Elf_Word flags1; // General flags
- Elf_Word flags2; // General flags
-};
-
-} // end namespace object.
-} // end namespace llvm.
-
-#endif // LLVM_OBJECT_ELFTYPES_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+
+#define LLVM_ELF_COMMA ,
+#define LLVM_ELF_IMPORT_TYPES(E, W) \
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
+
+// Section header.
+template <class ELFT> struct Elf_Shdr_Base;
+
+template <endianness TargetEndianness>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word sh_name; // Section name (index into string table)
+ Elf_Word sh_type; // Section type (SHT_*)
+ Elf_Word sh_flags; // Section flags (SHF_*)
+ Elf_Addr sh_addr; // Address where section is to be loaded
+ Elf_Off sh_offset; // File offset of section data, in bytes
+ Elf_Word sh_size; // Size of section, in bytes
+ Elf_Word sh_link; // Section type-specific header table index link
+ Elf_Word sh_info; // Section type-specific extra information
+ Elf_Word sh_addralign; // Section address alignment
+ Elf_Word sh_entsize; // Size of records contained within the section
+};
+
+template <endianness TargetEndianness>
+struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word sh_name; // Section name (index into string table)
+ Elf_Word sh_type; // Section type (SHT_*)
+ Elf_Xword sh_flags; // Section flags (SHF_*)
+ Elf_Addr sh_addr; // Address where section is to be loaded
+ Elf_Off sh_offset; // File offset of section data, in bytes
+ Elf_Xword sh_size; // Size of section, in bytes
+ Elf_Word sh_link; // Section type-specific header table index link
+ Elf_Word sh_info; // Section type-specific extra information
+ Elf_Xword sh_addralign; // Section address alignment
+ Elf_Xword sh_entsize; // Size of records contained within the section
+};
+
+template <class ELFT>
+struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
+ using Elf_Shdr_Base<ELFT>::sh_entsize;
+ using Elf_Shdr_Base<ELFT>::sh_size;
+
+ /// Get the number of entities this section contains if it has any.
+ unsigned getEntityCount() const {
+ if (sh_entsize == 0)
+ return 0;
+ return sh_size / sh_entsize;
+ }
+};
+
+template <class ELFT> struct Elf_Sym_Base;
+
+template <endianness TargetEndianness>
+struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word st_name; // Symbol name (index into string table)
+ Elf_Addr st_value; // Value or address associated with the symbol
+ Elf_Word st_size; // Size of the symbol
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf_Half st_shndx; // Which section (header table index) it's defined in
+};
+
+template <endianness TargetEndianness>
+struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word st_name; // Symbol name (index into string table)
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf_Half st_shndx; // Which section (header table index) it's defined in
+ Elf_Addr st_value; // Value or address associated with the symbol
+ Elf_Xword st_size; // Size of the symbol
+};
+
+template <class ELFT>
+struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
+ using Elf_Sym_Base<ELFT>::st_info;
+ using Elf_Sym_Base<ELFT>::st_shndx;
+ using Elf_Sym_Base<ELFT>::st_other;
+ using Elf_Sym_Base<ELFT>::st_value;
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding() const { return st_info >> 4; }
+ unsigned char getType() const { return st_info & 0x0f; }
+ uint64_t getValue() const { return st_value; }
+ void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
+ void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
+
+ void setBindingAndType(unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+
+ /// Access to the STV_xxx flag stored in the first two bits of st_other.
+ /// STV_DEFAULT: 0
+ /// STV_INTERNAL: 1
+ /// STV_HIDDEN: 2
+ /// STV_PROTECTED: 3
+ unsigned char getVisibility() const { return st_other & 0x3; }
+ void setVisibility(unsigned char v) {
+ assert(v < 4 && "Invalid value for visibility");
+ st_other = (st_other & ~0x3) | v;
+ }
+
+ bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
+
+ bool isCommon() const {
+ return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
+ }
+
+ bool isDefined() const { return !isUndefined(); }
+
+ bool isProcessorSpecific() const {
+ return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
+ }
+
+ bool isOSSpecific() const {
+ return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
+ }
+
+ bool isReserved() const {
+ // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
+ // true and some compilers warn about it.
+ return st_shndx >= ELF::SHN_LORESERVE;
+ }
+
+ bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
+
+ bool isExternal() const {
+ return getBinding() != ELF::STB_LOCAL;
+ }
+
+ Expected<StringRef> getName(StringRef StrTab) const;
+};
+
+template <class ELFT>
+Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
+ uint32_t Offset = this->st_name;
+ if (Offset >= StrTab.size())
+ return createStringError(object_error::parse_failed,
+ "st_name (0x%" PRIx32
+ ") is past the end of the string table"
+ " of size 0x%zx",
+ Offset, StrTab.size());
+ return StringRef(StrTab.data() + Offset);
+}
+
+/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
+/// (.gnu.version). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Versym_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
+};
+
+/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
+/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verdef_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
+ Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
+ Elf_Half vd_ndx; // Version index, used in .gnu.version entries
+ Elf_Half vd_cnt; // Number of Verdaux entries
+ Elf_Word vd_hash; // Hash of name
+ Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes)
+ Elf_Word vd_next; // Offset to the next Verdef entry (in bytes)
+
+ /// Get the first Verdaux entry for this Verdef.
+ const Elf_Verdaux *getAux() const {
+ return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
+ }
+};
+
+/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
+/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verdaux_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word vda_name; // Version name (offset in string table)
+ Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
+};
+
+/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
+/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Verneed_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
+ Elf_Half vn_cnt; // Number of associated Vernaux entries
+ Elf_Word vn_file; // Library name (string table offset)
+ Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes)
+ Elf_Word vn_next; // Offset to next Verneed entry (in bytes)
+};
+
+/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
+/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
+template <class ELFT>
+struct Elf_Vernaux_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word vna_hash; // Hash of dependency name
+ Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
+ Elf_Half vna_other; // Version index, used in .gnu.version entries
+ Elf_Word vna_name; // Dependency name
+ Elf_Word vna_next; // Offset to next Vernaux entry (in bytes)
+};
+
+/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
+/// table section (.dynamic) look like.
+template <class ELFT> struct Elf_Dyn_Base;
+
+template <endianness TargetEndianness>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Sword d_tag;
+ union {
+ Elf_Word d_val;
+ Elf_Addr d_ptr;
+ } d_un;
+};
+
+template <endianness TargetEndianness>
+struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Sxword d_tag;
+ union {
+ Elf_Xword d_val;
+ Elf_Addr d_ptr;
+ } d_un;
+};
+
+/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
+template <class ELFT>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
+ using Elf_Dyn_Base<ELFT>::d_tag;
+ using Elf_Dyn_Base<ELFT>::d_un;
+ using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
+ using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
+ intX_t getTag() const { return d_tag; }
+ uintX_t getVal() const { return d_un.d_val; }
+ uintX_t getPtr() const { return d_un.d_ptr; }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ static const bool IsRela = false;
+ Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf_Word r_info; // Symbol table index and type of relocation to apply
+
+ uint32_t getRInfo(bool isMips64EL) const {
+ assert(!isMips64EL);
+ return r_info;
+ }
+ void setRInfo(uint32_t R, bool IsMips64EL) {
+ assert(!IsMips64EL);
+ r_info = R;
+ }
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ uint32_t getSymbol(bool isMips64EL) const {
+ return this->getRInfo(isMips64EL) >> 8;
+ }
+ unsigned char getType(bool isMips64EL) const {
+ return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
+ }
+ void setSymbol(uint32_t s, bool IsMips64EL) {
+ setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
+ }
+ void setType(unsigned char t, bool IsMips64EL) {
+ setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
+ }
+ void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
+ this->setRInfo((s << 8) + t, IsMips64EL);
+ }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
+ : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ static const bool IsRela = true;
+ Elf_Sword r_addend; // Compute value for relocatable field by adding this
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ static const bool IsRela = false;
+ Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf_Xword r_info; // Symbol table index and type of relocation to apply
+
+ uint64_t getRInfo(bool isMips64EL) const {
+ uint64_t t = r_info;
+ if (!isMips64EL)
+ return t;
+ // Mips64 little endian has a "special" encoding of r_info. Instead of one
+ // 64 bit little endian number, it is a little endian 32 bit number followed
+ // by a 32 bit big endian number.
+ return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
+ ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
+ }
+
+ void setRInfo(uint64_t R, bool IsMips64EL) {
+ if (IsMips64EL)
+ r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
+ ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
+ else
+ r_info = R;
+ }
+
+ // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
+ // and ELF64_R_INFO macros defined in the ELF specification:
+ uint32_t getSymbol(bool isMips64EL) const {
+ return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
+ }
+ uint32_t getType(bool isMips64EL) const {
+ return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
+ }
+ void setSymbol(uint32_t s, bool IsMips64EL) {
+ setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
+ }
+ void setType(uint32_t t, bool IsMips64EL) {
+ setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
+ }
+ void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
+ this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
+ }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
+ : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ static const bool IsRela = true;
+ Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
+};
+
+template <class ELFT>
+struct Elf_Ehdr_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
+ Elf_Half e_type; // Type of file (see ET_*)
+ Elf_Half e_machine; // Required architecture for this file (see EM_*)
+ Elf_Word e_version; // Must be equal to 1
+ Elf_Addr e_entry; // Address to jump to in order to start program
+ Elf_Off e_phoff; // Program header table's file offset, in bytes
+ Elf_Off e_shoff; // Section header table's file offset, in bytes
+ Elf_Word e_flags; // Processor-specific flags
+ Elf_Half e_ehsize; // Size of ELF header, in bytes
+ Elf_Half e_phentsize; // Size of an entry in the program header table
+ Elf_Half e_phnum; // Number of entries in the program header table
+ Elf_Half e_shentsize; // Size of an entry in the section header table
+ Elf_Half e_shnum; // Number of entries in the section header table
+ Elf_Half e_shstrndx; // Section header table index of section name
+ // string table
+
+ bool checkMagic() const {
+ return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
+ }
+
+ unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
+ unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
+};
+
+template <endianness TargetEndianness>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word p_type; // Type of segment
+ Elf_Off p_offset; // FileOffset where segment is located, in bytes
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Word p_flags; // Segment flags
+ Elf_Word p_align; // Segment alignment constraint
+};
+
+template <endianness TargetEndianness>
+struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word p_type; // Type of segment
+ Elf_Word p_flags; // Segment flags
+ Elf_Off p_offset; // FileOffset where segment is located, in bytes
+ Elf_Addr p_vaddr; // Virtual Address of beginning of segment
+ Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf_Xword p_align; // Segment alignment constraint
+};
+
+// ELFT needed for endianness.
+template <class ELFT>
+struct Elf_Hash_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word nbucket;
+ Elf_Word nchain;
+
+ ArrayRef<Elf_Word> buckets() const {
+ return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
+ }
+
+ ArrayRef<Elf_Word> chains() const {
+ return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
+ &nbucket + 2 + nbucket + nchain);
+ }
+};
+
+// .gnu.hash section
+template <class ELFT>
+struct Elf_GnuHash_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word nbuckets;
+ Elf_Word symndx;
+ Elf_Word maskwords;
+ Elf_Word shift2;
+
+ ArrayRef<Elf_Off> filter() const {
+ return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
+ maskwords);
+ }
+
+ ArrayRef<Elf_Word> buckets() const {
+ return ArrayRef<Elf_Word>(
+ reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
+ }
+
+ ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
+ assert(DynamicSymCount >= symndx);
+ return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
+ }
+};
+
+// Compressed section headers.
+// http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
+template <endianness TargetEndianness>
+struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word ch_type;
+ Elf_Word ch_size;
+ Elf_Word ch_addralign;
+};
+
+template <endianness TargetEndianness>
+struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word ch_type;
+ Elf_Word ch_reserved;
+ Elf_Xword ch_size;
+ Elf_Xword ch_addralign;
+};
+
+/// Note header
+template <class ELFT>
+struct Elf_Nhdr_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word n_namesz;
+ Elf_Word n_descsz;
+ Elf_Word n_type;
+
+ /// The alignment of the name and descriptor.
+ ///
+ /// Implementations differ from the specification here: in practice all
+ /// variants align both the name and descriptor to 4-bytes.
+ static const unsigned int Align = 4;
+
+ /// Get the size of the note, including name, descriptor, and padding.
+ size_t getSize() const {
+ return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
+ }
+};
+
+/// An ELF note.
+///
+/// Wraps a note header, providing methods for accessing the name and
+/// descriptor safely.
+template <class ELFT>
+class Elf_Note_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+
+ const Elf_Nhdr_Impl<ELFT> &Nhdr;
+
+ template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
+
+public:
+ Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
+
+ /// Get the note's name, excluding the terminating null byte.
+ StringRef getName() const {
+ if (!Nhdr.n_namesz)
+ return StringRef();
+ return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
+ Nhdr.n_namesz - 1);
+ }
+
+ /// Get the note's descriptor.
+ ArrayRef<uint8_t> getDesc() const {
+ if (!Nhdr.n_descsz)
+ return ArrayRef<uint8_t>();
+ return ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
+ alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz),
+ Nhdr.n_descsz);
+ }
+
+ /// Get the note's descriptor as StringRef
+ StringRef getDescAsStringRef() const {
+ ArrayRef<uint8_t> Desc = getDesc();
+ return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
+ }
+
+ /// Get the note's type.
+ Elf_Word getType() const { return Nhdr.n_type; }
+};
+
+template <class ELFT>
+class Elf_Note_Iterator_Impl
+ : std::iterator<std::forward_iterator_tag, Elf_Note_Impl<ELFT>> {
+ // Nhdr being a nullptr marks the end of iteration.
+ const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
+ size_t RemainingSize = 0u;
+ Error *Err = nullptr;
+
+ template <class ELFFileELFT> friend class ELFFile;
+
+ // Stop iteration and indicate an overflow.
+ void stopWithOverflowError() {
+ Nhdr = nullptr;
+ *Err = make_error<StringError>("ELF note overflows container",
+ object_error::parse_failed);
+ }
+
+ // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
+ //
+ // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
+ // upon returning. Handles stopping iteration when reaching the end of the
+ // container, either cleanly or with an overflow error.
+ void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
+ RemainingSize -= NoteSize;
+ if (RemainingSize == 0u) {
+ // Ensure that if the iterator walks to the end, the error is checked
+ // afterwards.
+ *Err = Error::success();
+ Nhdr = nullptr;
+ } else if (sizeof(*Nhdr) > RemainingSize)
+ stopWithOverflowError();
+ else {
+ Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
+ if (Nhdr->getSize() > RemainingSize)
+ stopWithOverflowError();
+ else
+ *Err = Error::success();
+ }
+ }
+
+ Elf_Note_Iterator_Impl() {}
+ explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
+ Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, Error &Err)
+ : RemainingSize(Size), Err(&Err) {
+ consumeError(std::move(Err));
+ assert(Start && "ELF note iterator starting at NULL");
+ advanceNhdr(Start, 0u);
+ }
+
+public:
+ Elf_Note_Iterator_Impl &operator++() {
+ assert(Nhdr && "incremented ELF note end iterator");
+ const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
+ size_t NoteSize = Nhdr->getSize();
+ advanceNhdr(NhdrPos, NoteSize);
+ return *this;
+ }
+ bool operator==(Elf_Note_Iterator_Impl Other) const {
+ if (!Nhdr && Other.Err)
+ (void)(bool)(*Other.Err);
+ if (!Other.Nhdr && Err)
+ (void)(bool)(*Err);
+ return Nhdr == Other.Nhdr;
+ }
+ bool operator!=(Elf_Note_Iterator_Impl Other) const {
+ return !(*this == Other);
+ }
+ Elf_Note_Impl<ELFT> operator*() const {
+ assert(Nhdr && "dereferenced ELF note end iterator");
+ return Elf_Note_Impl<ELFT>(*Nhdr);
+ }
+};
+
+template <class ELFT> struct Elf_CGProfile_Impl {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Word cgp_from;
+ Elf_Word cgp_to;
+ Elf_Xword cgp_weight;
+};
+
+// MIPS .reginfo section
+template <class ELFT>
+struct Elf_Mips_RegInfo;
+
+template <support::endianness TargetEndianness>
+struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
+ Elf_Word ri_gprmask; // bit-mask of used general registers
+ Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
+ Elf_Addr ri_gp_value; // gp register value
+};
+
+template <support::endianness TargetEndianness>
+struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
+ LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
+ Elf_Word ri_gprmask; // bit-mask of used general registers
+ Elf_Word ri_pad; // unused padding field
+ Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
+ Elf_Addr ri_gp_value; // gp register value
+};
+
+// .MIPS.options section
+template <class ELFT> struct Elf_Mips_Options {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ uint8_t kind; // Determines interpretation of variable part of descriptor
+ uint8_t size; // Byte size of descriptor, including this header
+ Elf_Half section; // Section header index of section affected,
+ // or 0 for global options
+ Elf_Word info; // Kind-specific information
+
+ Elf_Mips_RegInfo<ELFT> &getRegInfo() {
+ assert(kind == ELF::ODK_REGINFO);
+ return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
+ (uint8_t *)this + sizeof(Elf_Mips_Options));
+ }
+ const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
+ return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
+ }
+};
+
+// .MIPS.abiflags section content
+template <class ELFT> struct Elf_Mips_ABIFlags {
+ LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
+ Elf_Half version; // Version of the structure
+ uint8_t isa_level; // ISA level: 1-5, 32, and 64
+ uint8_t isa_rev; // ISA revision (0 for MIPS I - MIPS V)
+ uint8_t gpr_size; // General purpose registers size
+ uint8_t cpr1_size; // Co-processor 1 registers size
+ uint8_t cpr2_size; // Co-processor 2 registers size
+ uint8_t fp_abi; // Floating-point ABI flag
+ Elf_Word isa_ext; // Processor-specific extension
+ Elf_Word ases; // ASEs flags
+ Elf_Word flags1; // General flags
+ Elf_Word flags2; // General flags
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif // LLVM_OBJECT_ELFTYPES_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/Error.h b/contrib/libs/llvm12/include/llvm/Object/Error.h
index 8cfaa1a87cb..55033fb6b5e 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Error.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Error.h
@@ -1,105 +1,105 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Error.h - system_error extensions for Object -------------*- 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 declares a new error_category for the Object library.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_ERROR_H
-#define LLVM_OBJECT_ERROR_H
-
-#include "llvm/Support/Error.h"
-#include <system_error>
-
-namespace llvm {
-
-class Twine;
-
-namespace object {
-
-class Binary;
-
-const std::error_category &object_category();
-
-enum class object_error {
- // Error code 0 is absent. Use std::error_code() instead.
- arch_not_found = 1,
- invalid_file_type,
- parse_failed,
- unexpected_eof,
- string_table_non_null_end,
- invalid_section_index,
- bitcode_section_not_found,
- invalid_symbol_index,
-};
-
-inline std::error_code make_error_code(object_error e) {
- return std::error_code(static_cast<int>(e), object_category());
-}
-
-/// Base class for all errors indicating malformed binary files.
-///
-/// Having a subclass for all malformed binary files allows archive-walking
-/// code to skip malformed files without having to understand every possible
-/// way that a binary file might be malformed.
-///
-/// Currently inherits from ECError for easy interoperability with
-/// std::error_code, but this will be removed in the future.
-class BinaryError : public ErrorInfo<BinaryError, ECError> {
- void anchor() override;
-public:
- static char ID;
- BinaryError() {
- // Default to parse_failed, can be overridden with setErrorCode.
- setErrorCode(make_error_code(object_error::parse_failed));
- }
-};
-
-/// Generic binary error.
-///
-/// For errors that don't require their own specific sub-error (most errors)
-/// this class can be used to describe the error via a string message.
-class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
-public:
- static char ID;
- GenericBinaryError(const Twine &Msg);
- GenericBinaryError(const Twine &Msg, object_error ECOverride);
- const std::string &getMessage() const { return Msg; }
- void log(raw_ostream &OS) const override;
-private:
- std::string Msg;
-};
-
-/// isNotObjectErrorInvalidFileType() is used when looping through the children
-/// of an archive after calling getAsBinary() on the child and it returns an
-/// llvm::Error. In the cases we want to loop through the children and ignore the
-/// non-objects in the archive this is used to test the error to see if an
-/// error() function needs to called on the llvm::Error.
-Error isNotObjectErrorInvalidFileType(llvm::Error Err);
-
-} // end namespace object.
-
-} // end namespace llvm.
-
-namespace std {
-template <>
-struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
-}
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Error.h - system_error extensions for Object -------------*- 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 declares a new error_category for the Object library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ERROR_H
+#define LLVM_OBJECT_ERROR_H
+
+#include "llvm/Support/Error.h"
+#include <system_error>
+
+namespace llvm {
+
+class Twine;
+
+namespace object {
+
+class Binary;
+
+const std::error_category &object_category();
+
+enum class object_error {
+ // Error code 0 is absent. Use std::error_code() instead.
+ arch_not_found = 1,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof,
+ string_table_non_null_end,
+ invalid_section_index,
+ bitcode_section_not_found,
+ invalid_symbol_index,
+};
+
+inline std::error_code make_error_code(object_error e) {
+ return std::error_code(static_cast<int>(e), object_category());
+}
+
+/// Base class for all errors indicating malformed binary files.
+///
+/// Having a subclass for all malformed binary files allows archive-walking
+/// code to skip malformed files without having to understand every possible
+/// way that a binary file might be malformed.
+///
+/// Currently inherits from ECError for easy interoperability with
+/// std::error_code, but this will be removed in the future.
+class BinaryError : public ErrorInfo<BinaryError, ECError> {
+ void anchor() override;
+public:
+ static char ID;
+ BinaryError() {
+ // Default to parse_failed, can be overridden with setErrorCode.
+ setErrorCode(make_error_code(object_error::parse_failed));
+ }
+};
+
+/// Generic binary error.
+///
+/// For errors that don't require their own specific sub-error (most errors)
+/// this class can be used to describe the error via a string message.
+class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
+public:
+ static char ID;
+ GenericBinaryError(const Twine &Msg);
+ GenericBinaryError(const Twine &Msg, object_error ECOverride);
+ const std::string &getMessage() const { return Msg; }
+ void log(raw_ostream &OS) const override;
+private:
+ std::string Msg;
+};
+
+/// isNotObjectErrorInvalidFileType() is used when looping through the children
+/// of an archive after calling getAsBinary() on the child and it returns an
+/// llvm::Error. In the cases we want to loop through the children and ignore the
+/// non-objects in the archive this is used to test the error to see if an
+/// error() function needs to called on the llvm::Error.
+Error isNotObjectErrorInvalidFileType(llvm::Error Err);
+
+} // end namespace object.
+
+} // end namespace llvm.
+
+namespace std {
+template <>
+struct is_error_code_enum<llvm::object::object_error> : std::true_type {};
+}
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/IRObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/IRObjectFile.h
index da4a9d74aaa..548cea58d18 100644
--- a/contrib/libs/llvm12/include/llvm/Object/IRObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/IRObjectFile.h
@@ -1,102 +1,102 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- IRObjectFile.h - LLVM IR object file implementation ------*- 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 IRObjectFile template class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_IROBJECTFILE_H
-#define LLVM_OBJECT_IROBJECTFILE_H
-
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/Object/IRSymtab.h"
-#include "llvm/Object/ModuleSymbolTable.h"
-#include "llvm/Object/SymbolicFile.h"
-
-namespace llvm {
-class BitcodeModule;
-class Mangler;
-class Module;
-class GlobalValue;
-class Triple;
-
-namespace object {
-class ObjectFile;
-
-class IRObjectFile : public SymbolicFile {
- std::vector<std::unique_ptr<Module>> Mods;
- ModuleSymbolTable SymTab;
- IRObjectFile(MemoryBufferRef Object,
- std::vector<std::unique_ptr<Module>> Mods);
-
-public:
- ~IRObjectFile() override;
- void moveSymbolNext(DataRefImpl &Symb) const override;
- Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
- basic_symbol_iterator symbol_begin() const override;
- basic_symbol_iterator symbol_end() const override;
-
- StringRef getTargetTriple() const;
-
- static bool classof(const Binary *v) {
- return v->isIR();
- }
-
- using module_iterator =
- pointee_iterator<std::vector<std::unique_ptr<Module>>::const_iterator,
- const Module>;
-
- module_iterator module_begin() const { return module_iterator(Mods.begin()); }
- module_iterator module_end() const { return module_iterator(Mods.end()); }
-
- iterator_range<module_iterator> modules() const {
- return make_range(module_begin(), module_end());
- }
-
- /// Finds and returns bitcode embedded in the given object file, or an
- /// error code if not found.
- static Expected<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
-
- /// Finds and returns bitcode in the given memory buffer (which may
- /// be either a bitcode file or a native object file with embedded bitcode),
- /// or an error code if not found.
- static Expected<MemoryBufferRef>
- findBitcodeInMemBuffer(MemoryBufferRef Object);
-
- static Expected<std::unique_ptr<IRObjectFile>> create(MemoryBufferRef Object,
- LLVMContext &Context);
-};
-
-/// The contents of a bitcode file and its irsymtab. Any underlying data
-/// for the irsymtab are owned by Symtab and Strtab.
-struct IRSymtabFile {
- std::vector<BitcodeModule> Mods;
- SmallVector<char, 0> Symtab, Strtab;
- irsymtab::Reader TheReader;
-};
-
-/// Reads a bitcode file, creating its irsymtab if necessary.
-Expected<IRSymtabFile> readIRSymtab(MemoryBufferRef MBRef);
-
-}
-
-}
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- IRObjectFile.h - LLVM IR object file implementation ------*- 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 IRObjectFile template class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IROBJECTFILE_H
+#define LLVM_OBJECT_IROBJECTFILE_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Object/IRSymtab.h"
+#include "llvm/Object/ModuleSymbolTable.h"
+#include "llvm/Object/SymbolicFile.h"
+
+namespace llvm {
+class BitcodeModule;
+class Mangler;
+class Module;
+class GlobalValue;
+class Triple;
+
+namespace object {
+class ObjectFile;
+
+class IRObjectFile : public SymbolicFile {
+ std::vector<std::unique_ptr<Module>> Mods;
+ ModuleSymbolTable SymTab;
+ IRObjectFile(MemoryBufferRef Object,
+ std::vector<std::unique_ptr<Module>> Mods);
+
+public:
+ ~IRObjectFile() override;
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ StringRef getTargetTriple() const;
+
+ static bool classof(const Binary *v) {
+ return v->isIR();
+ }
+
+ using module_iterator =
+ pointee_iterator<std::vector<std::unique_ptr<Module>>::const_iterator,
+ const Module>;
+
+ module_iterator module_begin() const { return module_iterator(Mods.begin()); }
+ module_iterator module_end() const { return module_iterator(Mods.end()); }
+
+ iterator_range<module_iterator> modules() const {
+ return make_range(module_begin(), module_end());
+ }
+
+ /// Finds and returns bitcode embedded in the given object file, or an
+ /// error code if not found.
+ static Expected<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj);
+
+ /// Finds and returns bitcode in the given memory buffer (which may
+ /// be either a bitcode file or a native object file with embedded bitcode),
+ /// or an error code if not found.
+ static Expected<MemoryBufferRef>
+ findBitcodeInMemBuffer(MemoryBufferRef Object);
+
+ static Expected<std::unique_ptr<IRObjectFile>> create(MemoryBufferRef Object,
+ LLVMContext &Context);
+};
+
+/// The contents of a bitcode file and its irsymtab. Any underlying data
+/// for the irsymtab are owned by Symtab and Strtab.
+struct IRSymtabFile {
+ std::vector<BitcodeModule> Mods;
+ SmallVector<char, 0> Symtab, Strtab;
+ irsymtab::Reader TheReader;
+};
+
+/// Reads a bitcode file, creating its irsymtab if necessary.
+Expected<IRSymtabFile> readIRSymtab(MemoryBufferRef MBRef);
+
+}
+
+}
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/IRSymtab.h b/contrib/libs/llvm12/include/llvm/Object/IRSymtab.h
index 59a6817bd5d..5aec93d8eb9 100644
--- a/contrib/libs/llvm12/include/llvm/Object/IRSymtab.h
+++ b/contrib/libs/llvm12/include/llvm/Object/IRSymtab.h
@@ -1,385 +1,385 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- IRSymtab.h - data definitions for IR symbol tables -------*- 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 contains data definitions and a reader and builder for a symbol
-// table for LLVM IR. Its purpose is to allow linkers and other consumers of
-// bitcode files to efficiently read the symbol table for symbol resolution
-// purposes without needing to construct a module in memory.
-//
-// As with most object files the symbol table has two parts: the symbol table
-// itself and a string table which is referenced by the symbol table.
-//
-// A symbol table corresponds to a single bitcode file, which may consist of
-// multiple modules, so symbol tables may likewise contain symbols for multiple
-// modules.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_IRSYMTAB_H
-#define LLVM_OBJECT_IRSYMTAB_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-
-struct BitcodeFileContents;
-class StringTableBuilder;
-
-namespace irsymtab {
-
-namespace storage {
-
-// The data structures in this namespace define the low-level serialization
-// format. Clients that just want to read a symbol table should use the
-// irsymtab::Reader class.
-
-using Word = support::ulittle32_t;
-
-/// A reference to a string in the string table.
-struct Str {
- Word Offset, Size;
-
- StringRef get(StringRef Strtab) const {
- return {Strtab.data() + Offset, Size};
- }
-};
-
-/// A reference to a range of objects in the symbol table.
-template <typename T> struct Range {
- Word Offset, Size;
-
- ArrayRef<T> get(StringRef Symtab) const {
- return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
- }
-};
-
-/// Describes the range of a particular module's symbols within the symbol
-/// table.
-struct Module {
- Word Begin, End;
-
- /// The index of the first Uncommon for this Module.
- Word UncBegin;
-};
-
-/// This is equivalent to an IR comdat.
-struct Comdat {
- Str Name;
-};
-
-/// Contains the information needed by linkers for symbol resolution, as well as
-/// by the LTO implementation itself.
-struct Symbol {
- /// The mangled symbol name.
- Str Name;
-
- /// The unmangled symbol name, or the empty string if this is not an IR
- /// symbol.
- Str IRName;
-
- /// The index into Header::Comdats, or -1 if not a comdat member.
- Word ComdatIndex;
-
- Word Flags;
- enum FlagBits {
- FB_visibility, // 2 bits
- FB_has_uncommon = FB_visibility + 2,
- FB_undefined,
- FB_weak,
- FB_common,
- FB_indirect,
- FB_used,
- FB_tls,
- FB_may_omit,
- FB_global,
- FB_format_specific,
- FB_unnamed_addr,
- FB_executable,
- };
-};
-
-/// This data structure contains rarely used symbol fields and is optionally
-/// referenced by a Symbol.
-struct Uncommon {
- Word CommonSize, CommonAlign;
-
- /// COFF-specific: the name of the symbol that a weak external resolves to
- /// if not defined.
- Str COFFWeakExternFallbackName;
-
- /// Specified section name, if any.
- Str SectionName;
-};
-
-
-struct Header {
- /// Version number of the symtab format. This number should be incremented
- /// when the format changes, but it does not need to be incremented if a
- /// change to LLVM would cause it to create a different symbol table.
- Word Version;
- enum { kCurrentVersion = 2 };
-
- /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
- /// Consumers should rebuild the symbol table from IR if the producer's
- /// version does not match the consumer's version due to potential differences
- /// in symbol table format, symbol enumeration order and so on.
- Str Producer;
-
- Range<Module> Modules;
- Range<Comdat> Comdats;
- Range<Symbol> Symbols;
- Range<Uncommon> Uncommons;
-
- Str TargetTriple, SourceFileName;
-
- /// COFF-specific: linker directives.
- Str COFFLinkerOpts;
-
- /// Dependent Library Specifiers
- Range<Str> DependentLibraries;
-};
-
-} // end namespace storage
-
-/// Fills in Symtab and StrtabBuilder with a valid symbol and string table for
-/// Mods.
-Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
- StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc);
-
-/// This represents a symbol that has been read from a storage::Symbol and
-/// possibly a storage::Uncommon.
-struct Symbol {
- // Copied from storage::Symbol.
- StringRef Name, IRName;
- int ComdatIndex;
- uint32_t Flags;
-
- // Copied from storage::Uncommon.
- uint32_t CommonSize, CommonAlign;
- StringRef COFFWeakExternFallbackName;
- StringRef SectionName;
-
- /// Returns the mangled symbol name.
- StringRef getName() const { return Name; }
-
- /// Returns the unmangled symbol name, or the empty string if this is not an
- /// IR symbol.
- StringRef getIRName() const { return IRName; }
-
- /// Returns the index into the comdat table (see Reader::getComdatTable()), or
- /// -1 if not a comdat member.
- int getComdatIndex() const { return ComdatIndex; }
-
- using S = storage::Symbol;
-
- GlobalValue::VisibilityTypes getVisibility() const {
- return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
- }
-
- bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
- bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
- bool isCommon() const { return (Flags >> S::FB_common) & 1; }
- bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
- bool isUsed() const { return (Flags >> S::FB_used) & 1; }
- bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
-
- bool canBeOmittedFromSymbolTable() const {
- return (Flags >> S::FB_may_omit) & 1;
- }
-
- bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
- bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
- bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
- bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
-
- uint64_t getCommonSize() const {
- assert(isCommon());
- return CommonSize;
- }
-
- uint32_t getCommonAlignment() const {
- assert(isCommon());
- return CommonAlign;
- }
-
- /// COFF-specific: for weak externals, returns the name of the symbol that is
- /// used as a fallback if the weak external remains undefined.
- StringRef getCOFFWeakExternalFallback() const {
- assert(isWeak() && isIndirect());
- return COFFWeakExternFallbackName;
- }
-
- StringRef getSectionName() const { return SectionName; }
-};
-
-/// This class can be used to read a Symtab and Strtab produced by
-/// irsymtab::build.
-class Reader {
- StringRef Symtab, Strtab;
-
- ArrayRef<storage::Module> Modules;
- ArrayRef<storage::Comdat> Comdats;
- ArrayRef<storage::Symbol> Symbols;
- ArrayRef<storage::Uncommon> Uncommons;
- ArrayRef<storage::Str> DependentLibraries;
-
- StringRef str(storage::Str S) const { return S.get(Strtab); }
-
- template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
- return R.get(Symtab);
- }
-
- const storage::Header &header() const {
- return *reinterpret_cast<const storage::Header *>(Symtab.data());
- }
-
-public:
- class SymbolRef;
-
- Reader() = default;
- Reader(StringRef Symtab, StringRef Strtab) : Symtab(Symtab), Strtab(Strtab) {
- Modules = range(header().Modules);
- Comdats = range(header().Comdats);
- Symbols = range(header().Symbols);
- Uncommons = range(header().Uncommons);
- DependentLibraries = range(header().DependentLibraries);
- }
-
- using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
-
- /// Returns the symbol table for the entire bitcode file.
- /// The symbols enumerated by this method are ephemeral, but they can be
- /// copied into an irsymtab::Symbol object.
- symbol_range symbols() const;
-
- size_t getNumModules() const { return Modules.size(); }
-
- /// Returns a slice of the symbol table for the I'th module in the file.
- /// The symbols enumerated by this method are ephemeral, but they can be
- /// copied into an irsymtab::Symbol object.
- symbol_range module_symbols(unsigned I) const;
-
- StringRef getTargetTriple() const { return str(header().TargetTriple); }
-
- /// Returns the source file path specified at compile time.
- StringRef getSourceFileName() const { return str(header().SourceFileName); }
-
- /// Returns a table with all the comdats used by this file.
- std::vector<StringRef> getComdatTable() const {
- std::vector<StringRef> ComdatTable;
- ComdatTable.reserve(Comdats.size());
- for (auto C : Comdats)
- ComdatTable.push_back(str(C.Name));
- return ComdatTable;
- }
-
- /// COFF-specific: returns linker options specified in the input file.
- StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
-
- /// Returns dependent library specifiers
- std::vector<StringRef> getDependentLibraries() const {
- std::vector<StringRef> Specifiers;
- Specifiers.reserve(DependentLibraries.size());
- for (auto S : DependentLibraries) {
- Specifiers.push_back(str(S));
- }
- return Specifiers;
- }
-};
-
-/// Ephemeral symbols produced by Reader::symbols() and
-/// Reader::module_symbols().
-class Reader::SymbolRef : public Symbol {
- const storage::Symbol *SymI, *SymE;
- const storage::Uncommon *UncI;
- const Reader *R;
-
- void read() {
- if (SymI == SymE)
- return;
-
- Name = R->str(SymI->Name);
- IRName = R->str(SymI->IRName);
- ComdatIndex = SymI->ComdatIndex;
- Flags = SymI->Flags;
-
- if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
- CommonSize = UncI->CommonSize;
- CommonAlign = UncI->CommonAlign;
- COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
- SectionName = R->str(UncI->SectionName);
- } else
- // Reset this field so it can be queried unconditionally for all symbols.
- SectionName = "";
- }
-
-public:
- SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
- const storage::Uncommon *UncI, const Reader *R)
- : SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
- read();
- }
-
- void moveNext() {
- ++SymI;
- if (Flags & (1 << storage::Symbol::FB_has_uncommon))
- ++UncI;
- read();
- }
-
- bool operator==(const SymbolRef &Other) const { return SymI == Other.SymI; }
-};
-
-inline Reader::symbol_range Reader::symbols() const {
- return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
- SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
-}
-
-inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
- const storage::Module &M = Modules[I];
- const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
- *MEnd = Symbols.begin() + M.End;
- return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
- SymbolRef(MEnd, MEnd, nullptr, this)};
-}
-
-/// The contents of the irsymtab in a bitcode file. Any underlying data for the
-/// irsymtab are owned by Symtab and Strtab.
-struct FileContents {
- SmallVector<char, 0> Symtab, Strtab;
- Reader TheReader;
-};
-
-/// Reads the contents of a bitcode file, creating its irsymtab if necessary.
-Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
-
-} // end namespace irsymtab
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_IRSYMTAB_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- IRSymtab.h - data definitions for IR symbol tables -------*- 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 contains data definitions and a reader and builder for a symbol
+// table for LLVM IR. Its purpose is to allow linkers and other consumers of
+// bitcode files to efficiently read the symbol table for symbol resolution
+// purposes without needing to construct a module in memory.
+//
+// As with most object files the symbol table has two parts: the symbol table
+// itself and a string table which is referenced by the symbol table.
+//
+// A symbol table corresponds to a single bitcode file, which may consist of
+// multiple modules, so symbol tables may likewise contain symbols for multiple
+// modules.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_IRSYMTAB_H
+#define LLVM_OBJECT_IRSYMTAB_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+struct BitcodeFileContents;
+class StringTableBuilder;
+
+namespace irsymtab {
+
+namespace storage {
+
+// The data structures in this namespace define the low-level serialization
+// format. Clients that just want to read a symbol table should use the
+// irsymtab::Reader class.
+
+using Word = support::ulittle32_t;
+
+/// A reference to a string in the string table.
+struct Str {
+ Word Offset, Size;
+
+ StringRef get(StringRef Strtab) const {
+ return {Strtab.data() + Offset, Size};
+ }
+};
+
+/// A reference to a range of objects in the symbol table.
+template <typename T> struct Range {
+ Word Offset, Size;
+
+ ArrayRef<T> get(StringRef Symtab) const {
+ return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
+ }
+};
+
+/// Describes the range of a particular module's symbols within the symbol
+/// table.
+struct Module {
+ Word Begin, End;
+
+ /// The index of the first Uncommon for this Module.
+ Word UncBegin;
+};
+
+/// This is equivalent to an IR comdat.
+struct Comdat {
+ Str Name;
+};
+
+/// Contains the information needed by linkers for symbol resolution, as well as
+/// by the LTO implementation itself.
+struct Symbol {
+ /// The mangled symbol name.
+ Str Name;
+
+ /// The unmangled symbol name, or the empty string if this is not an IR
+ /// symbol.
+ Str IRName;
+
+ /// The index into Header::Comdats, or -1 if not a comdat member.
+ Word ComdatIndex;
+
+ Word Flags;
+ enum FlagBits {
+ FB_visibility, // 2 bits
+ FB_has_uncommon = FB_visibility + 2,
+ FB_undefined,
+ FB_weak,
+ FB_common,
+ FB_indirect,
+ FB_used,
+ FB_tls,
+ FB_may_omit,
+ FB_global,
+ FB_format_specific,
+ FB_unnamed_addr,
+ FB_executable,
+ };
+};
+
+/// This data structure contains rarely used symbol fields and is optionally
+/// referenced by a Symbol.
+struct Uncommon {
+ Word CommonSize, CommonAlign;
+
+ /// COFF-specific: the name of the symbol that a weak external resolves to
+ /// if not defined.
+ Str COFFWeakExternFallbackName;
+
+ /// Specified section name, if any.
+ Str SectionName;
+};
+
+
+struct Header {
+ /// Version number of the symtab format. This number should be incremented
+ /// when the format changes, but it does not need to be incremented if a
+ /// change to LLVM would cause it to create a different symbol table.
+ Word Version;
+ enum { kCurrentVersion = 2 };
+
+ /// The producer's version string (LLVM_VERSION_STRING " " LLVM_REVISION).
+ /// Consumers should rebuild the symbol table from IR if the producer's
+ /// version does not match the consumer's version due to potential differences
+ /// in symbol table format, symbol enumeration order and so on.
+ Str Producer;
+
+ Range<Module> Modules;
+ Range<Comdat> Comdats;
+ Range<Symbol> Symbols;
+ Range<Uncommon> Uncommons;
+
+ Str TargetTriple, SourceFileName;
+
+ /// COFF-specific: linker directives.
+ Str COFFLinkerOpts;
+
+ /// Dependent Library Specifiers
+ Range<Str> DependentLibraries;
+};
+
+} // end namespace storage
+
+/// Fills in Symtab and StrtabBuilder with a valid symbol and string table for
+/// Mods.
+Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
+ StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc);
+
+/// This represents a symbol that has been read from a storage::Symbol and
+/// possibly a storage::Uncommon.
+struct Symbol {
+ // Copied from storage::Symbol.
+ StringRef Name, IRName;
+ int ComdatIndex;
+ uint32_t Flags;
+
+ // Copied from storage::Uncommon.
+ uint32_t CommonSize, CommonAlign;
+ StringRef COFFWeakExternFallbackName;
+ StringRef SectionName;
+
+ /// Returns the mangled symbol name.
+ StringRef getName() const { return Name; }
+
+ /// Returns the unmangled symbol name, or the empty string if this is not an
+ /// IR symbol.
+ StringRef getIRName() const { return IRName; }
+
+ /// Returns the index into the comdat table (see Reader::getComdatTable()), or
+ /// -1 if not a comdat member.
+ int getComdatIndex() const { return ComdatIndex; }
+
+ using S = storage::Symbol;
+
+ GlobalValue::VisibilityTypes getVisibility() const {
+ return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
+ }
+
+ bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
+ bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
+ bool isCommon() const { return (Flags >> S::FB_common) & 1; }
+ bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
+ bool isUsed() const { return (Flags >> S::FB_used) & 1; }
+ bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
+
+ bool canBeOmittedFromSymbolTable() const {
+ return (Flags >> S::FB_may_omit) & 1;
+ }
+
+ bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
+ bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
+ bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
+ bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
+
+ uint64_t getCommonSize() const {
+ assert(isCommon());
+ return CommonSize;
+ }
+
+ uint32_t getCommonAlignment() const {
+ assert(isCommon());
+ return CommonAlign;
+ }
+
+ /// COFF-specific: for weak externals, returns the name of the symbol that is
+ /// used as a fallback if the weak external remains undefined.
+ StringRef getCOFFWeakExternalFallback() const {
+ assert(isWeak() && isIndirect());
+ return COFFWeakExternFallbackName;
+ }
+
+ StringRef getSectionName() const { return SectionName; }
+};
+
+/// This class can be used to read a Symtab and Strtab produced by
+/// irsymtab::build.
+class Reader {
+ StringRef Symtab, Strtab;
+
+ ArrayRef<storage::Module> Modules;
+ ArrayRef<storage::Comdat> Comdats;
+ ArrayRef<storage::Symbol> Symbols;
+ ArrayRef<storage::Uncommon> Uncommons;
+ ArrayRef<storage::Str> DependentLibraries;
+
+ StringRef str(storage::Str S) const { return S.get(Strtab); }
+
+ template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
+ return R.get(Symtab);
+ }
+
+ const storage::Header &header() const {
+ return *reinterpret_cast<const storage::Header *>(Symtab.data());
+ }
+
+public:
+ class SymbolRef;
+
+ Reader() = default;
+ Reader(StringRef Symtab, StringRef Strtab) : Symtab(Symtab), Strtab(Strtab) {
+ Modules = range(header().Modules);
+ Comdats = range(header().Comdats);
+ Symbols = range(header().Symbols);
+ Uncommons = range(header().Uncommons);
+ DependentLibraries = range(header().DependentLibraries);
+ }
+
+ using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
+
+ /// Returns the symbol table for the entire bitcode file.
+ /// The symbols enumerated by this method are ephemeral, but they can be
+ /// copied into an irsymtab::Symbol object.
+ symbol_range symbols() const;
+
+ size_t getNumModules() const { return Modules.size(); }
+
+ /// Returns a slice of the symbol table for the I'th module in the file.
+ /// The symbols enumerated by this method are ephemeral, but they can be
+ /// copied into an irsymtab::Symbol object.
+ symbol_range module_symbols(unsigned I) const;
+
+ StringRef getTargetTriple() const { return str(header().TargetTriple); }
+
+ /// Returns the source file path specified at compile time.
+ StringRef getSourceFileName() const { return str(header().SourceFileName); }
+
+ /// Returns a table with all the comdats used by this file.
+ std::vector<StringRef> getComdatTable() const {
+ std::vector<StringRef> ComdatTable;
+ ComdatTable.reserve(Comdats.size());
+ for (auto C : Comdats)
+ ComdatTable.push_back(str(C.Name));
+ return ComdatTable;
+ }
+
+ /// COFF-specific: returns linker options specified in the input file.
+ StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
+
+ /// Returns dependent library specifiers
+ std::vector<StringRef> getDependentLibraries() const {
+ std::vector<StringRef> Specifiers;
+ Specifiers.reserve(DependentLibraries.size());
+ for (auto S : DependentLibraries) {
+ Specifiers.push_back(str(S));
+ }
+ return Specifiers;
+ }
+};
+
+/// Ephemeral symbols produced by Reader::symbols() and
+/// Reader::module_symbols().
+class Reader::SymbolRef : public Symbol {
+ const storage::Symbol *SymI, *SymE;
+ const storage::Uncommon *UncI;
+ const Reader *R;
+
+ void read() {
+ if (SymI == SymE)
+ return;
+
+ Name = R->str(SymI->Name);
+ IRName = R->str(SymI->IRName);
+ ComdatIndex = SymI->ComdatIndex;
+ Flags = SymI->Flags;
+
+ if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
+ CommonSize = UncI->CommonSize;
+ CommonAlign = UncI->CommonAlign;
+ COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
+ SectionName = R->str(UncI->SectionName);
+ } else
+ // Reset this field so it can be queried unconditionally for all symbols.
+ SectionName = "";
+ }
+
+public:
+ SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
+ const storage::Uncommon *UncI, const Reader *R)
+ : SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
+ read();
+ }
+
+ void moveNext() {
+ ++SymI;
+ if (Flags & (1 << storage::Symbol::FB_has_uncommon))
+ ++UncI;
+ read();
+ }
+
+ bool operator==(const SymbolRef &Other) const { return SymI == Other.SymI; }
+};
+
+inline Reader::symbol_range Reader::symbols() const {
+ return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
+ SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
+}
+
+inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
+ const storage::Module &M = Modules[I];
+ const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
+ *MEnd = Symbols.begin() + M.End;
+ return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
+ SymbolRef(MEnd, MEnd, nullptr, this)};
+}
+
+/// The contents of the irsymtab in a bitcode file. Any underlying data for the
+/// irsymtab are owned by Symtab and Strtab.
+struct FileContents {
+ SmallVector<char, 0> Symtab, Strtab;
+ Reader TheReader;
+};
+
+/// Reads the contents of a bitcode file, creating its irsymtab if necessary.
+Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
+
+} // end namespace irsymtab
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_IRSYMTAB_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/MachO.h b/contrib/libs/llvm12/include/llvm/Object/MachO.h
index bbc0a233ee1..7c8004f6883 100644
--- a/contrib/libs/llvm12/include/llvm/Object/MachO.h
+++ b/contrib/libs/llvm12/include/llvm/Object/MachO.h
@@ -1,750 +1,750 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MachO.h - MachO object file implementation ---------------*- 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 MachOObjectFile class, which implement the ObjectFile
-// interface for MachO files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MACHO_H
-#define LLVM_OBJECT_MACHO_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <system_error>
-
-namespace llvm {
-namespace object {
-
-/// DiceRef - This is a value type class that represents a single
-/// data in code entry in the table in a Mach-O object file.
-class DiceRef {
- DataRefImpl DicePimpl;
- const ObjectFile *OwningObject = nullptr;
-
-public:
- DiceRef() = default;
- DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
-
- bool operator==(const DiceRef &Other) const;
- bool operator<(const DiceRef &Other) const;
-
- void moveNext();
-
- std::error_code getOffset(uint32_t &Result) const;
- std::error_code getLength(uint16_t &Result) const;
- std::error_code getKind(uint16_t &Result) const;
-
- DataRefImpl getRawDataRefImpl() const;
- const ObjectFile *getObjectFile() const;
-};
-using dice_iterator = content_iterator<DiceRef>;
-
-/// ExportEntry encapsulates the current-state-of-the-walk used when doing a
-/// non-recursive walk of the trie data structure. This allows you to iterate
-/// across all exported symbols using:
-/// Error Err = Error::success();
-/// for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) {
-/// }
-/// if (Err) { report error ...
-class ExportEntry {
-public:
- ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef<uint8_t> Trie);
-
- StringRef name() const;
- uint64_t flags() const;
- uint64_t address() const;
- uint64_t other() const;
- StringRef otherName() const;
- uint32_t nodeOffset() const;
-
- bool operator==(const ExportEntry &) const;
-
- void moveNext();
-
-private:
- friend class MachOObjectFile;
-
- void moveToFirst();
- void moveToEnd();
- uint64_t readULEB128(const uint8_t *&p, const char **error);
- void pushDownUntilBottom();
- void pushNode(uint64_t Offset);
-
- // Represents a node in the mach-o exports trie.
- struct NodeState {
- NodeState(const uint8_t *Ptr);
-
- const uint8_t *Start;
- const uint8_t *Current;
- uint64_t Flags = 0;
- uint64_t Address = 0;
- uint64_t Other = 0;
- const char *ImportName = nullptr;
- unsigned ChildCount = 0;
- unsigned NextChildIndex = 0;
- unsigned ParentStringLength = 0;
- bool IsExportNode = false;
- };
- using NodeList = SmallVector<NodeState, 16>;
- using node_iterator = NodeList::const_iterator;
-
- Error *E;
- const MachOObjectFile *O;
- ArrayRef<uint8_t> Trie;
- SmallString<256> CumulativeString;
- NodeList Stack;
- bool Done = false;
-
- iterator_range<node_iterator> nodes() const {
- return make_range(Stack.begin(), Stack.end());
- }
-};
-using export_iterator = content_iterator<ExportEntry>;
-
-// Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
-// can be checked and translated. Only the SegIndex/SegOffset pairs from
-// checked entries are to be used with the segmentName(), sectionName() and
-// address() methods below.
-class BindRebaseSegInfo {
-public:
- BindRebaseSegInfo(const MachOObjectFile *Obj);
-
- // Used to check a Mach-O Bind or Rebase entry for errors when iterating.
- const char* checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
- uint8_t PointerSize, uint32_t Count=1,
- uint32_t Skip=0);
- // Used with valid SegIndex/SegOffset values from checked entries.
- StringRef segmentName(int32_t SegIndex);
- StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
- uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
-
-private:
- struct SectionInfo {
- uint64_t Address;
- uint64_t Size;
- StringRef SectionName;
- StringRef SegmentName;
- uint64_t OffsetInSegment;
- uint64_t SegmentStartAddress;
- int32_t SegmentIndex;
- };
- const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
-
- SmallVector<SectionInfo, 32> Sections;
- int32_t MaxSegIndex;
-};
-
-/// MachORebaseEntry encapsulates the current state in the decompression of
-/// rebasing opcodes. This allows you to iterate through the compressed table of
-/// rebasing using:
-/// Error Err = Error::success();
-/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
-/// }
-/// if (Err) { report error ...
-class MachORebaseEntry {
-public:
- MachORebaseEntry(Error *Err, const MachOObjectFile *O,
- ArrayRef<uint8_t> opcodes, bool is64Bit);
-
- int32_t segmentIndex() const;
- uint64_t segmentOffset() const;
- StringRef typeName() const;
- StringRef segmentName() const;
- StringRef sectionName() const;
- uint64_t address() const;
-
- bool operator==(const MachORebaseEntry &) const;
-
- void moveNext();
-
-private:
- friend class MachOObjectFile;
-
- void moveToFirst();
- void moveToEnd();
- uint64_t readULEB128(const char **error);
-
- Error *E;
- const MachOObjectFile *O;
- ArrayRef<uint8_t> Opcodes;
- const uint8_t *Ptr;
- uint64_t SegmentOffset = 0;
- int32_t SegmentIndex = -1;
- uint64_t RemainingLoopCount = 0;
- uint64_t AdvanceAmount = 0;
- uint8_t RebaseType = 0;
- uint8_t PointerSize;
- bool Done = false;
-};
-using rebase_iterator = content_iterator<MachORebaseEntry>;
-
-/// MachOBindEntry encapsulates the current state in the decompression of
-/// binding opcodes. This allows you to iterate through the compressed table of
-/// bindings using:
-/// Error Err = Error::success();
-/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) {
-/// }
-/// if (Err) { report error ...
-class MachOBindEntry {
-public:
- enum class Kind { Regular, Lazy, Weak };
-
- MachOBindEntry(Error *Err, const MachOObjectFile *O,
- ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
-
- int32_t segmentIndex() const;
- uint64_t segmentOffset() const;
- StringRef typeName() const;
- StringRef symbolName() const;
- uint32_t flags() const;
- int64_t addend() const;
- int ordinal() const;
-
- StringRef segmentName() const;
- StringRef sectionName() const;
- uint64_t address() const;
-
- bool operator==(const MachOBindEntry &) const;
-
- void moveNext();
-
-private:
- friend class MachOObjectFile;
-
- void moveToFirst();
- void moveToEnd();
- uint64_t readULEB128(const char **error);
- int64_t readSLEB128(const char **error);
-
- Error *E;
- const MachOObjectFile *O;
- ArrayRef<uint8_t> Opcodes;
- const uint8_t *Ptr;
- uint64_t SegmentOffset = 0;
- int32_t SegmentIndex = -1;
- StringRef SymbolName;
- bool LibraryOrdinalSet = false;
- int Ordinal = 0;
- uint32_t Flags = 0;
- int64_t Addend = 0;
- uint64_t RemainingLoopCount = 0;
- uint64_t AdvanceAmount = 0;
- uint8_t BindType = 0;
- uint8_t PointerSize;
- Kind TableKind;
- bool Done = false;
-};
-using bind_iterator = content_iterator<MachOBindEntry>;
-
-class MachOObjectFile : public ObjectFile {
-public:
- struct LoadCommandInfo {
- const char *Ptr; // Where in memory the load command is.
- MachO::load_command C; // The command itself.
- };
- using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
- using load_command_iterator = LoadCommandList::const_iterator;
-
- static Expected<std::unique_ptr<MachOObjectFile>>
- create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
- uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0);
-
- void moveSymbolNext(DataRefImpl &Symb) const override;
-
- uint64_t getNValue(DataRefImpl Sym) const;
- Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
-
- // MachO specific.
- Error checkSymbolTable() const;
-
- std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
- unsigned getSectionType(SectionRef Sec) const;
-
- Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
- uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
- uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
- Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
- unsigned getSymbolSectionID(SymbolRef Symb) const;
- unsigned getSectionID(SectionRef Sec) const;
-
- void moveSectionNext(DataRefImpl &Sec) const override;
- Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
- uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
- uint64_t getSectionSize(DataRefImpl Sec) const override;
- ArrayRef<uint8_t> getSectionContents(uint32_t Offset, uint64_t Size) const;
- Expected<ArrayRef<uint8_t>>
- getSectionContents(DataRefImpl Sec) const override;
- uint64_t getSectionAlignment(DataRefImpl Sec) const override;
- Expected<SectionRef> getSection(unsigned SectionIndex) const;
- Expected<SectionRef> getSection(StringRef SectionName) const;
- bool isSectionCompressed(DataRefImpl Sec) const override;
- bool isSectionText(DataRefImpl Sec) const override;
- bool isSectionData(DataRefImpl Sec) const override;
- bool isSectionBSS(DataRefImpl Sec) const override;
- bool isSectionVirtual(DataRefImpl Sec) const override;
- bool isSectionBitcode(DataRefImpl Sec) const override;
- bool isDebugSection(StringRef SectionName) const override;
-
- /// When dsymutil generates the companion file, it strips all unnecessary
- /// sections (e.g. everything in the _TEXT segment) by omitting their body
- /// and setting the offset in their corresponding load command to zero.
- ///
- /// While the load command itself is valid, reading the section corresponds
- /// to reading the number of bytes specified in the load command, starting
- /// from offset 0 (i.e. the Mach-O header at the beginning of the file).
- bool isSectionStripped(DataRefImpl Sec) const override;
-
- relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
- relocation_iterator section_rel_end(DataRefImpl Sec) const override;
-
- relocation_iterator extrel_begin() const;
- relocation_iterator extrel_end() const;
- iterator_range<relocation_iterator> external_relocations() const {
- return make_range(extrel_begin(), extrel_end());
- }
-
- relocation_iterator locrel_begin() const;
- relocation_iterator locrel_end() const;
-
- void moveRelocationNext(DataRefImpl &Rel) const override;
- uint64_t getRelocationOffset(DataRefImpl Rel) const override;
- symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- section_iterator getRelocationSection(DataRefImpl Rel) const;
- uint64_t getRelocationType(DataRefImpl Rel) const override;
- void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
- uint8_t getRelocationLength(DataRefImpl Rel) const;
-
- // MachO specific.
- std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
- uint32_t getLibraryCount() const;
-
- section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
-
- // TODO: Would be useful to have an iterator based version
- // of the load command interface too.
-
- basic_symbol_iterator symbol_begin() const override;
- basic_symbol_iterator symbol_end() const override;
-
- // MachO specific.
- symbol_iterator getSymbolByIndex(unsigned Index) const;
- uint64_t getSymbolIndex(DataRefImpl Symb) const;
-
- section_iterator section_begin() const override;
- section_iterator section_end() const override;
-
- uint8_t getBytesInAddress() const override;
-
- StringRef getFileFormatName() const override;
- Triple::ArchType getArch() const override;
- SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
- Triple getArchTriple(const char **McpuDefault = nullptr) const;
-
- relocation_iterator section_rel_begin(unsigned Index) const;
- relocation_iterator section_rel_end(unsigned Index) const;
-
- dice_iterator begin_dices() const;
- dice_iterator end_dices() const;
-
- load_command_iterator begin_load_commands() const;
- load_command_iterator end_load_commands() const;
- iterator_range<load_command_iterator> load_commands() const;
-
- /// For use iterating over all exported symbols.
- iterator_range<export_iterator> exports(Error &Err) const;
-
- /// For use examining a trie not in a MachOObjectFile.
- static iterator_range<export_iterator> exports(Error &Err,
- ArrayRef<uint8_t> Trie,
- const MachOObjectFile *O =
- nullptr);
-
- /// For use iterating over all rebase table entries.
- iterator_range<rebase_iterator> rebaseTable(Error &Err);
-
- /// For use examining rebase opcodes in a MachOObjectFile.
- static iterator_range<rebase_iterator> rebaseTable(Error &Err,
- MachOObjectFile *O,
- ArrayRef<uint8_t> Opcodes,
- bool is64);
-
- /// For use iterating over all bind table entries.
- iterator_range<bind_iterator> bindTable(Error &Err);
-
- /// For use iterating over all lazy bind table entries.
- iterator_range<bind_iterator> lazyBindTable(Error &Err);
-
- /// For use iterating over all weak bind table entries.
- iterator_range<bind_iterator> weakBindTable(Error &Err);
-
- /// For use examining bind opcodes in a MachOObjectFile.
- static iterator_range<bind_iterator> bindTable(Error &Err,
- MachOObjectFile *O,
- ArrayRef<uint8_t> Opcodes,
- bool is64,
- MachOBindEntry::Kind);
-
- // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
- // that fully contains a pointer at that location. Multiple fixups in a bind
- // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
- // be tested via the Count and Skip parameters.
- //
- // This is used by MachOBindEntry::moveNext() to validate a MachOBindEntry.
- const char *BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
- uint8_t PointerSize, uint32_t Count=1,
- uint32_t Skip=0) const {
- return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
- PointerSize, Count, Skip);
- }
-
- // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
- // that fully contains a pointer at that location. Multiple fixups in a rebase
- // (such as with the REBASE_OPCODE_DO_*_TIMES* opcodes) can be tested via the
- // Count and Skip parameters.
- //
- // This is used by MachORebaseEntry::moveNext() to validate a MachORebaseEntry
- const char *RebaseEntryCheckSegAndOffsets(int32_t SegIndex,
- uint64_t SegOffset,
- uint8_t PointerSize,
- uint32_t Count=1,
- uint32_t Skip=0) const {
- return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
- PointerSize, Count, Skip);
- }
-
- /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
- /// get the segment name.
- StringRef BindRebaseSegmentName(int32_t SegIndex) const {
- return BindRebaseSectionTable->segmentName(SegIndex);
- }
-
- /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
- /// Rebase entry to get the section name.
- StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
- return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
- }
-
- /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
- /// Rebase entry to get the address.
- uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
- return BindRebaseSectionTable->address(SegIndex, SegOffset);
- }
-
- // In a MachO file, sections have a segment name. This is used in the .o
- // files. They have a single segment, but this field specifies which segment
- // a section should be put in the final object.
- StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
-
- // Names are stored as 16 bytes. These returns the raw 16 bytes without
- // interpreting them as a C string.
- ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
- ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
-
- // MachO specific Info about relocations.
- bool isRelocationScattered(const MachO::any_relocation_info &RE) const;
- unsigned getPlainRelocationSymbolNum(
- const MachO::any_relocation_info &RE) const;
- bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const;
- bool getScatteredRelocationScattered(
- const MachO::any_relocation_info &RE) const;
- uint32_t getScatteredRelocationValue(
- const MachO::any_relocation_info &RE) const;
- uint32_t getScatteredRelocationType(
- const MachO::any_relocation_info &RE) const;
- unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
- unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
- unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
- unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
- SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const;
-
- // MachO specific structures.
- MachO::section getSection(DataRefImpl DRI) const;
- MachO::section_64 getSection64(DataRefImpl DRI) const;
- MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const;
- MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const;
- MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const;
- MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const;
-
- MachO::linkedit_data_command
- getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
- MachO::segment_command
- getSegmentLoadCommand(const LoadCommandInfo &L) const;
- MachO::segment_command_64
- getSegment64LoadCommand(const LoadCommandInfo &L) const;
- MachO::linker_option_command
- getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
- MachO::version_min_command
- getVersionMinLoadCommand(const LoadCommandInfo &L) const;
- MachO::note_command
- getNoteLoadCommand(const LoadCommandInfo &L) const;
- MachO::build_version_command
- getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
- MachO::build_tool_version
- getBuildToolVersion(unsigned index) const;
- MachO::dylib_command
- getDylibIDLoadCommand(const LoadCommandInfo &L) const;
- MachO::dyld_info_command
- getDyldInfoLoadCommand(const LoadCommandInfo &L) const;
- MachO::dylinker_command
- getDylinkerCommand(const LoadCommandInfo &L) const;
- MachO::uuid_command
- getUuidCommand(const LoadCommandInfo &L) const;
- MachO::rpath_command
- getRpathCommand(const LoadCommandInfo &L) const;
- MachO::source_version_command
- getSourceVersionCommand(const LoadCommandInfo &L) const;
- MachO::entry_point_command
- getEntryPointCommand(const LoadCommandInfo &L) const;
- MachO::encryption_info_command
- getEncryptionInfoCommand(const LoadCommandInfo &L) const;
- MachO::encryption_info_command_64
- getEncryptionInfoCommand64(const LoadCommandInfo &L) const;
- MachO::sub_framework_command
- getSubFrameworkCommand(const LoadCommandInfo &L) const;
- MachO::sub_umbrella_command
- getSubUmbrellaCommand(const LoadCommandInfo &L) const;
- MachO::sub_library_command
- getSubLibraryCommand(const LoadCommandInfo &L) const;
- MachO::sub_client_command
- getSubClientCommand(const LoadCommandInfo &L) const;
- MachO::routines_command
- getRoutinesCommand(const LoadCommandInfo &L) const;
- MachO::routines_command_64
- getRoutinesCommand64(const LoadCommandInfo &L) const;
- MachO::thread_command
- getThreadCommand(const LoadCommandInfo &L) const;
-
- MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
- MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
- const MachO::mach_header &getHeader() const;
- const MachO::mach_header_64 &getHeader64() const;
- uint32_t
- getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
- unsigned Index) const;
- MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset,
- unsigned Index) const;
- MachO::symtab_command getSymtabLoadCommand() const;
- MachO::dysymtab_command getDysymtabLoadCommand() const;
- MachO::linkedit_data_command getDataInCodeLoadCommand() const;
- MachO::linkedit_data_command getLinkOptHintsLoadCommand() const;
- ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const;
- ArrayRef<uint8_t> getDyldInfoBindOpcodes() const;
- ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const;
- ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const;
- ArrayRef<uint8_t> getDyldInfoExportsTrie() const;
- ArrayRef<uint8_t> getUuid() const;
-
- StringRef getStringTableData() const;
- bool is64Bit() const;
- void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
-
- static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
- StringRef &Suffix);
-
- static Triple::ArchType getArch(uint32_t CPUType, uint32_t CPUSubType);
- static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
- const char **McpuDefault = nullptr,
- const char **ArchFlag = nullptr);
- static bool isValidArch(StringRef ArchFlag);
- static ArrayRef<StringRef> getValidArchs();
- static Triple getHostArch();
-
- bool isRelocatableObject() const override;
-
- StringRef mapDebugSectionName(StringRef Name) const override;
-
- bool hasPageZeroSegment() const { return HasPageZeroSegment; }
-
- static bool classof(const Binary *v) {
- return v->isMachO();
- }
-
- static uint32_t
- getVersionMinMajor(MachO::version_min_command &C, bool SDK) {
- uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
- return (VersionOrSDK >> 16) & 0xffff;
- }
-
- static uint32_t
- getVersionMinMinor(MachO::version_min_command &C, bool SDK) {
- uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
- return (VersionOrSDK >> 8) & 0xff;
- }
-
- static uint32_t
- getVersionMinUpdate(MachO::version_min_command &C, bool SDK) {
- uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
- return VersionOrSDK & 0xff;
- }
-
- static std::string getBuildPlatform(uint32_t platform) {
- switch (platform) {
- case MachO::PLATFORM_MACOS: return "macos";
- case MachO::PLATFORM_IOS: return "ios";
- case MachO::PLATFORM_TVOS: return "tvos";
- case MachO::PLATFORM_WATCHOS: return "watchos";
- case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
- case MachO::PLATFORM_MACCATALYST: return "macCatalyst";
- case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator";
- case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator";
- case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator";
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MachO.h - MachO object file implementation ---------------*- 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 MachOObjectFile class, which implement the ObjectFile
+// interface for MachO files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHO_H
+#define LLVM_OBJECT_MACHO_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+/// DiceRef - This is a value type class that represents a single
+/// data in code entry in the table in a Mach-O object file.
+class DiceRef {
+ DataRefImpl DicePimpl;
+ const ObjectFile *OwningObject = nullptr;
+
+public:
+ DiceRef() = default;
+ DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
+
+ bool operator==(const DiceRef &Other) const;
+ bool operator<(const DiceRef &Other) const;
+
+ void moveNext();
+
+ std::error_code getOffset(uint32_t &Result) const;
+ std::error_code getLength(uint16_t &Result) const;
+ std::error_code getKind(uint16_t &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const ObjectFile *getObjectFile() const;
+};
+using dice_iterator = content_iterator<DiceRef>;
+
+/// ExportEntry encapsulates the current-state-of-the-walk used when doing a
+/// non-recursive walk of the trie data structure. This allows you to iterate
+/// across all exported symbols using:
+/// Error Err = Error::success();
+/// for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) {
+/// }
+/// if (Err) { report error ...
+class ExportEntry {
+public:
+ ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef<uint8_t> Trie);
+
+ StringRef name() const;
+ uint64_t flags() const;
+ uint64_t address() const;
+ uint64_t other() const;
+ StringRef otherName() const;
+ uint32_t nodeOffset() const;
+
+ bool operator==(const ExportEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128(const uint8_t *&p, const char **error);
+ void pushDownUntilBottom();
+ void pushNode(uint64_t Offset);
+
+ // Represents a node in the mach-o exports trie.
+ struct NodeState {
+ NodeState(const uint8_t *Ptr);
+
+ const uint8_t *Start;
+ const uint8_t *Current;
+ uint64_t Flags = 0;
+ uint64_t Address = 0;
+ uint64_t Other = 0;
+ const char *ImportName = nullptr;
+ unsigned ChildCount = 0;
+ unsigned NextChildIndex = 0;
+ unsigned ParentStringLength = 0;
+ bool IsExportNode = false;
+ };
+ using NodeList = SmallVector<NodeState, 16>;
+ using node_iterator = NodeList::const_iterator;
+
+ Error *E;
+ const MachOObjectFile *O;
+ ArrayRef<uint8_t> Trie;
+ SmallString<256> CumulativeString;
+ NodeList Stack;
+ bool Done = false;
+
+ iterator_range<node_iterator> nodes() const {
+ return make_range(Stack.begin(), Stack.end());
+ }
+};
+using export_iterator = content_iterator<ExportEntry>;
+
+// Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
+// can be checked and translated. Only the SegIndex/SegOffset pairs from
+// checked entries are to be used with the segmentName(), sectionName() and
+// address() methods below.
+class BindRebaseSegInfo {
+public:
+ BindRebaseSegInfo(const MachOObjectFile *Obj);
+
+ // Used to check a Mach-O Bind or Rebase entry for errors when iterating.
+ const char* checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
+ uint8_t PointerSize, uint32_t Count=1,
+ uint32_t Skip=0);
+ // Used with valid SegIndex/SegOffset values from checked entries.
+ StringRef segmentName(int32_t SegIndex);
+ StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
+ uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
+
+private:
+ struct SectionInfo {
+ uint64_t Address;
+ uint64_t Size;
+ StringRef SectionName;
+ StringRef SegmentName;
+ uint64_t OffsetInSegment;
+ uint64_t SegmentStartAddress;
+ int32_t SegmentIndex;
+ };
+ const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
+
+ SmallVector<SectionInfo, 32> Sections;
+ int32_t MaxSegIndex;
+};
+
+/// MachORebaseEntry encapsulates the current state in the decompression of
+/// rebasing opcodes. This allows you to iterate through the compressed table of
+/// rebasing using:
+/// Error Err = Error::success();
+/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
+/// }
+/// if (Err) { report error ...
+class MachORebaseEntry {
+public:
+ MachORebaseEntry(Error *Err, const MachOObjectFile *O,
+ ArrayRef<uint8_t> opcodes, bool is64Bit);
+
+ int32_t segmentIndex() const;
+ uint64_t segmentOffset() const;
+ StringRef typeName() const;
+ StringRef segmentName() const;
+ StringRef sectionName() const;
+ uint64_t address() const;
+
+ bool operator==(const MachORebaseEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128(const char **error);
+
+ Error *E;
+ const MachOObjectFile *O;
+ ArrayRef<uint8_t> Opcodes;
+ const uint8_t *Ptr;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t RebaseType = 0;
+ uint8_t PointerSize;
+ bool Done = false;
+};
+using rebase_iterator = content_iterator<MachORebaseEntry>;
+
+/// MachOBindEntry encapsulates the current state in the decompression of
+/// binding opcodes. This allows you to iterate through the compressed table of
+/// bindings using:
+/// Error Err = Error::success();
+/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) {
+/// }
+/// if (Err) { report error ...
+class MachOBindEntry {
+public:
+ enum class Kind { Regular, Lazy, Weak };
+
+ MachOBindEntry(Error *Err, const MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
+
+ int32_t segmentIndex() const;
+ uint64_t segmentOffset() const;
+ StringRef typeName() const;
+ StringRef symbolName() const;
+ uint32_t flags() const;
+ int64_t addend() const;
+ int ordinal() const;
+
+ StringRef segmentName() const;
+ StringRef sectionName() const;
+ uint64_t address() const;
+
+ bool operator==(const MachOBindEntry &) const;
+
+ void moveNext();
+
+private:
+ friend class MachOObjectFile;
+
+ void moveToFirst();
+ void moveToEnd();
+ uint64_t readULEB128(const char **error);
+ int64_t readSLEB128(const char **error);
+
+ Error *E;
+ const MachOObjectFile *O;
+ ArrayRef<uint8_t> Opcodes;
+ const uint8_t *Ptr;
+ uint64_t SegmentOffset = 0;
+ int32_t SegmentIndex = -1;
+ StringRef SymbolName;
+ bool LibraryOrdinalSet = false;
+ int Ordinal = 0;
+ uint32_t Flags = 0;
+ int64_t Addend = 0;
+ uint64_t RemainingLoopCount = 0;
+ uint64_t AdvanceAmount = 0;
+ uint8_t BindType = 0;
+ uint8_t PointerSize;
+ Kind TableKind;
+ bool Done = false;
+};
+using bind_iterator = content_iterator<MachOBindEntry>;
+
+class MachOObjectFile : public ObjectFile {
+public:
+ struct LoadCommandInfo {
+ const char *Ptr; // Where in memory the load command is.
+ MachO::load_command C; // The command itself.
+ };
+ using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
+ using load_command_iterator = LoadCommandList::const_iterator;
+
+ static Expected<std::unique_ptr<MachOObjectFile>>
+ create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
+ uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0);
+
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+
+ uint64_t getNValue(DataRefImpl Sym) const;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+
+ // MachO specific.
+ Error checkSymbolTable() const;
+
+ std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
+ unsigned getSectionType(SectionRef Sec) const;
+
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ unsigned getSymbolSectionID(SymbolRef Symb) const;
+ unsigned getSectionID(SectionRef Sec) const;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ ArrayRef<uint8_t> getSectionContents(uint32_t Offset, uint64_t Size) const;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ Expected<SectionRef> getSection(unsigned SectionIndex) const;
+ Expected<SectionRef> getSection(StringRef SectionName) const;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool isSectionBitcode(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
+
+ /// When dsymutil generates the companion file, it strips all unnecessary
+ /// sections (e.g. everything in the _TEXT segment) by omitting their body
+ /// and setting the offset in their corresponding load command to zero.
+ ///
+ /// While the load command itself is valid, reading the section corresponds
+ /// to reading the number of bytes specified in the load command, starting
+ /// from offset 0 (i.e. the Mach-O header at the beginning of the file).
+ bool isSectionStripped(DataRefImpl Sec) const override;
+
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ relocation_iterator extrel_begin() const;
+ relocation_iterator extrel_end() const;
+ iterator_range<relocation_iterator> external_relocations() const {
+ return make_range(extrel_begin(), extrel_end());
+ }
+
+ relocation_iterator locrel_begin() const;
+ relocation_iterator locrel_end() const;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ section_iterator getRelocationSection(DataRefImpl Rel) const;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+ uint8_t getRelocationLength(DataRefImpl Rel) const;
+
+ // MachO specific.
+ std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
+ uint32_t getLibraryCount() const;
+
+ section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
+
+ // TODO: Would be useful to have an iterator based version
+ // of the load command interface too.
+
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ // MachO specific.
+ symbol_iterator getSymbolByIndex(unsigned Index) const;
+ uint64_t getSymbolIndex(DataRefImpl Symb) const;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+
+ uint8_t getBytesInAddress() const override;
+
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
+ Triple getArchTriple(const char **McpuDefault = nullptr) const;
+
+ relocation_iterator section_rel_begin(unsigned Index) const;
+ relocation_iterator section_rel_end(unsigned Index) const;
+
+ dice_iterator begin_dices() const;
+ dice_iterator end_dices() const;
+
+ load_command_iterator begin_load_commands() const;
+ load_command_iterator end_load_commands() const;
+ iterator_range<load_command_iterator> load_commands() const;
+
+ /// For use iterating over all exported symbols.
+ iterator_range<export_iterator> exports(Error &Err) const;
+
+ /// For use examining a trie not in a MachOObjectFile.
+ static iterator_range<export_iterator> exports(Error &Err,
+ ArrayRef<uint8_t> Trie,
+ const MachOObjectFile *O =
+ nullptr);
+
+ /// For use iterating over all rebase table entries.
+ iterator_range<rebase_iterator> rebaseTable(Error &Err);
+
+ /// For use examining rebase opcodes in a MachOObjectFile.
+ static iterator_range<rebase_iterator> rebaseTable(Error &Err,
+ MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes,
+ bool is64);
+
+ /// For use iterating over all bind table entries.
+ iterator_range<bind_iterator> bindTable(Error &Err);
+
+ /// For use iterating over all lazy bind table entries.
+ iterator_range<bind_iterator> lazyBindTable(Error &Err);
+
+ /// For use iterating over all weak bind table entries.
+ iterator_range<bind_iterator> weakBindTable(Error &Err);
+
+ /// For use examining bind opcodes in a MachOObjectFile.
+ static iterator_range<bind_iterator> bindTable(Error &Err,
+ MachOObjectFile *O,
+ ArrayRef<uint8_t> Opcodes,
+ bool is64,
+ MachOBindEntry::Kind);
+
+ // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
+ // that fully contains a pointer at that location. Multiple fixups in a bind
+ // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can
+ // be tested via the Count and Skip parameters.
+ //
+ // This is used by MachOBindEntry::moveNext() to validate a MachOBindEntry.
+ const char *BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset,
+ uint8_t PointerSize, uint32_t Count=1,
+ uint32_t Skip=0) const {
+ return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
+ PointerSize, Count, Skip);
+ }
+
+ // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists
+ // that fully contains a pointer at that location. Multiple fixups in a rebase
+ // (such as with the REBASE_OPCODE_DO_*_TIMES* opcodes) can be tested via the
+ // Count and Skip parameters.
+ //
+ // This is used by MachORebaseEntry::moveNext() to validate a MachORebaseEntry
+ const char *RebaseEntryCheckSegAndOffsets(int32_t SegIndex,
+ uint64_t SegOffset,
+ uint8_t PointerSize,
+ uint32_t Count=1,
+ uint32_t Skip=0) const {
+ return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset,
+ PointerSize, Count, Skip);
+ }
+
+ /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
+ /// get the segment name.
+ StringRef BindRebaseSegmentName(int32_t SegIndex) const {
+ return BindRebaseSectionTable->segmentName(SegIndex);
+ }
+
+ /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+ /// Rebase entry to get the section name.
+ StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
+ return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
+ }
+
+ /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
+ /// Rebase entry to get the address.
+ uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
+ return BindRebaseSectionTable->address(SegIndex, SegOffset);
+ }
+
+ // In a MachO file, sections have a segment name. This is used in the .o
+ // files. They have a single segment, but this field specifies which segment
+ // a section should be put in the final object.
+ StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
+
+ // Names are stored as 16 bytes. These returns the raw 16 bytes without
+ // interpreting them as a C string.
+ ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
+ ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
+
+ // MachO specific Info about relocations.
+ bool isRelocationScattered(const MachO::any_relocation_info &RE) const;
+ unsigned getPlainRelocationSymbolNum(
+ const MachO::any_relocation_info &RE) const;
+ bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const;
+ bool getScatteredRelocationScattered(
+ const MachO::any_relocation_info &RE) const;
+ uint32_t getScatteredRelocationValue(
+ const MachO::any_relocation_info &RE) const;
+ uint32_t getScatteredRelocationType(
+ const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
+ unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
+ SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const;
+
+ // MachO specific structures.
+ MachO::section getSection(DataRefImpl DRI) const;
+ MachO::section_64 getSection64(DataRefImpl DRI) const;
+ MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const;
+ MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const;
+ MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const;
+ MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const;
+
+ MachO::linkedit_data_command
+ getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
+ MachO::segment_command
+ getSegmentLoadCommand(const LoadCommandInfo &L) const;
+ MachO::segment_command_64
+ getSegment64LoadCommand(const LoadCommandInfo &L) const;
+ MachO::linker_option_command
+ getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
+ MachO::version_min_command
+ getVersionMinLoadCommand(const LoadCommandInfo &L) const;
+ MachO::note_command
+ getNoteLoadCommand(const LoadCommandInfo &L) const;
+ MachO::build_version_command
+ getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
+ MachO::build_tool_version
+ getBuildToolVersion(unsigned index) const;
+ MachO::dylib_command
+ getDylibIDLoadCommand(const LoadCommandInfo &L) const;
+ MachO::dyld_info_command
+ getDyldInfoLoadCommand(const LoadCommandInfo &L) const;
+ MachO::dylinker_command
+ getDylinkerCommand(const LoadCommandInfo &L) const;
+ MachO::uuid_command
+ getUuidCommand(const LoadCommandInfo &L) const;
+ MachO::rpath_command
+ getRpathCommand(const LoadCommandInfo &L) const;
+ MachO::source_version_command
+ getSourceVersionCommand(const LoadCommandInfo &L) const;
+ MachO::entry_point_command
+ getEntryPointCommand(const LoadCommandInfo &L) const;
+ MachO::encryption_info_command
+ getEncryptionInfoCommand(const LoadCommandInfo &L) const;
+ MachO::encryption_info_command_64
+ getEncryptionInfoCommand64(const LoadCommandInfo &L) const;
+ MachO::sub_framework_command
+ getSubFrameworkCommand(const LoadCommandInfo &L) const;
+ MachO::sub_umbrella_command
+ getSubUmbrellaCommand(const LoadCommandInfo &L) const;
+ MachO::sub_library_command
+ getSubLibraryCommand(const LoadCommandInfo &L) const;
+ MachO::sub_client_command
+ getSubClientCommand(const LoadCommandInfo &L) const;
+ MachO::routines_command
+ getRoutinesCommand(const LoadCommandInfo &L) const;
+ MachO::routines_command_64
+ getRoutinesCommand64(const LoadCommandInfo &L) const;
+ MachO::thread_command
+ getThreadCommand(const LoadCommandInfo &L) const;
+
+ MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
+ MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
+ const MachO::mach_header &getHeader() const;
+ const MachO::mach_header_64 &getHeader64() const;
+ uint32_t
+ getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
+ unsigned Index) const;
+ MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset,
+ unsigned Index) const;
+ MachO::symtab_command getSymtabLoadCommand() const;
+ MachO::dysymtab_command getDysymtabLoadCommand() const;
+ MachO::linkedit_data_command getDataInCodeLoadCommand() const;
+ MachO::linkedit_data_command getLinkOptHintsLoadCommand() const;
+ ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoBindOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const;
+ ArrayRef<uint8_t> getDyldInfoExportsTrie() const;
+ ArrayRef<uint8_t> getUuid() const;
+
+ StringRef getStringTableData() const;
+ bool is64Bit() const;
+ void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
+
+ static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
+ StringRef &Suffix);
+
+ static Triple::ArchType getArch(uint32_t CPUType, uint32_t CPUSubType);
+ static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
+ const char **McpuDefault = nullptr,
+ const char **ArchFlag = nullptr);
+ static bool isValidArch(StringRef ArchFlag);
+ static ArrayRef<StringRef> getValidArchs();
+ static Triple getHostArch();
+
+ bool isRelocatableObject() const override;
+
+ StringRef mapDebugSectionName(StringRef Name) const override;
+
+ bool hasPageZeroSegment() const { return HasPageZeroSegment; }
+
+ static bool classof(const Binary *v) {
+ return v->isMachO();
+ }
+
+ static uint32_t
+ getVersionMinMajor(MachO::version_min_command &C, bool SDK) {
+ uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
+ return (VersionOrSDK >> 16) & 0xffff;
+ }
+
+ static uint32_t
+ getVersionMinMinor(MachO::version_min_command &C, bool SDK) {
+ uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
+ return (VersionOrSDK >> 8) & 0xff;
+ }
+
+ static uint32_t
+ getVersionMinUpdate(MachO::version_min_command &C, bool SDK) {
+ uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
+ return VersionOrSDK & 0xff;
+ }
+
+ static std::string getBuildPlatform(uint32_t platform) {
+ switch (platform) {
+ case MachO::PLATFORM_MACOS: return "macos";
+ case MachO::PLATFORM_IOS: return "ios";
+ case MachO::PLATFORM_TVOS: return "tvos";
+ case MachO::PLATFORM_WATCHOS: return "watchos";
+ case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
+ case MachO::PLATFORM_MACCATALYST: return "macCatalyst";
+ case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator";
+ case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator";
+ case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator";
case MachO::PLATFORM_DRIVERKIT: return "driverkit";
- default:
- std::string ret;
- raw_string_ostream ss(ret);
- ss << format_hex(platform, 8, true);
- return ss.str();
- }
- }
-
- static std::string getBuildTool(uint32_t tools) {
- switch (tools) {
- case MachO::TOOL_CLANG: return "clang";
- case MachO::TOOL_SWIFT: return "swift";
- case MachO::TOOL_LD: return "ld";
- default:
- std::string ret;
- raw_string_ostream ss(ret);
- ss << format_hex(tools, 8, true);
- return ss.str();
- }
- }
-
- static std::string getVersionString(uint32_t version) {
- uint32_t major = (version >> 16) & 0xffff;
- uint32_t minor = (version >> 8) & 0xff;
- uint32_t update = version & 0xff;
-
- SmallString<32> Version;
- Version = utostr(major) + "." + utostr(minor);
- if (update != 0)
- Version += "." + utostr(update);
- return std::string(std::string(Version.str()));
- }
-
-private:
- MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
- Error &Err, uint32_t UniversalCputype = 0,
- uint32_t UniversalIndex = 0);
-
- uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
-
- union {
- MachO::mach_header_64 Header64;
- MachO::mach_header Header;
- };
- using SectionList = SmallVector<const char*, 1>;
- SectionList Sections;
- using LibraryList = SmallVector<const char*, 1>;
- LibraryList Libraries;
- LoadCommandList LoadCommands;
- using LibraryShortName = SmallVector<StringRef, 1>;
- using BuildToolList = SmallVector<const char*, 1>;
- BuildToolList BuildTools;
- mutable LibraryShortName LibrariesShortNames;
- std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
- const char *SymtabLoadCmd = nullptr;
- const char *DysymtabLoadCmd = nullptr;
- const char *DataInCodeLoadCmd = nullptr;
- const char *LinkOptHintsLoadCmd = nullptr;
- const char *DyldInfoLoadCmd = nullptr;
- const char *UuidLoadCmd = nullptr;
- bool HasPageZeroSegment = false;
-};
-
-/// DiceRef
-inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner)
- : DicePimpl(DiceP) , OwningObject(Owner) {}
-
-inline bool DiceRef::operator==(const DiceRef &Other) const {
- return DicePimpl == Other.DicePimpl;
-}
-
-inline bool DiceRef::operator<(const DiceRef &Other) const {
- return DicePimpl < Other.DicePimpl;
-}
-
-inline void DiceRef::moveNext() {
- const MachO::data_in_code_entry *P =
- reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
- DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
-}
-
-// Since a Mach-O data in code reference, a DiceRef, can only be created when
-// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
-// the methods that get the values of the fields of the reference.
-
-inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
- const MachOObjectFile *MachOOF =
- static_cast<const MachOObjectFile *>(OwningObject);
- MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
- Result = Dice.offset;
- return std::error_code();
-}
-
-inline std::error_code DiceRef::getLength(uint16_t &Result) const {
- const MachOObjectFile *MachOOF =
- static_cast<const MachOObjectFile *>(OwningObject);
- MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
- Result = Dice.length;
- return std::error_code();
-}
-
-inline std::error_code DiceRef::getKind(uint16_t &Result) const {
- const MachOObjectFile *MachOOF =
- static_cast<const MachOObjectFile *>(OwningObject);
- MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
- Result = Dice.kind;
- return std::error_code();
-}
-
-inline DataRefImpl DiceRef::getRawDataRefImpl() const {
- return DicePimpl;
-}
-
-inline const ObjectFile *DiceRef::getObjectFile() const {
- return OwningObject;
-}
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_MACHO_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+ default:
+ std::string ret;
+ raw_string_ostream ss(ret);
+ ss << format_hex(platform, 8, true);
+ return ss.str();
+ }
+ }
+
+ static std::string getBuildTool(uint32_t tools) {
+ switch (tools) {
+ case MachO::TOOL_CLANG: return "clang";
+ case MachO::TOOL_SWIFT: return "swift";
+ case MachO::TOOL_LD: return "ld";
+ default:
+ std::string ret;
+ raw_string_ostream ss(ret);
+ ss << format_hex(tools, 8, true);
+ return ss.str();
+ }
+ }
+
+ static std::string getVersionString(uint32_t version) {
+ uint32_t major = (version >> 16) & 0xffff;
+ uint32_t minor = (version >> 8) & 0xff;
+ uint32_t update = version & 0xff;
+
+ SmallString<32> Version;
+ Version = utostr(major) + "." + utostr(minor);
+ if (update != 0)
+ Version += "." + utostr(update);
+ return std::string(std::string(Version.str()));
+ }
+
+private:
+ MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
+ Error &Err, uint32_t UniversalCputype = 0,
+ uint32_t UniversalIndex = 0);
+
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+
+ union {
+ MachO::mach_header_64 Header64;
+ MachO::mach_header Header;
+ };
+ using SectionList = SmallVector<const char*, 1>;
+ SectionList Sections;
+ using LibraryList = SmallVector<const char*, 1>;
+ LibraryList Libraries;
+ LoadCommandList LoadCommands;
+ using LibraryShortName = SmallVector<StringRef, 1>;
+ using BuildToolList = SmallVector<const char*, 1>;
+ BuildToolList BuildTools;
+ mutable LibraryShortName LibrariesShortNames;
+ std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
+ const char *SymtabLoadCmd = nullptr;
+ const char *DysymtabLoadCmd = nullptr;
+ const char *DataInCodeLoadCmd = nullptr;
+ const char *LinkOptHintsLoadCmd = nullptr;
+ const char *DyldInfoLoadCmd = nullptr;
+ const char *UuidLoadCmd = nullptr;
+ bool HasPageZeroSegment = false;
+};
+
+/// DiceRef
+inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner)
+ : DicePimpl(DiceP) , OwningObject(Owner) {}
+
+inline bool DiceRef::operator==(const DiceRef &Other) const {
+ return DicePimpl == Other.DicePimpl;
+}
+
+inline bool DiceRef::operator<(const DiceRef &Other) const {
+ return DicePimpl < Other.DicePimpl;
+}
+
+inline void DiceRef::moveNext() {
+ const MachO::data_in_code_entry *P =
+ reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
+ DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
+}
+
+// Since a Mach-O data in code reference, a DiceRef, can only be created when
+// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
+// the methods that get the values of the fields of the reference.
+
+inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
+ const MachOObjectFile *MachOOF =
+ static_cast<const MachOObjectFile *>(OwningObject);
+ MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+ Result = Dice.offset;
+ return std::error_code();
+}
+
+inline std::error_code DiceRef::getLength(uint16_t &Result) const {
+ const MachOObjectFile *MachOOF =
+ static_cast<const MachOObjectFile *>(OwningObject);
+ MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+ Result = Dice.length;
+ return std::error_code();
+}
+
+inline std::error_code DiceRef::getKind(uint16_t &Result) const {
+ const MachOObjectFile *MachOOF =
+ static_cast<const MachOObjectFile *>(OwningObject);
+ MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
+ Result = Dice.kind;
+ return std::error_code();
+}
+
+inline DataRefImpl DiceRef::getRawDataRefImpl() const {
+ return DicePimpl;
+}
+
+inline const ObjectFile *DiceRef::getObjectFile() const {
+ return OwningObject;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MACHO_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h b/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h
index 2f34b6a71ba..089d4cdbd42 100644
--- a/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h
+++ b/contrib/libs/llvm12/include/llvm/Object/MachOUniversal.h
@@ -1,183 +1,183 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- MachOUniversal.h - Mach-O universal binaries -------------*- 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 Mach-O fat/universal binaries.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
-#define LLVM_OBJECT_MACHOUNIVERSAL_H
-
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/MachO.h"
-
-namespace llvm {
-class StringRef;
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- MachOUniversal.h - Mach-O universal binaries -------------*- 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 Mach-O fat/universal binaries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
+#define LLVM_OBJECT_MACHOUNIVERSAL_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/MachO.h"
+
+namespace llvm {
+class StringRef;
class Module;
class LLVMContext;
-
-namespace object {
+
+namespace object {
class IRObjectFile;
-
-class MachOUniversalBinary : public Binary {
- virtual void anchor();
-
- uint32_t Magic;
- uint32_t NumberOfObjects;
-public:
- static constexpr uint32_t MaxSectionAlignment = 15; /* 2**15 or 0x8000 */
-
- class ObjectForArch {
- const MachOUniversalBinary *Parent;
- /// Index of object in the universal binary.
- uint32_t Index;
- /// Descriptor of the object.
- MachO::fat_arch Header;
- MachO::fat_arch_64 Header64;
-
- public:
- ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
-
- void clear() {
- Parent = nullptr;
- Index = 0;
- }
-
- bool operator==(const ObjectForArch &Other) const {
- return (Parent == Other.Parent) && (Index == Other.Index);
- }
-
- ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
- uint32_t getCPUType() const {
- if (Parent->getMagic() == MachO::FAT_MAGIC)
- return Header.cputype;
- else // Parent->getMagic() == MachO::FAT_MAGIC_64
- return Header64.cputype;
- }
- uint32_t getCPUSubType() const {
- if (Parent->getMagic() == MachO::FAT_MAGIC)
- return Header.cpusubtype;
- else // Parent->getMagic() == MachO::FAT_MAGIC_64
- return Header64.cpusubtype;
- }
- uint64_t getOffset() const {
- if (Parent->getMagic() == MachO::FAT_MAGIC)
- return Header.offset;
- else // Parent->getMagic() == MachO::FAT_MAGIC_64
- return Header64.offset;
- }
- uint64_t getSize() const {
- if (Parent->getMagic() == MachO::FAT_MAGIC)
- return Header.size;
- else // Parent->getMagic() == MachO::FAT_MAGIC_64
- return Header64.size;
- }
- uint32_t getAlign() const {
- if (Parent->getMagic() == MachO::FAT_MAGIC)
- return Header.align;
- else // Parent->getMagic() == MachO::FAT_MAGIC_64
- return Header64.align;
- }
- uint32_t getReserved() const {
- if (Parent->getMagic() == MachO::FAT_MAGIC)
- return 0;
- else // Parent->getMagic() == MachO::FAT_MAGIC_64
- return Header64.reserved;
- }
- Triple getTriple() const {
- return MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType());
- }
- std::string getArchFlagName() const {
- const char *McpuDefault, *ArchFlag;
- MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType(),
- &McpuDefault, &ArchFlag);
- return ArchFlag ? ArchFlag : std::string();
- }
-
- Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
+
+class MachOUniversalBinary : public Binary {
+ virtual void anchor();
+
+ uint32_t Magic;
+ uint32_t NumberOfObjects;
+public:
+ static constexpr uint32_t MaxSectionAlignment = 15; /* 2**15 or 0x8000 */
+
+ class ObjectForArch {
+ const MachOUniversalBinary *Parent;
+ /// Index of object in the universal binary.
+ uint32_t Index;
+ /// Descriptor of the object.
+ MachO::fat_arch Header;
+ MachO::fat_arch_64 Header64;
+
+ public:
+ ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
+
+ void clear() {
+ Parent = nullptr;
+ Index = 0;
+ }
+
+ bool operator==(const ObjectForArch &Other) const {
+ return (Parent == Other.Parent) && (Index == Other.Index);
+ }
+
+ ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
+ uint32_t getCPUType() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.cputype;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.cputype;
+ }
+ uint32_t getCPUSubType() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.cpusubtype;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.cpusubtype;
+ }
+ uint64_t getOffset() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.offset;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.offset;
+ }
+ uint64_t getSize() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.size;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.size;
+ }
+ uint32_t getAlign() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return Header.align;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.align;
+ }
+ uint32_t getReserved() const {
+ if (Parent->getMagic() == MachO::FAT_MAGIC)
+ return 0;
+ else // Parent->getMagic() == MachO::FAT_MAGIC_64
+ return Header64.reserved;
+ }
+ Triple getTriple() const {
+ return MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType());
+ }
+ std::string getArchFlagName() const {
+ const char *McpuDefault, *ArchFlag;
+ MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType(),
+ &McpuDefault, &ArchFlag);
+ return ArchFlag ? ArchFlag : std::string();
+ }
+
+ Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
Expected<std::unique_ptr<IRObjectFile>>
getAsIRObject(LLVMContext &Ctx) const;
-
- Expected<std::unique_ptr<Archive>> getAsArchive() const;
- };
-
- class object_iterator {
- ObjectForArch Obj;
- public:
- object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
- const ObjectForArch *operator->() const { return &Obj; }
- const ObjectForArch &operator*() const { return Obj; }
-
- bool operator==(const object_iterator &Other) const {
- return Obj == Other.Obj;
- }
- bool operator!=(const object_iterator &Other) const {
- return !(*this == Other);
- }
-
- object_iterator& operator++() { // Preincrement
- Obj = Obj.getNext();
- return *this;
- }
- };
-
- MachOUniversalBinary(MemoryBufferRef Souce, Error &Err);
- static Expected<std::unique_ptr<MachOUniversalBinary>>
- create(MemoryBufferRef Source);
-
- object_iterator begin_objects() const {
- return ObjectForArch(this, 0);
- }
- object_iterator end_objects() const {
- return ObjectForArch(nullptr, 0);
- }
-
- iterator_range<object_iterator> objects() const {
- return make_range(begin_objects(), end_objects());
- }
-
- uint32_t getMagic() const { return Magic; }
- uint32_t getNumberOfObjects() const { return NumberOfObjects; }
-
- // Cast methods.
- static bool classof(Binary const *V) {
- return V->isMachOUniversalBinary();
- }
-
- Expected<ObjectForArch>
- getObjectForArch(StringRef ArchName) const;
-
- Expected<std::unique_ptr<MachOObjectFile>>
- getMachOObjectForArch(StringRef ArchName) const;
-
+
+ Expected<std::unique_ptr<Archive>> getAsArchive() const;
+ };
+
+ class object_iterator {
+ ObjectForArch Obj;
+ public:
+ object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
+ const ObjectForArch *operator->() const { return &Obj; }
+ const ObjectForArch &operator*() const { return Obj; }
+
+ bool operator==(const object_iterator &Other) const {
+ return Obj == Other.Obj;
+ }
+ bool operator!=(const object_iterator &Other) const {
+ return !(*this == Other);
+ }
+
+ object_iterator& operator++() { // Preincrement
+ Obj = Obj.getNext();
+ return *this;
+ }
+ };
+
+ MachOUniversalBinary(MemoryBufferRef Souce, Error &Err);
+ static Expected<std::unique_ptr<MachOUniversalBinary>>
+ create(MemoryBufferRef Source);
+
+ object_iterator begin_objects() const {
+ return ObjectForArch(this, 0);
+ }
+ object_iterator end_objects() const {
+ return ObjectForArch(nullptr, 0);
+ }
+
+ iterator_range<object_iterator> objects() const {
+ return make_range(begin_objects(), end_objects());
+ }
+
+ uint32_t getMagic() const { return Magic; }
+ uint32_t getNumberOfObjects() const { return NumberOfObjects; }
+
+ // Cast methods.
+ static bool classof(Binary const *V) {
+ return V->isMachOUniversalBinary();
+ }
+
+ Expected<ObjectForArch>
+ getObjectForArch(StringRef ArchName) const;
+
+ Expected<std::unique_ptr<MachOObjectFile>>
+ getMachOObjectForArch(StringRef ArchName) const;
+
Expected<std::unique_ptr<IRObjectFile>>
getIRObjectForArch(StringRef ArchName, LLVMContext &Ctx) const;
- Expected<std::unique_ptr<Archive>>
- getArchiveForArch(StringRef ArchName) const;
-};
-
-}
-}
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+ Expected<std::unique_ptr<Archive>>
+ getArchiveForArch(StringRef ArchName) const;
+};
+
+}
+}
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/Minidump.h b/contrib/libs/llvm12/include/llvm/Object/Minidump.h
index 7adc325663d..2b1867e6584 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Minidump.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Minidump.h
@@ -1,227 +1,227 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Minidump.h - Minidump object file implementation ---------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MINIDUMP_H
-#define LLVM_OBJECT_MINIDUMP_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/BinaryFormat/Minidump.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Support/Error.h"
-
-namespace llvm {
-namespace object {
-
-/// A class providing access to the contents of a minidump file.
-class MinidumpFile : public Binary {
-public:
- /// Construct a new MinidumpFile object from the given memory buffer. Returns
- /// an error if this file cannot be identified as a minidump file, or if its
- /// contents are badly corrupted (i.e. we cannot read the stream directory).
- static Expected<std::unique_ptr<MinidumpFile>> create(MemoryBufferRef Source);
-
- static bool classof(const Binary *B) { return B->isMinidump(); }
-
- /// Returns the contents of the minidump header.
- const minidump::Header &header() const { return Header; }
-
- /// Returns the list of streams (stream directory entries) in this file.
- ArrayRef<minidump::Directory> streams() const { return Streams; }
-
- /// Returns the raw contents of the stream given by the directory entry.
- ArrayRef<uint8_t> getRawStream(const minidump::Directory &Stream) const {
- return getData().slice(Stream.Location.RVA, Stream.Location.DataSize);
- }
-
- /// Returns the raw contents of the stream of the given type, or None if the
- /// file does not contain a stream of this type.
- Optional<ArrayRef<uint8_t>> getRawStream(minidump::StreamType Type) const;
-
- /// Returns the raw contents of an object given by the LocationDescriptor. An
- /// error is returned if the descriptor points outside of the minidump file.
- Expected<ArrayRef<uint8_t>>
- getRawData(minidump::LocationDescriptor Desc) const {
- return getDataSlice(getData(), Desc.RVA, Desc.DataSize);
- }
-
- /// Returns the minidump string at the given offset. An error is returned if
- /// we fail to parse the string, or the string is invalid UTF16.
- Expected<std::string> getString(size_t Offset) const;
-
- /// Returns the contents of the SystemInfo stream, cast to the appropriate
- /// type. An error is returned if the file does not contain this stream, or
- /// the stream is smaller than the size of the SystemInfo structure. The
- /// internal consistency of the stream is not checked in any way.
- Expected<const minidump::SystemInfo &> getSystemInfo() const {
- return getStream<minidump::SystemInfo>(minidump::StreamType::SystemInfo);
- }
-
- /// Returns the module list embedded in the ModuleList stream. An error is
- /// returned if the file does not contain this stream, or if the stream is
- /// not large enough to contain the number of modules declared in the stream
- /// header. The consistency of the Module entries themselves is not checked in
- /// any way.
- Expected<ArrayRef<minidump::Module>> getModuleList() const {
- return getListStream<minidump::Module>(minidump::StreamType::ModuleList);
- }
-
- /// Returns the thread list embedded in the ThreadList stream. An error is
- /// returned if the file does not contain this stream, or if the stream is
- /// not large enough to contain the number of threads declared in the stream
- /// header. The consistency of the Thread entries themselves is not checked in
- /// any way.
- Expected<ArrayRef<minidump::Thread>> getThreadList() const {
- return getListStream<minidump::Thread>(minidump::StreamType::ThreadList);
- }
-
- /// Returns the contents of the Exception stream. An error is returned if the
- /// file does not contain this stream, or the stream is smaller than the size
- /// of the ExceptionStream structure. The internal consistency of the stream
- /// is not checked in any way.
- Expected<const minidump::ExceptionStream &> getExceptionStream() const {
- return getStream<minidump::ExceptionStream>(
- minidump::StreamType::Exception);
- }
-
- /// Returns the list of descriptors embedded in the MemoryList stream. The
- /// descriptors provide the content of interesting regions of memory at the
- /// time the minidump was taken. An error is returned if the file does not
- /// contain this stream, or if the stream is not large enough to contain the
- /// number of memory descriptors declared in the stream header. The
- /// consistency of the MemoryDescriptor entries themselves is not checked in
- /// any way.
- Expected<ArrayRef<minidump::MemoryDescriptor>> getMemoryList() const {
- return getListStream<minidump::MemoryDescriptor>(
- minidump::StreamType::MemoryList);
- }
-
- class MemoryInfoIterator
- : public iterator_facade_base<MemoryInfoIterator,
- std::forward_iterator_tag,
- minidump::MemoryInfo> {
- public:
- MemoryInfoIterator(ArrayRef<uint8_t> Storage, size_t Stride)
- : Storage(Storage), Stride(Stride) {
- assert(Storage.size() % Stride == 0);
- }
-
- bool operator==(const MemoryInfoIterator &R) const {
- return Storage.size() == R.Storage.size();
- }
-
- const minidump::MemoryInfo &operator*() const {
- assert(Storage.size() >= sizeof(minidump::MemoryInfo));
- return *reinterpret_cast<const minidump::MemoryInfo *>(Storage.data());
- }
-
- MemoryInfoIterator &operator++() {
- Storage = Storage.drop_front(Stride);
- return *this;
- }
-
- private:
- ArrayRef<uint8_t> Storage;
- size_t Stride;
- };
-
- /// Returns the list of descriptors embedded in the MemoryInfoList stream. The
- /// descriptors provide properties (e.g. permissions) of interesting regions
- /// of memory at the time the minidump was taken. An error is returned if the
- /// file does not contain this stream, or if the stream is not large enough to
- /// contain the number of memory descriptors declared in the stream header.
- /// The consistency of the MemoryInfoList entries themselves is not checked
- /// in any way.
- Expected<iterator_range<MemoryInfoIterator>> getMemoryInfoList() const;
-
-private:
- static Error createError(StringRef Str) {
- return make_error<GenericBinaryError>(Str, object_error::parse_failed);
- }
-
- static Error createEOFError() {
- return make_error<GenericBinaryError>("Unexpected EOF",
- object_error::unexpected_eof);
- }
-
- /// Return a slice of the given data array, with bounds checking.
- static Expected<ArrayRef<uint8_t>> getDataSlice(ArrayRef<uint8_t> Data,
- size_t Offset, size_t Size);
-
- /// Return the slice of the given data array as an array of objects of the
- /// given type. The function checks that the input array is large enough to
- /// contain the correct number of objects of the given type.
- template <typename T>
- static Expected<ArrayRef<T>> getDataSliceAs(ArrayRef<uint8_t> Data,
- size_t Offset, size_t Count);
-
- MinidumpFile(MemoryBufferRef Source, const minidump::Header &Header,
- ArrayRef<minidump::Directory> Streams,
- DenseMap<minidump::StreamType, std::size_t> StreamMap)
- : Binary(ID_Minidump, Source), Header(Header), Streams(Streams),
- StreamMap(std::move(StreamMap)) {}
-
- ArrayRef<uint8_t> getData() const {
- return arrayRefFromStringRef(Data.getBuffer());
- }
-
- /// Return the stream of the given type, cast to the appropriate type. Checks
- /// that the stream is large enough to hold an object of this type.
- template <typename T>
- Expected<const T &> getStream(minidump::StreamType Stream) const;
-
- /// Return the contents of a stream which contains a list of fixed-size items,
- /// prefixed by the list size.
- template <typename T>
- Expected<ArrayRef<T>> getListStream(minidump::StreamType Stream) const;
-
- const minidump::Header &Header;
- ArrayRef<minidump::Directory> Streams;
- DenseMap<minidump::StreamType, std::size_t> StreamMap;
-};
-
-template <typename T>
-Expected<const T &> MinidumpFile::getStream(minidump::StreamType Type) const {
- if (Optional<ArrayRef<uint8_t>> Stream = getRawStream(Type)) {
- if (Stream->size() >= sizeof(T))
- return *reinterpret_cast<const T *>(Stream->data());
- return createEOFError();
- }
- return createError("No such stream");
-}
-
-template <typename T>
-Expected<ArrayRef<T>> MinidumpFile::getDataSliceAs(ArrayRef<uint8_t> Data,
- size_t Offset,
- size_t Count) {
- // Check for overflow.
- if (Count > std::numeric_limits<size_t>::max() / sizeof(T))
- return createEOFError();
- Expected<ArrayRef<uint8_t>> Slice =
- getDataSlice(Data, Offset, sizeof(T) * Count);
- if (!Slice)
- return Slice.takeError();
- return ArrayRef<T>(reinterpret_cast<const T *>(Slice->data()), Count);
-}
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_MINIDUMP_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Minidump.h - Minidump object file implementation ---------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MINIDUMP_H
+#define LLVM_OBJECT_MINIDUMP_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/BinaryFormat/Minidump.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace object {
+
+/// A class providing access to the contents of a minidump file.
+class MinidumpFile : public Binary {
+public:
+ /// Construct a new MinidumpFile object from the given memory buffer. Returns
+ /// an error if this file cannot be identified as a minidump file, or if its
+ /// contents are badly corrupted (i.e. we cannot read the stream directory).
+ static Expected<std::unique_ptr<MinidumpFile>> create(MemoryBufferRef Source);
+
+ static bool classof(const Binary *B) { return B->isMinidump(); }
+
+ /// Returns the contents of the minidump header.
+ const minidump::Header &header() const { return Header; }
+
+ /// Returns the list of streams (stream directory entries) in this file.
+ ArrayRef<minidump::Directory> streams() const { return Streams; }
+
+ /// Returns the raw contents of the stream given by the directory entry.
+ ArrayRef<uint8_t> getRawStream(const minidump::Directory &Stream) const {
+ return getData().slice(Stream.Location.RVA, Stream.Location.DataSize);
+ }
+
+ /// Returns the raw contents of the stream of the given type, or None if the
+ /// file does not contain a stream of this type.
+ Optional<ArrayRef<uint8_t>> getRawStream(minidump::StreamType Type) const;
+
+ /// Returns the raw contents of an object given by the LocationDescriptor. An
+ /// error is returned if the descriptor points outside of the minidump file.
+ Expected<ArrayRef<uint8_t>>
+ getRawData(minidump::LocationDescriptor Desc) const {
+ return getDataSlice(getData(), Desc.RVA, Desc.DataSize);
+ }
+
+ /// Returns the minidump string at the given offset. An error is returned if
+ /// we fail to parse the string, or the string is invalid UTF16.
+ Expected<std::string> getString(size_t Offset) const;
+
+ /// Returns the contents of the SystemInfo stream, cast to the appropriate
+ /// type. An error is returned if the file does not contain this stream, or
+ /// the stream is smaller than the size of the SystemInfo structure. The
+ /// internal consistency of the stream is not checked in any way.
+ Expected<const minidump::SystemInfo &> getSystemInfo() const {
+ return getStream<minidump::SystemInfo>(minidump::StreamType::SystemInfo);
+ }
+
+ /// Returns the module list embedded in the ModuleList stream. An error is
+ /// returned if the file does not contain this stream, or if the stream is
+ /// not large enough to contain the number of modules declared in the stream
+ /// header. The consistency of the Module entries themselves is not checked in
+ /// any way.
+ Expected<ArrayRef<minidump::Module>> getModuleList() const {
+ return getListStream<minidump::Module>(minidump::StreamType::ModuleList);
+ }
+
+ /// Returns the thread list embedded in the ThreadList stream. An error is
+ /// returned if the file does not contain this stream, or if the stream is
+ /// not large enough to contain the number of threads declared in the stream
+ /// header. The consistency of the Thread entries themselves is not checked in
+ /// any way.
+ Expected<ArrayRef<minidump::Thread>> getThreadList() const {
+ return getListStream<minidump::Thread>(minidump::StreamType::ThreadList);
+ }
+
+ /// Returns the contents of the Exception stream. An error is returned if the
+ /// file does not contain this stream, or the stream is smaller than the size
+ /// of the ExceptionStream structure. The internal consistency of the stream
+ /// is not checked in any way.
+ Expected<const minidump::ExceptionStream &> getExceptionStream() const {
+ return getStream<minidump::ExceptionStream>(
+ minidump::StreamType::Exception);
+ }
+
+ /// Returns the list of descriptors embedded in the MemoryList stream. The
+ /// descriptors provide the content of interesting regions of memory at the
+ /// time the minidump was taken. An error is returned if the file does not
+ /// contain this stream, or if the stream is not large enough to contain the
+ /// number of memory descriptors declared in the stream header. The
+ /// consistency of the MemoryDescriptor entries themselves is not checked in
+ /// any way.
+ Expected<ArrayRef<minidump::MemoryDescriptor>> getMemoryList() const {
+ return getListStream<minidump::MemoryDescriptor>(
+ minidump::StreamType::MemoryList);
+ }
+
+ class MemoryInfoIterator
+ : public iterator_facade_base<MemoryInfoIterator,
+ std::forward_iterator_tag,
+ minidump::MemoryInfo> {
+ public:
+ MemoryInfoIterator(ArrayRef<uint8_t> Storage, size_t Stride)
+ : Storage(Storage), Stride(Stride) {
+ assert(Storage.size() % Stride == 0);
+ }
+
+ bool operator==(const MemoryInfoIterator &R) const {
+ return Storage.size() == R.Storage.size();
+ }
+
+ const minidump::MemoryInfo &operator*() const {
+ assert(Storage.size() >= sizeof(minidump::MemoryInfo));
+ return *reinterpret_cast<const minidump::MemoryInfo *>(Storage.data());
+ }
+
+ MemoryInfoIterator &operator++() {
+ Storage = Storage.drop_front(Stride);
+ return *this;
+ }
+
+ private:
+ ArrayRef<uint8_t> Storage;
+ size_t Stride;
+ };
+
+ /// Returns the list of descriptors embedded in the MemoryInfoList stream. The
+ /// descriptors provide properties (e.g. permissions) of interesting regions
+ /// of memory at the time the minidump was taken. An error is returned if the
+ /// file does not contain this stream, or if the stream is not large enough to
+ /// contain the number of memory descriptors declared in the stream header.
+ /// The consistency of the MemoryInfoList entries themselves is not checked
+ /// in any way.
+ Expected<iterator_range<MemoryInfoIterator>> getMemoryInfoList() const;
+
+private:
+ static Error createError(StringRef Str) {
+ return make_error<GenericBinaryError>(Str, object_error::parse_failed);
+ }
+
+ static Error createEOFError() {
+ return make_error<GenericBinaryError>("Unexpected EOF",
+ object_error::unexpected_eof);
+ }
+
+ /// Return a slice of the given data array, with bounds checking.
+ static Expected<ArrayRef<uint8_t>> getDataSlice(ArrayRef<uint8_t> Data,
+ size_t Offset, size_t Size);
+
+ /// Return the slice of the given data array as an array of objects of the
+ /// given type. The function checks that the input array is large enough to
+ /// contain the correct number of objects of the given type.
+ template <typename T>
+ static Expected<ArrayRef<T>> getDataSliceAs(ArrayRef<uint8_t> Data,
+ size_t Offset, size_t Count);
+
+ MinidumpFile(MemoryBufferRef Source, const minidump::Header &Header,
+ ArrayRef<minidump::Directory> Streams,
+ DenseMap<minidump::StreamType, std::size_t> StreamMap)
+ : Binary(ID_Minidump, Source), Header(Header), Streams(Streams),
+ StreamMap(std::move(StreamMap)) {}
+
+ ArrayRef<uint8_t> getData() const {
+ return arrayRefFromStringRef(Data.getBuffer());
+ }
+
+ /// Return the stream of the given type, cast to the appropriate type. Checks
+ /// that the stream is large enough to hold an object of this type.
+ template <typename T>
+ Expected<const T &> getStream(minidump::StreamType Stream) const;
+
+ /// Return the contents of a stream which contains a list of fixed-size items,
+ /// prefixed by the list size.
+ template <typename T>
+ Expected<ArrayRef<T>> getListStream(minidump::StreamType Stream) const;
+
+ const minidump::Header &Header;
+ ArrayRef<minidump::Directory> Streams;
+ DenseMap<minidump::StreamType, std::size_t> StreamMap;
+};
+
+template <typename T>
+Expected<const T &> MinidumpFile::getStream(minidump::StreamType Type) const {
+ if (Optional<ArrayRef<uint8_t>> Stream = getRawStream(Type)) {
+ if (Stream->size() >= sizeof(T))
+ return *reinterpret_cast<const T *>(Stream->data());
+ return createEOFError();
+ }
+ return createError("No such stream");
+}
+
+template <typename T>
+Expected<ArrayRef<T>> MinidumpFile::getDataSliceAs(ArrayRef<uint8_t> Data,
+ size_t Offset,
+ size_t Count) {
+ // Check for overflow.
+ if (Count > std::numeric_limits<size_t>::max() / sizeof(T))
+ return createEOFError();
+ Expected<ArrayRef<uint8_t>> Slice =
+ getDataSlice(Data, Offset, sizeof(T) * Count);
+ if (!Slice)
+ return Slice.takeError();
+ return ArrayRef<T>(reinterpret_cast<const T *>(Slice->data()), Count);
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MINIDUMP_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/ModuleSymbolTable.h b/contrib/libs/llvm12/include/llvm/Object/ModuleSymbolTable.h
index b661386eebb..0021f4c5cc8 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ModuleSymbolTable.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ModuleSymbolTable.h
@@ -1,84 +1,84 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ModuleSymbolTable.h - symbol table for in-memory IR ------*- 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 class represents a symbol table built from in-memory IR. It provides
-// access to GlobalValues and should only be used if such access is required
-// (e.g. in the LTO implementation).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H
-#define LLVM_OBJECT_MODULESYMBOLTABLE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/Allocator.h"
-#include <cstdint>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace llvm {
-
-class GlobalValue;
-class Module;
-
-class ModuleSymbolTable {
-public:
- using AsmSymbol = std::pair<std::string, uint32_t>;
- using Symbol = PointerUnion<GlobalValue *, AsmSymbol *>;
-
-private:
- Module *FirstMod = nullptr;
-
- SpecificBumpPtrAllocator<AsmSymbol> AsmSymbols;
- std::vector<Symbol> SymTab;
- Mangler Mang;
-
-public:
- ArrayRef<Symbol> symbols() const { return SymTab; }
- void addModule(Module *M);
-
- void printSymbolName(raw_ostream &OS, Symbol S) const;
- uint32_t getSymbolFlags(Symbol S) const;
-
- /// Parse inline ASM and collect the symbols that are defined or referenced in
- /// the current module.
- ///
- /// For each found symbol, call \p AsmSymbol with the name of the symbol found
- /// and the associated flags.
- static void CollectAsmSymbols(
- const Module &M,
- function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
-
- /// Parse inline ASM and collect the symvers directives that are defined in
- /// the current module.
- ///
- /// For each found symbol, call \p AsmSymver with the name of the symbol and
- /// its alias.
- static void
- CollectAsmSymvers(const Module &M,
- function_ref<void(StringRef, StringRef)> AsmSymver);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_MODULESYMBOLTABLE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ModuleSymbolTable.h - symbol table for in-memory IR ------*- 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 class represents a symbol table built from in-memory IR. It provides
+// access to GlobalValues and should only be used if such access is required
+// (e.g. in the LTO implementation).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H
+#define LLVM_OBJECT_MODULESYMBOLTABLE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
+#include <cstdint>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class GlobalValue;
+class Module;
+
+class ModuleSymbolTable {
+public:
+ using AsmSymbol = std::pair<std::string, uint32_t>;
+ using Symbol = PointerUnion<GlobalValue *, AsmSymbol *>;
+
+private:
+ Module *FirstMod = nullptr;
+
+ SpecificBumpPtrAllocator<AsmSymbol> AsmSymbols;
+ std::vector<Symbol> SymTab;
+ Mangler Mang;
+
+public:
+ ArrayRef<Symbol> symbols() const { return SymTab; }
+ void addModule(Module *M);
+
+ void printSymbolName(raw_ostream &OS, Symbol S) const;
+ uint32_t getSymbolFlags(Symbol S) const;
+
+ /// Parse inline ASM and collect the symbols that are defined or referenced in
+ /// the current module.
+ ///
+ /// For each found symbol, call \p AsmSymbol with the name of the symbol found
+ /// and the associated flags.
+ static void CollectAsmSymbols(
+ const Module &M,
+ function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
+
+ /// Parse inline ASM and collect the symvers directives that are defined in
+ /// the current module.
+ ///
+ /// For each found symbol, call \p AsmSymver with the name of the symbol and
+ /// its alias.
+ static void
+ CollectAsmSymvers(const Module &M,
+ function_ref<void(StringRef, StringRef)> AsmSymver);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_MODULESYMBOLTABLE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h
index 7f9ec78c1d4..76e157182d4 100644
--- a/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/ObjectFile.h
@@ -1,603 +1,603 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- ObjectFile.h - File format independent object file -------*- 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 a file format independent ObjectFile class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_OBJECTFILE_H
-#define LLVM_OBJECT_OBJECTFILE_H
-
-#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/Magic.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cassert>
-#include <cstdint>
-#include <memory>
-#include <system_error>
-
-namespace llvm {
-
-class ARMAttributeParser;
-class SubtargetFeatures;
-
-namespace object {
-
-class COFFObjectFile;
-class MachOObjectFile;
-class ObjectFile;
-class SectionRef;
-class SymbolRef;
-class symbol_iterator;
-class WasmObjectFile;
-
-using section_iterator = content_iterator<SectionRef>;
-
-/// This is a value type class that represents a single relocation in the list
-/// of relocations in the object file.
-class RelocationRef {
- DataRefImpl RelocationPimpl;
- const ObjectFile *OwningObject = nullptr;
-
-public:
- RelocationRef() = default;
- RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
-
- bool operator==(const RelocationRef &Other) const;
-
- void moveNext();
-
- uint64_t getOffset() const;
- symbol_iterator getSymbol() const;
- uint64_t getType() const;
-
- /// Get a string that represents the type of this relocation.
- ///
- /// This is for display purposes only.
- void getTypeName(SmallVectorImpl<char> &Result) const;
-
- DataRefImpl getRawDataRefImpl() const;
- const ObjectFile *getObject() const;
-};
-
-using relocation_iterator = content_iterator<RelocationRef>;
-
-/// This is a value type class that represents a single section in the list of
-/// sections in the object file.
-class SectionRef {
- friend class SymbolRef;
-
- DataRefImpl SectionPimpl;
- const ObjectFile *OwningObject = nullptr;
-
-public:
- SectionRef() = default;
- SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
-
- bool operator==(const SectionRef &Other) const;
- bool operator!=(const SectionRef &Other) const;
- bool operator<(const SectionRef &Other) const;
-
- void moveNext();
-
- Expected<StringRef> getName() const;
- uint64_t getAddress() const;
- uint64_t getIndex() const;
- uint64_t getSize() const;
- Expected<StringRef> getContents() const;
-
- /// Get the alignment of this section as the actual value (not log 2).
- uint64_t getAlignment() const;
-
- bool isCompressed() const;
- /// Whether this section contains instructions.
- bool isText() const;
- /// Whether this section contains data, not instructions.
- bool isData() const;
- /// Whether this section contains BSS uninitialized data.
- bool isBSS() const;
- bool isVirtual() const;
- bool isBitcode() const;
- bool isStripped() const;
-
- /// Whether this section will be placed in the text segment, according to the
- /// Berkeley size format. This is true if the section is allocatable, and
- /// contains either code or readonly data.
- bool isBerkeleyText() const;
- /// Whether this section will be placed in the data segment, according to the
- /// Berkeley size format. This is true if the section is allocatable and
- /// contains data (e.g. PROGBITS), but is not text.
- bool isBerkeleyData() const;
-
- /// Whether this section is a debug section.
- bool isDebugSection(StringRef SectionName) const;
-
- bool containsSymbol(SymbolRef S) const;
-
- relocation_iterator relocation_begin() const;
- relocation_iterator relocation_end() const;
- iterator_range<relocation_iterator> relocations() const {
- return make_range(relocation_begin(), relocation_end());
- }
- Expected<section_iterator> getRelocatedSection() const;
-
- DataRefImpl getRawDataRefImpl() const;
- const ObjectFile *getObject() const;
-};
-
-struct SectionedAddress {
- const static uint64_t UndefSection = UINT64_MAX;
-
- uint64_t Address = 0;
- uint64_t SectionIndex = UndefSection;
-};
-
-inline bool operator<(const SectionedAddress &LHS,
- const SectionedAddress &RHS) {
- return std::tie(LHS.SectionIndex, LHS.Address) <
- std::tie(RHS.SectionIndex, RHS.Address);
-}
-
-inline bool operator==(const SectionedAddress &LHS,
- const SectionedAddress &RHS) {
- return std::tie(LHS.SectionIndex, LHS.Address) ==
- std::tie(RHS.SectionIndex, RHS.Address);
-}
-
-raw_ostream &operator<<(raw_ostream &OS, const SectionedAddress &Addr);
-
-/// This is a value type class that represents a single symbol in the list of
-/// symbols in the object file.
-class SymbolRef : public BasicSymbolRef {
- friend class SectionRef;
-
-public:
- enum Type {
- ST_Unknown, // Type not specified
- ST_Data,
- ST_Debug,
- ST_File,
- ST_Function,
- ST_Other
- };
-
- SymbolRef() = default;
- SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
- SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
- assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
- }
-
- Expected<StringRef> getName() const;
- /// Returns the symbol virtual address (i.e. address at which it will be
- /// mapped).
- Expected<uint64_t> getAddress() const;
-
- /// Return the value of the symbol depending on the object this can be an
- /// offset or a virtual address.
- Expected<uint64_t> getValue() const;
-
- /// Get the alignment of this symbol as the actual value (not log 2).
- uint32_t getAlignment() const;
- uint64_t getCommonSize() const;
- Expected<SymbolRef::Type> getType() const;
-
- /// Get section this symbol is defined in reference to. Result is
- /// end_sections() if it is undefined or is an absolute symbol.
- Expected<section_iterator> getSection() const;
-
- const ObjectFile *getObject() const;
-};
-
-class symbol_iterator : public basic_symbol_iterator {
-public:
- symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
- symbol_iterator(const basic_symbol_iterator &B)
- : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
- cast<ObjectFile>(B->getObject()))) {}
-
- const SymbolRef *operator->() const {
- const BasicSymbolRef &P = basic_symbol_iterator::operator *();
- return static_cast<const SymbolRef*>(&P);
- }
-
- const SymbolRef &operator*() const {
- const BasicSymbolRef &P = basic_symbol_iterator::operator *();
- return static_cast<const SymbolRef&>(P);
- }
-};
-
-/// This class is the base class for all object file types. Concrete instances
-/// of this object are created by createObjectFile, which figures out which type
-/// to create.
-class ObjectFile : public SymbolicFile {
- virtual void anchor();
-
-protected:
- ObjectFile(unsigned int Type, MemoryBufferRef Source);
-
- const uint8_t *base() const {
- return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
- }
-
- // These functions are for SymbolRef to call internally. The main goal of
- // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
- // entry in the memory mapped object file. SymbolPimpl cannot contain any
- // virtual functions because then it could not point into the memory mapped
- // file.
- //
- // Implementations assume that the DataRefImpl is valid and has not been
- // modified externally. It's UB otherwise.
- friend class SymbolRef;
-
- virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
- Error printSymbolName(raw_ostream &OS,
- DataRefImpl Symb) const override;
- virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
- virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
- virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
- virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
- virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
- virtual Expected<section_iterator>
- getSymbolSection(DataRefImpl Symb) const = 0;
-
- // Same as above for SectionRef.
- friend class SectionRef;
-
- virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
- virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
- virtual Expected<ArrayRef<uint8_t>>
- getSectionContents(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
- virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
- virtual bool isSectionText(DataRefImpl Sec) const = 0;
- virtual bool isSectionData(DataRefImpl Sec) const = 0;
- virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
- // A section is 'virtual' if its contents aren't present in the object image.
- virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
- virtual bool isSectionBitcode(DataRefImpl Sec) const;
- virtual bool isSectionStripped(DataRefImpl Sec) const;
- virtual bool isBerkeleyText(DataRefImpl Sec) const;
- virtual bool isBerkeleyData(DataRefImpl Sec) const;
- virtual bool isDebugSection(StringRef SectionName) const;
- virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
- virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
- virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
-
- // Same as above for RelocationRef.
- friend class RelocationRef;
- virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
- virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
- virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
- virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
- virtual void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const = 0;
-
- Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
-
-public:
- ObjectFile() = delete;
- ObjectFile(const ObjectFile &other) = delete;
-
- uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
- Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
- if (!SymbolFlagsOrErr)
- // TODO: Actually report errors helpfully.
- report_fatal_error(SymbolFlagsOrErr.takeError());
- assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
- return getCommonSymbolSizeImpl(Symb);
- }
-
- virtual std::vector<SectionRef> dynamic_relocation_sections() const {
- return std::vector<SectionRef>();
- }
-
- using symbol_iterator_range = iterator_range<symbol_iterator>;
- symbol_iterator_range symbols() const {
- return symbol_iterator_range(symbol_begin(), symbol_end());
- }
-
- virtual section_iterator section_begin() const = 0;
- virtual section_iterator section_end() const = 0;
-
- using section_iterator_range = iterator_range<section_iterator>;
- section_iterator_range sections() const {
- return section_iterator_range(section_begin(), section_end());
- }
-
- /// The number of bytes used to represent an address in this object
- /// file format.
- virtual uint8_t getBytesInAddress() const = 0;
-
- virtual StringRef getFileFormatName() const = 0;
- virtual Triple::ArchType getArch() const = 0;
- virtual SubtargetFeatures getFeatures() const = 0;
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- ObjectFile.h - File format independent object file -------*- 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 a file format independent ObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_OBJECTFILE_H
+#define LLVM_OBJECT_OBJECTFILE_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+
+class ARMAttributeParser;
+class SubtargetFeatures;
+
+namespace object {
+
+class COFFObjectFile;
+class MachOObjectFile;
+class ObjectFile;
+class SectionRef;
+class SymbolRef;
+class symbol_iterator;
+class WasmObjectFile;
+
+using section_iterator = content_iterator<SectionRef>;
+
+/// This is a value type class that represents a single relocation in the list
+/// of relocations in the object file.
+class RelocationRef {
+ DataRefImpl RelocationPimpl;
+ const ObjectFile *OwningObject = nullptr;
+
+public:
+ RelocationRef() = default;
+ RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
+
+ bool operator==(const RelocationRef &Other) const;
+
+ void moveNext();
+
+ uint64_t getOffset() const;
+ symbol_iterator getSymbol() const;
+ uint64_t getType() const;
+
+ /// Get a string that represents the type of this relocation.
+ ///
+ /// This is for display purposes only.
+ void getTypeName(SmallVectorImpl<char> &Result) const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const ObjectFile *getObject() const;
+};
+
+using relocation_iterator = content_iterator<RelocationRef>;
+
+/// This is a value type class that represents a single section in the list of
+/// sections in the object file.
+class SectionRef {
+ friend class SymbolRef;
+
+ DataRefImpl SectionPimpl;
+ const ObjectFile *OwningObject = nullptr;
+
+public:
+ SectionRef() = default;
+ SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
+
+ bool operator==(const SectionRef &Other) const;
+ bool operator!=(const SectionRef &Other) const;
+ bool operator<(const SectionRef &Other) const;
+
+ void moveNext();
+
+ Expected<StringRef> getName() const;
+ uint64_t getAddress() const;
+ uint64_t getIndex() const;
+ uint64_t getSize() const;
+ Expected<StringRef> getContents() const;
+
+ /// Get the alignment of this section as the actual value (not log 2).
+ uint64_t getAlignment() const;
+
+ bool isCompressed() const;
+ /// Whether this section contains instructions.
+ bool isText() const;
+ /// Whether this section contains data, not instructions.
+ bool isData() const;
+ /// Whether this section contains BSS uninitialized data.
+ bool isBSS() const;
+ bool isVirtual() const;
+ bool isBitcode() const;
+ bool isStripped() const;
+
+ /// Whether this section will be placed in the text segment, according to the
+ /// Berkeley size format. This is true if the section is allocatable, and
+ /// contains either code or readonly data.
+ bool isBerkeleyText() const;
+ /// Whether this section will be placed in the data segment, according to the
+ /// Berkeley size format. This is true if the section is allocatable and
+ /// contains data (e.g. PROGBITS), but is not text.
+ bool isBerkeleyData() const;
+
+ /// Whether this section is a debug section.
+ bool isDebugSection(StringRef SectionName) const;
+
+ bool containsSymbol(SymbolRef S) const;
+
+ relocation_iterator relocation_begin() const;
+ relocation_iterator relocation_end() const;
+ iterator_range<relocation_iterator> relocations() const {
+ return make_range(relocation_begin(), relocation_end());
+ }
+ Expected<section_iterator> getRelocatedSection() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const ObjectFile *getObject() const;
+};
+
+struct SectionedAddress {
+ const static uint64_t UndefSection = UINT64_MAX;
+
+ uint64_t Address = 0;
+ uint64_t SectionIndex = UndefSection;
+};
+
+inline bool operator<(const SectionedAddress &LHS,
+ const SectionedAddress &RHS) {
+ return std::tie(LHS.SectionIndex, LHS.Address) <
+ std::tie(RHS.SectionIndex, RHS.Address);
+}
+
+inline bool operator==(const SectionedAddress &LHS,
+ const SectionedAddress &RHS) {
+ return std::tie(LHS.SectionIndex, LHS.Address) ==
+ std::tie(RHS.SectionIndex, RHS.Address);
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const SectionedAddress &Addr);
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class SymbolRef : public BasicSymbolRef {
+ friend class SectionRef;
+
+public:
+ enum Type {
+ ST_Unknown, // Type not specified
+ ST_Data,
+ ST_Debug,
+ ST_File,
+ ST_Function,
+ ST_Other
+ };
+
+ SymbolRef() = default;
+ SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
+ SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
+ assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
+ }
+
+ Expected<StringRef> getName() const;
+ /// Returns the symbol virtual address (i.e. address at which it will be
+ /// mapped).
+ Expected<uint64_t> getAddress() const;
+
+ /// Return the value of the symbol depending on the object this can be an
+ /// offset or a virtual address.
+ Expected<uint64_t> getValue() const;
+
+ /// Get the alignment of this symbol as the actual value (not log 2).
+ uint32_t getAlignment() const;
+ uint64_t getCommonSize() const;
+ Expected<SymbolRef::Type> getType() const;
+
+ /// Get section this symbol is defined in reference to. Result is
+ /// end_sections() if it is undefined or is an absolute symbol.
+ Expected<section_iterator> getSection() const;
+
+ const ObjectFile *getObject() const;
+};
+
+class symbol_iterator : public basic_symbol_iterator {
+public:
+ symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
+ symbol_iterator(const basic_symbol_iterator &B)
+ : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
+ cast<ObjectFile>(B->getObject()))) {}
+
+ const SymbolRef *operator->() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef*>(&P);
+ }
+
+ const SymbolRef &operator*() const {
+ const BasicSymbolRef &P = basic_symbol_iterator::operator *();
+ return static_cast<const SymbolRef&>(P);
+ }
+};
+
+/// This class is the base class for all object file types. Concrete instances
+/// of this object are created by createObjectFile, which figures out which type
+/// to create.
+class ObjectFile : public SymbolicFile {
+ virtual void anchor();
+
+protected:
+ ObjectFile(unsigned int Type, MemoryBufferRef Source);
+
+ const uint8_t *base() const {
+ return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
+ }
+
+ // These functions are for SymbolRef to call internally. The main goal of
+ // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
+ // entry in the memory mapped object file. SymbolPimpl cannot contain any
+ // virtual functions because then it could not point into the memory mapped
+ // file.
+ //
+ // Implementations assume that the DataRefImpl is valid and has not been
+ // modified externally. It's UB otherwise.
+ friend class SymbolRef;
+
+ virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
+ Error printSymbolName(raw_ostream &OS,
+ DataRefImpl Symb) const override;
+ virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
+ virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
+ virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
+ virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
+ virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
+ virtual Expected<section_iterator>
+ getSymbolSection(DataRefImpl Symb) const = 0;
+
+ // Same as above for SectionRef.
+ friend class SectionRef;
+
+ virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
+ virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
+ virtual Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const = 0;
+ virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
+ virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
+ virtual bool isSectionText(DataRefImpl Sec) const = 0;
+ virtual bool isSectionData(DataRefImpl Sec) const = 0;
+ virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
+ // A section is 'virtual' if its contents aren't present in the object image.
+ virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
+ virtual bool isSectionBitcode(DataRefImpl Sec) const;
+ virtual bool isSectionStripped(DataRefImpl Sec) const;
+ virtual bool isBerkeleyText(DataRefImpl Sec) const;
+ virtual bool isBerkeleyData(DataRefImpl Sec) const;
+ virtual bool isDebugSection(StringRef SectionName) const;
+ virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
+ virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
+ virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
+
+ // Same as above for RelocationRef.
+ friend class RelocationRef;
+ virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
+ virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
+ virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
+ virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
+ virtual void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const = 0;
+
+ Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
+
+public:
+ ObjectFile() = delete;
+ ObjectFile(const ObjectFile &other) = delete;
+
+ uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
+ Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
+ if (!SymbolFlagsOrErr)
+ // TODO: Actually report errors helpfully.
+ report_fatal_error(SymbolFlagsOrErr.takeError());
+ assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
+ return getCommonSymbolSizeImpl(Symb);
+ }
+
+ virtual std::vector<SectionRef> dynamic_relocation_sections() const {
+ return std::vector<SectionRef>();
+ }
+
+ using symbol_iterator_range = iterator_range<symbol_iterator>;
+ symbol_iterator_range symbols() const {
+ return symbol_iterator_range(symbol_begin(), symbol_end());
+ }
+
+ virtual section_iterator section_begin() const = 0;
+ virtual section_iterator section_end() const = 0;
+
+ using section_iterator_range = iterator_range<section_iterator>;
+ section_iterator_range sections() const {
+ return section_iterator_range(section_begin(), section_end());
+ }
+
+ /// The number of bytes used to represent an address in this object
+ /// file format.
+ virtual uint8_t getBytesInAddress() const = 0;
+
+ virtual StringRef getFileFormatName() const = 0;
+ virtual Triple::ArchType getArch() const = 0;
+ virtual SubtargetFeatures getFeatures() const = 0;
virtual Optional<StringRef> tryGetCPUName() const { return None; };
- virtual void setARMSubArch(Triple &TheTriple) const { }
- virtual Expected<uint64_t> getStartAddress() const {
- return errorCodeToError(object_error::parse_failed);
- };
-
- /// Create a triple from the data in this object file.
- Triple makeTriple() const;
-
- /// Maps a debug section name to a standard DWARF section name.
- virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
-
- /// True if this is a relocatable object (.o/.obj).
- virtual bool isRelocatableObject() const = 0;
-
- /// @returns Pointer to ObjectFile subclass to handle this type of object.
- /// @param ObjectPath The path to the object file. ObjectPath.isObject must
- /// return true.
- /// Create ObjectFile from path.
- static Expected<OwningBinary<ObjectFile>>
- createObjectFile(StringRef ObjectPath);
-
- static Expected<std::unique_ptr<ObjectFile>>
+ virtual void setARMSubArch(Triple &TheTriple) const { }
+ virtual Expected<uint64_t> getStartAddress() const {
+ return errorCodeToError(object_error::parse_failed);
+ };
+
+ /// Create a triple from the data in this object file.
+ Triple makeTriple() const;
+
+ /// Maps a debug section name to a standard DWARF section name.
+ virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
+
+ /// True if this is a relocatable object (.o/.obj).
+ virtual bool isRelocatableObject() const = 0;
+
+ /// @returns Pointer to ObjectFile subclass to handle this type of object.
+ /// @param ObjectPath The path to the object file. ObjectPath.isObject must
+ /// return true.
+ /// Create ObjectFile from path.
+ static Expected<OwningBinary<ObjectFile>>
+ createObjectFile(StringRef ObjectPath);
+
+ static Expected<std::unique_ptr<ObjectFile>>
createObjectFile(MemoryBufferRef Object, llvm::file_magic Type,
bool InitContent = true);
- static Expected<std::unique_ptr<ObjectFile>>
- createObjectFile(MemoryBufferRef Object) {
- return createObjectFile(Object, llvm::file_magic::unknown);
- }
-
- static bool classof(const Binary *v) {
- return v->isObject();
- }
-
- static Expected<std::unique_ptr<COFFObjectFile>>
- createCOFFObjectFile(MemoryBufferRef Object);
-
- static Expected<std::unique_ptr<ObjectFile>>
- createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
-
- static Expected<std::unique_ptr<ObjectFile>>
+ static Expected<std::unique_ptr<ObjectFile>>
+ createObjectFile(MemoryBufferRef Object) {
+ return createObjectFile(Object, llvm::file_magic::unknown);
+ }
+
+ static bool classof(const Binary *v) {
+ return v->isObject();
+ }
+
+ static Expected<std::unique_ptr<COFFObjectFile>>
+ createCOFFObjectFile(MemoryBufferRef Object);
+
+ static Expected<std::unique_ptr<ObjectFile>>
+ createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
+
+ static Expected<std::unique_ptr<ObjectFile>>
createELFObjectFile(MemoryBufferRef Object, bool InitContent = true);
-
- static Expected<std::unique_ptr<MachOObjectFile>>
- createMachOObjectFile(MemoryBufferRef Object,
- uint32_t UniversalCputype = 0,
- uint32_t UniversalIndex = 0);
-
- static Expected<std::unique_ptr<WasmObjectFile>>
- createWasmObjectFile(MemoryBufferRef Object);
-};
-
-// Inline function definitions.
-inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
- : BasicSymbolRef(SymbolP, Owner) {}
-
-inline Expected<StringRef> SymbolRef::getName() const {
- return getObject()->getSymbolName(getRawDataRefImpl());
-}
-
-inline Expected<uint64_t> SymbolRef::getAddress() const {
- return getObject()->getSymbolAddress(getRawDataRefImpl());
-}
-
-inline Expected<uint64_t> SymbolRef::getValue() const {
- return getObject()->getSymbolValue(getRawDataRefImpl());
-}
-
-inline uint32_t SymbolRef::getAlignment() const {
- return getObject()->getSymbolAlignment(getRawDataRefImpl());
-}
-
-inline uint64_t SymbolRef::getCommonSize() const {
- return getObject()->getCommonSymbolSize(getRawDataRefImpl());
-}
-
-inline Expected<section_iterator> SymbolRef::getSection() const {
- return getObject()->getSymbolSection(getRawDataRefImpl());
-}
-
-inline Expected<SymbolRef::Type> SymbolRef::getType() const {
- return getObject()->getSymbolType(getRawDataRefImpl());
-}
-
-inline const ObjectFile *SymbolRef::getObject() const {
- const SymbolicFile *O = BasicSymbolRef::getObject();
- return cast<ObjectFile>(O);
-}
-
-/// SectionRef
-inline SectionRef::SectionRef(DataRefImpl SectionP,
- const ObjectFile *Owner)
- : SectionPimpl(SectionP)
- , OwningObject(Owner) {}
-
-inline bool SectionRef::operator==(const SectionRef &Other) const {
- return OwningObject == Other.OwningObject &&
- SectionPimpl == Other.SectionPimpl;
-}
-
-inline bool SectionRef::operator!=(const SectionRef &Other) const {
- return !(*this == Other);
-}
-
-inline bool SectionRef::operator<(const SectionRef &Other) const {
- assert(OwningObject == Other.OwningObject);
- return SectionPimpl < Other.SectionPimpl;
-}
-
-inline void SectionRef::moveNext() {
- return OwningObject->moveSectionNext(SectionPimpl);
-}
-
-inline Expected<StringRef> SectionRef::getName() const {
- return OwningObject->getSectionName(SectionPimpl);
-}
-
-inline uint64_t SectionRef::getAddress() const {
- return OwningObject->getSectionAddress(SectionPimpl);
-}
-
-inline uint64_t SectionRef::getIndex() const {
- return OwningObject->getSectionIndex(SectionPimpl);
-}
-
-inline uint64_t SectionRef::getSize() const {
- return OwningObject->getSectionSize(SectionPimpl);
-}
-
-inline Expected<StringRef> SectionRef::getContents() const {
- Expected<ArrayRef<uint8_t>> Res =
- OwningObject->getSectionContents(SectionPimpl);
- if (!Res)
- return Res.takeError();
- return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
-}
-
-inline uint64_t SectionRef::getAlignment() const {
- return OwningObject->getSectionAlignment(SectionPimpl);
-}
-
-inline bool SectionRef::isCompressed() const {
- return OwningObject->isSectionCompressed(SectionPimpl);
-}
-
-inline bool SectionRef::isText() const {
- return OwningObject->isSectionText(SectionPimpl);
-}
-
-inline bool SectionRef::isData() const {
- return OwningObject->isSectionData(SectionPimpl);
-}
-
-inline bool SectionRef::isBSS() const {
- return OwningObject->isSectionBSS(SectionPimpl);
-}
-
-inline bool SectionRef::isVirtual() const {
- return OwningObject->isSectionVirtual(SectionPimpl);
-}
-
-inline bool SectionRef::isBitcode() const {
- return OwningObject->isSectionBitcode(SectionPimpl);
-}
-
-inline bool SectionRef::isStripped() const {
- return OwningObject->isSectionStripped(SectionPimpl);
-}
-
-inline bool SectionRef::isBerkeleyText() const {
- return OwningObject->isBerkeleyText(SectionPimpl);
-}
-
-inline bool SectionRef::isBerkeleyData() const {
- return OwningObject->isBerkeleyData(SectionPimpl);
-}
-
-inline bool SectionRef::isDebugSection(StringRef SectionName) const {
- return OwningObject->isDebugSection(SectionName);
-}
-
-inline relocation_iterator SectionRef::relocation_begin() const {
- return OwningObject->section_rel_begin(SectionPimpl);
-}
-
-inline relocation_iterator SectionRef::relocation_end() const {
- return OwningObject->section_rel_end(SectionPimpl);
-}
-
-inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
- return OwningObject->getRelocatedSection(SectionPimpl);
-}
-
-inline DataRefImpl SectionRef::getRawDataRefImpl() const {
- return SectionPimpl;
-}
-
-inline const ObjectFile *SectionRef::getObject() const {
- return OwningObject;
-}
-
-/// RelocationRef
-inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
- const ObjectFile *Owner)
- : RelocationPimpl(RelocationP)
- , OwningObject(Owner) {}
-
-inline bool RelocationRef::operator==(const RelocationRef &Other) const {
- return RelocationPimpl == Other.RelocationPimpl;
-}
-
-inline void RelocationRef::moveNext() {
- return OwningObject->moveRelocationNext(RelocationPimpl);
-}
-
-inline uint64_t RelocationRef::getOffset() const {
- return OwningObject->getRelocationOffset(RelocationPimpl);
-}
-
-inline symbol_iterator RelocationRef::getSymbol() const {
- return OwningObject->getRelocationSymbol(RelocationPimpl);
-}
-
-inline uint64_t RelocationRef::getType() const {
- return OwningObject->getRelocationType(RelocationPimpl);
-}
-
-inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
- return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
-}
-
-inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
- return RelocationPimpl;
-}
-
-inline const ObjectFile *RelocationRef::getObject() const {
- return OwningObject;
-}
-
-} // end namespace object
-
-template <> struct DenseMapInfo<object::SectionRef> {
- static bool isEqual(const object::SectionRef &A,
- const object::SectionRef &B) {
- return A == B;
- }
- static object::SectionRef getEmptyKey() {
- return object::SectionRef({}, nullptr);
- }
- static object::SectionRef getTombstoneKey() {
- object::DataRefImpl TS;
- TS.p = (uintptr_t)-1;
- return object::SectionRef(TS, nullptr);
- }
- static unsigned getHashValue(const object::SectionRef &Sec) {
- object::DataRefImpl Raw = Sec.getRawDataRefImpl();
- return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
- }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_OBJECTFILE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+
+ static Expected<std::unique_ptr<MachOObjectFile>>
+ createMachOObjectFile(MemoryBufferRef Object,
+ uint32_t UniversalCputype = 0,
+ uint32_t UniversalIndex = 0);
+
+ static Expected<std::unique_ptr<WasmObjectFile>>
+ createWasmObjectFile(MemoryBufferRef Object);
+};
+
+// Inline function definitions.
+inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
+ : BasicSymbolRef(SymbolP, Owner) {}
+
+inline Expected<StringRef> SymbolRef::getName() const {
+ return getObject()->getSymbolName(getRawDataRefImpl());
+}
+
+inline Expected<uint64_t> SymbolRef::getAddress() const {
+ return getObject()->getSymbolAddress(getRawDataRefImpl());
+}
+
+inline Expected<uint64_t> SymbolRef::getValue() const {
+ return getObject()->getSymbolValue(getRawDataRefImpl());
+}
+
+inline uint32_t SymbolRef::getAlignment() const {
+ return getObject()->getSymbolAlignment(getRawDataRefImpl());
+}
+
+inline uint64_t SymbolRef::getCommonSize() const {
+ return getObject()->getCommonSymbolSize(getRawDataRefImpl());
+}
+
+inline Expected<section_iterator> SymbolRef::getSection() const {
+ return getObject()->getSymbolSection(getRawDataRefImpl());
+}
+
+inline Expected<SymbolRef::Type> SymbolRef::getType() const {
+ return getObject()->getSymbolType(getRawDataRefImpl());
+}
+
+inline const ObjectFile *SymbolRef::getObject() const {
+ const SymbolicFile *O = BasicSymbolRef::getObject();
+ return cast<ObjectFile>(O);
+}
+
+/// SectionRef
+inline SectionRef::SectionRef(DataRefImpl SectionP,
+ const ObjectFile *Owner)
+ : SectionPimpl(SectionP)
+ , OwningObject(Owner) {}
+
+inline bool SectionRef::operator==(const SectionRef &Other) const {
+ return OwningObject == Other.OwningObject &&
+ SectionPimpl == Other.SectionPimpl;
+}
+
+inline bool SectionRef::operator!=(const SectionRef &Other) const {
+ return !(*this == Other);
+}
+
+inline bool SectionRef::operator<(const SectionRef &Other) const {
+ assert(OwningObject == Other.OwningObject);
+ return SectionPimpl < Other.SectionPimpl;
+}
+
+inline void SectionRef::moveNext() {
+ return OwningObject->moveSectionNext(SectionPimpl);
+}
+
+inline Expected<StringRef> SectionRef::getName() const {
+ return OwningObject->getSectionName(SectionPimpl);
+}
+
+inline uint64_t SectionRef::getAddress() const {
+ return OwningObject->getSectionAddress(SectionPimpl);
+}
+
+inline uint64_t SectionRef::getIndex() const {
+ return OwningObject->getSectionIndex(SectionPimpl);
+}
+
+inline uint64_t SectionRef::getSize() const {
+ return OwningObject->getSectionSize(SectionPimpl);
+}
+
+inline Expected<StringRef> SectionRef::getContents() const {
+ Expected<ArrayRef<uint8_t>> Res =
+ OwningObject->getSectionContents(SectionPimpl);
+ if (!Res)
+ return Res.takeError();
+ return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
+}
+
+inline uint64_t SectionRef::getAlignment() const {
+ return OwningObject->getSectionAlignment(SectionPimpl);
+}
+
+inline bool SectionRef::isCompressed() const {
+ return OwningObject->isSectionCompressed(SectionPimpl);
+}
+
+inline bool SectionRef::isText() const {
+ return OwningObject->isSectionText(SectionPimpl);
+}
+
+inline bool SectionRef::isData() const {
+ return OwningObject->isSectionData(SectionPimpl);
+}
+
+inline bool SectionRef::isBSS() const {
+ return OwningObject->isSectionBSS(SectionPimpl);
+}
+
+inline bool SectionRef::isVirtual() const {
+ return OwningObject->isSectionVirtual(SectionPimpl);
+}
+
+inline bool SectionRef::isBitcode() const {
+ return OwningObject->isSectionBitcode(SectionPimpl);
+}
+
+inline bool SectionRef::isStripped() const {
+ return OwningObject->isSectionStripped(SectionPimpl);
+}
+
+inline bool SectionRef::isBerkeleyText() const {
+ return OwningObject->isBerkeleyText(SectionPimpl);
+}
+
+inline bool SectionRef::isBerkeleyData() const {
+ return OwningObject->isBerkeleyData(SectionPimpl);
+}
+
+inline bool SectionRef::isDebugSection(StringRef SectionName) const {
+ return OwningObject->isDebugSection(SectionName);
+}
+
+inline relocation_iterator SectionRef::relocation_begin() const {
+ return OwningObject->section_rel_begin(SectionPimpl);
+}
+
+inline relocation_iterator SectionRef::relocation_end() const {
+ return OwningObject->section_rel_end(SectionPimpl);
+}
+
+inline Expected<section_iterator> SectionRef::getRelocatedSection() const {
+ return OwningObject->getRelocatedSection(SectionPimpl);
+}
+
+inline DataRefImpl SectionRef::getRawDataRefImpl() const {
+ return SectionPimpl;
+}
+
+inline const ObjectFile *SectionRef::getObject() const {
+ return OwningObject;
+}
+
+/// RelocationRef
+inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
+ const ObjectFile *Owner)
+ : RelocationPimpl(RelocationP)
+ , OwningObject(Owner) {}
+
+inline bool RelocationRef::operator==(const RelocationRef &Other) const {
+ return RelocationPimpl == Other.RelocationPimpl;
+}
+
+inline void RelocationRef::moveNext() {
+ return OwningObject->moveRelocationNext(RelocationPimpl);
+}
+
+inline uint64_t RelocationRef::getOffset() const {
+ return OwningObject->getRelocationOffset(RelocationPimpl);
+}
+
+inline symbol_iterator RelocationRef::getSymbol() const {
+ return OwningObject->getRelocationSymbol(RelocationPimpl);
+}
+
+inline uint64_t RelocationRef::getType() const {
+ return OwningObject->getRelocationType(RelocationPimpl);
+}
+
+inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
+ return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
+}
+
+inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
+ return RelocationPimpl;
+}
+
+inline const ObjectFile *RelocationRef::getObject() const {
+ return OwningObject;
+}
+
+} // end namespace object
+
+template <> struct DenseMapInfo<object::SectionRef> {
+ static bool isEqual(const object::SectionRef &A,
+ const object::SectionRef &B) {
+ return A == B;
+ }
+ static object::SectionRef getEmptyKey() {
+ return object::SectionRef({}, nullptr);
+ }
+ static object::SectionRef getTombstoneKey() {
+ object::DataRefImpl TS;
+ TS.p = (uintptr_t)-1;
+ return object::SectionRef(TS, nullptr);
+ }
+ static unsigned getHashValue(const object::SectionRef &Sec) {
+ object::DataRefImpl Raw = Sec.getRawDataRefImpl();
+ return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_OBJECTFILE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h b/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h
index d53f50e3e5e..520d7ff50b1 100644
--- a/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h
+++ b/contrib/libs/llvm12/include/llvm/Object/RelocationResolver.h
@@ -1,59 +1,59 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- RelocVisitor.h - Visitor for object file relocations -----*- 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 provides a wrapper around all the different types of relocations
-// in different file formats, such that a client can handle them in a unified
-// manner by only implementing a minimal number of functions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_RELOCVISITOR_H
-#define LLVM_OBJECT_RELOCVISITOR_H
-
-#include "llvm/ADT/Triple.h"
-#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/BinaryFormat/MachO.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/Wasm.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <cstdint>
-#include <system_error>
-
-namespace llvm {
-namespace object {
-
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- RelocVisitor.h - Visitor for object file relocations -----*- 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 provides a wrapper around all the different types of relocations
+// in different file formats, such that a client can handle them in a unified
+// manner by only implementing a minimal number of functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_RELOCVISITOR_H
+#define LLVM_OBJECT_RELOCVISITOR_H
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/Wasm.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstdint>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
using SupportsRelocation = bool (*)(uint64_t);
using RelocationResolver = uint64_t (*)(uint64_t Type, uint64_t Offset,
uint64_t S, uint64_t LocData,
int64_t Addend);
-
+
std::pair<SupportsRelocation, RelocationResolver>
-getRelocationResolver(const ObjectFile &Obj);
-
+getRelocationResolver(const ObjectFile &Obj);
+
uint64_t resolveRelocation(RelocationResolver Resolver, const RelocationRef &R,
uint64_t S, uint64_t LocData);
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_RELOCVISITOR_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_RELOCVISITOR_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h b/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h
index 4551e80bb23..100ad707245 100644
--- a/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h
+++ b/contrib/libs/llvm12/include/llvm/Object/StackMapParser.h
@@ -1,333 +1,333 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- StackMapParser.h - StackMap Parsing Support --------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_STACKMAPPARSER_H
-#define LLVM_CODEGEN_STACKMAPPARSER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/iterator_range.h"
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StackMapParser.h - StackMap Parsing Support --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_STACKMAPPARSER_H
+#define LLVM_CODEGEN_STACKMAPPARSER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Object/ELF.h"
-#include "llvm/Support/Endian.h"
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-
-/// A parser for the latest stackmap format. At the moment, latest=V3.
-template <support::endianness Endianness>
-class StackMapParser {
-public:
- template <typename AccessorT>
- class AccessorIterator {
- public:
- AccessorIterator(AccessorT A) : A(A) {}
-
- AccessorIterator& operator++() { A = A.next(); return *this; }
- AccessorIterator operator++(int) {
- auto tmp = *this;
- ++*this;
- return tmp;
- }
-
- bool operator==(const AccessorIterator &Other) const {
- return A.P == Other.A.P;
- }
-
- bool operator!=(const AccessorIterator &Other) const {
- return !(*this == Other);
- }
-
- AccessorT& operator*() { return A; }
- AccessorT* operator->() { return &A; }
-
- private:
- AccessorT A;
- };
-
- /// Accessor for function records.
- class FunctionAccessor {
- friend class StackMapParser;
-
- public:
- /// Get the function address.
- uint64_t getFunctionAddress() const {
- return read<uint64_t>(P);
- }
-
- /// Get the function's stack size.
- uint64_t getStackSize() const {
- return read<uint64_t>(P + sizeof(uint64_t));
- }
-
- /// Get the number of callsite records.
- uint64_t getRecordCount() const {
- return read<uint64_t>(P + (2 * sizeof(uint64_t)));
- }
-
- private:
- FunctionAccessor(const uint8_t *P) : P(P) {}
-
- const static int FunctionAccessorSize = 3 * sizeof(uint64_t);
-
- FunctionAccessor next() const {
- return FunctionAccessor(P + FunctionAccessorSize);
- }
-
- const uint8_t *P;
- };
-
- /// Accessor for constants.
- class ConstantAccessor {
- friend class StackMapParser;
-
- public:
- /// Return the value of this constant.
- uint64_t getValue() const { return read<uint64_t>(P); }
-
- private:
- ConstantAccessor(const uint8_t *P) : P(P) {}
-
- const static int ConstantAccessorSize = sizeof(uint64_t);
-
- ConstantAccessor next() const {
- return ConstantAccessor(P + ConstantAccessorSize);
- }
-
- const uint8_t *P;
- };
-
- enum class LocationKind : uint8_t {
- Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5
- };
-
- /// Accessor for location records.
- class LocationAccessor {
- friend class StackMapParser;
- friend class RecordAccessor;
-
- public:
- /// Get the Kind for this location.
- LocationKind getKind() const {
- return LocationKind(P[KindOffset]);
- }
-
- /// Get the Size for this location.
- unsigned getSizeInBytes() const {
- return read<uint16_t>(P + SizeOffset);
-
- }
-
- /// Get the Dwarf register number for this location.
- uint16_t getDwarfRegNum() const {
- return read<uint16_t>(P + DwarfRegNumOffset);
- }
-
- /// Get the small-constant for this location. (Kind must be Constant).
- uint32_t getSmallConstant() const {
- assert(getKind() == LocationKind::Constant && "Not a small constant.");
- return read<uint32_t>(P + SmallConstantOffset);
- }
-
- /// Get the constant-index for this location. (Kind must be ConstantIndex).
- uint32_t getConstantIndex() const {
- assert(getKind() == LocationKind::ConstantIndex &&
- "Not a constant-index.");
- return read<uint32_t>(P + SmallConstantOffset);
- }
-
- /// Get the offset for this location. (Kind must be Direct or Indirect).
- int32_t getOffset() const {
- assert((getKind() == LocationKind::Direct ||
- getKind() == LocationKind::Indirect) &&
- "Not direct or indirect.");
- return read<int32_t>(P + SmallConstantOffset);
- }
-
- private:
- LocationAccessor(const uint8_t *P) : P(P) {}
-
- LocationAccessor next() const {
- return LocationAccessor(P + LocationAccessorSize);
- }
-
- static const int KindOffset = 0;
- static const int SizeOffset = KindOffset + sizeof(uint16_t);
- static const int DwarfRegNumOffset = SizeOffset + sizeof(uint16_t);
- static const int SmallConstantOffset = DwarfRegNumOffset + sizeof(uint32_t);
- static const int LocationAccessorSize = sizeof(uint64_t) + sizeof(uint32_t);
-
- const uint8_t *P;
- };
-
- /// Accessor for stackmap live-out fields.
- class LiveOutAccessor {
- friend class StackMapParser;
- friend class RecordAccessor;
-
- public:
- /// Get the Dwarf register number for this live-out.
- uint16_t getDwarfRegNum() const {
- return read<uint16_t>(P + DwarfRegNumOffset);
- }
-
- /// Get the size in bytes of live [sub]register.
- unsigned getSizeInBytes() const {
- return read<uint8_t>(P + SizeOffset);
- }
-
- private:
- LiveOutAccessor(const uint8_t *P) : P(P) {}
-
- LiveOutAccessor next() const {
- return LiveOutAccessor(P + LiveOutAccessorSize);
- }
-
- static const int DwarfRegNumOffset = 0;
- static const int SizeOffset =
- DwarfRegNumOffset + sizeof(uint16_t) + sizeof(uint8_t);
- static const int LiveOutAccessorSize = sizeof(uint32_t);
-
- const uint8_t *P;
- };
-
- /// Accessor for stackmap records.
- class RecordAccessor {
- friend class StackMapParser;
-
- public:
- using location_iterator = AccessorIterator<LocationAccessor>;
- using liveout_iterator = AccessorIterator<LiveOutAccessor>;
-
- /// Get the patchpoint/stackmap ID for this record.
- uint64_t getID() const {
- return read<uint64_t>(P + PatchpointIDOffset);
- }
-
- /// Get the instruction offset (from the start of the containing function)
- /// for this record.
- uint32_t getInstructionOffset() const {
- return read<uint32_t>(P + InstructionOffsetOffset);
- }
-
- /// Get the number of locations contained in this record.
- uint16_t getNumLocations() const {
- return read<uint16_t>(P + NumLocationsOffset);
- }
-
- /// Get the location with the given index.
- LocationAccessor getLocation(unsigned LocationIndex) const {
- unsigned LocationOffset =
- LocationListOffset + LocationIndex * LocationSize;
- return LocationAccessor(P + LocationOffset);
- }
-
- /// Begin iterator for locations.
- location_iterator location_begin() const {
- return location_iterator(getLocation(0));
- }
-
- /// End iterator for locations.
- location_iterator location_end() const {
- return location_iterator(getLocation(getNumLocations()));
- }
-
- /// Iterator range for locations.
- iterator_range<location_iterator> locations() const {
- return make_range(location_begin(), location_end());
- }
-
- /// Get the number of liveouts contained in this record.
- uint16_t getNumLiveOuts() const {
- return read<uint16_t>(P + getNumLiveOutsOffset());
- }
-
- /// Get the live-out with the given index.
- LiveOutAccessor getLiveOut(unsigned LiveOutIndex) const {
- unsigned LiveOutOffset =
- getNumLiveOutsOffset() + sizeof(uint16_t) + LiveOutIndex * LiveOutSize;
- return LiveOutAccessor(P + LiveOutOffset);
- }
-
- /// Begin iterator for live-outs.
- liveout_iterator liveouts_begin() const {
- return liveout_iterator(getLiveOut(0));
- }
-
- /// End iterator for live-outs.
- liveout_iterator liveouts_end() const {
- return liveout_iterator(getLiveOut(getNumLiveOuts()));
- }
-
- /// Iterator range for live-outs.
- iterator_range<liveout_iterator> liveouts() const {
- return make_range(liveouts_begin(), liveouts_end());
- }
-
- private:
- RecordAccessor(const uint8_t *P) : P(P) {}
-
- unsigned getNumLiveOutsOffset() const {
- unsigned LocOffset =
- ((LocationListOffset + LocationSize * getNumLocations()) + 7) & ~0x7;
- return LocOffset + sizeof(uint16_t);
- }
-
- unsigned getSizeInBytes() const {
- unsigned RecordSize =
- getNumLiveOutsOffset() + sizeof(uint16_t) + getNumLiveOuts() * LiveOutSize;
- return (RecordSize + 7) & ~0x7;
- }
-
- RecordAccessor next() const {
- return RecordAccessor(P + getSizeInBytes());
- }
-
- static const unsigned PatchpointIDOffset = 0;
- static const unsigned InstructionOffsetOffset =
- PatchpointIDOffset + sizeof(uint64_t);
- static const unsigned NumLocationsOffset =
- InstructionOffsetOffset + sizeof(uint32_t) + sizeof(uint16_t);
- static const unsigned LocationListOffset =
- NumLocationsOffset + sizeof(uint16_t);
- static const unsigned LocationSize = sizeof(uint64_t) + sizeof(uint32_t);
- static const unsigned LiveOutSize = sizeof(uint32_t);
-
- const uint8_t *P;
- };
-
- /// Construct a parser for a version-3 stackmap. StackMap data will be read
- /// from the given array.
- StackMapParser(ArrayRef<uint8_t> StackMapSection)
- : StackMapSection(StackMapSection) {
- ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize;
-
- assert(StackMapSection[0] == 3 &&
- "StackMapParser can only parse version 3 stackmaps");
-
- unsigned CurrentRecordOffset =
- ConstantsListOffset + getNumConstants() * ConstantSize;
-
- for (unsigned I = 0, E = getNumRecords(); I != E; ++I) {
- StackMapRecordOffsets.push_back(CurrentRecordOffset);
- CurrentRecordOffset +=
- RecordAccessor(&StackMapSection[CurrentRecordOffset]).getSizeInBytes();
- }
- }
-
+#include "llvm/Support/Endian.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+
+/// A parser for the latest stackmap format. At the moment, latest=V3.
+template <support::endianness Endianness>
+class StackMapParser {
+public:
+ template <typename AccessorT>
+ class AccessorIterator {
+ public:
+ AccessorIterator(AccessorT A) : A(A) {}
+
+ AccessorIterator& operator++() { A = A.next(); return *this; }
+ AccessorIterator operator++(int) {
+ auto tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(const AccessorIterator &Other) const {
+ return A.P == Other.A.P;
+ }
+
+ bool operator!=(const AccessorIterator &Other) const {
+ return !(*this == Other);
+ }
+
+ AccessorT& operator*() { return A; }
+ AccessorT* operator->() { return &A; }
+
+ private:
+ AccessorT A;
+ };
+
+ /// Accessor for function records.
+ class FunctionAccessor {
+ friend class StackMapParser;
+
+ public:
+ /// Get the function address.
+ uint64_t getFunctionAddress() const {
+ return read<uint64_t>(P);
+ }
+
+ /// Get the function's stack size.
+ uint64_t getStackSize() const {
+ return read<uint64_t>(P + sizeof(uint64_t));
+ }
+
+ /// Get the number of callsite records.
+ uint64_t getRecordCount() const {
+ return read<uint64_t>(P + (2 * sizeof(uint64_t)));
+ }
+
+ private:
+ FunctionAccessor(const uint8_t *P) : P(P) {}
+
+ const static int FunctionAccessorSize = 3 * sizeof(uint64_t);
+
+ FunctionAccessor next() const {
+ return FunctionAccessor(P + FunctionAccessorSize);
+ }
+
+ const uint8_t *P;
+ };
+
+ /// Accessor for constants.
+ class ConstantAccessor {
+ friend class StackMapParser;
+
+ public:
+ /// Return the value of this constant.
+ uint64_t getValue() const { return read<uint64_t>(P); }
+
+ private:
+ ConstantAccessor(const uint8_t *P) : P(P) {}
+
+ const static int ConstantAccessorSize = sizeof(uint64_t);
+
+ ConstantAccessor next() const {
+ return ConstantAccessor(P + ConstantAccessorSize);
+ }
+
+ const uint8_t *P;
+ };
+
+ enum class LocationKind : uint8_t {
+ Register = 1, Direct = 2, Indirect = 3, Constant = 4, ConstantIndex = 5
+ };
+
+ /// Accessor for location records.
+ class LocationAccessor {
+ friend class StackMapParser;
+ friend class RecordAccessor;
+
+ public:
+ /// Get the Kind for this location.
+ LocationKind getKind() const {
+ return LocationKind(P[KindOffset]);
+ }
+
+ /// Get the Size for this location.
+ unsigned getSizeInBytes() const {
+ return read<uint16_t>(P + SizeOffset);
+
+ }
+
+ /// Get the Dwarf register number for this location.
+ uint16_t getDwarfRegNum() const {
+ return read<uint16_t>(P + DwarfRegNumOffset);
+ }
+
+ /// Get the small-constant for this location. (Kind must be Constant).
+ uint32_t getSmallConstant() const {
+ assert(getKind() == LocationKind::Constant && "Not a small constant.");
+ return read<uint32_t>(P + SmallConstantOffset);
+ }
+
+ /// Get the constant-index for this location. (Kind must be ConstantIndex).
+ uint32_t getConstantIndex() const {
+ assert(getKind() == LocationKind::ConstantIndex &&
+ "Not a constant-index.");
+ return read<uint32_t>(P + SmallConstantOffset);
+ }
+
+ /// Get the offset for this location. (Kind must be Direct or Indirect).
+ int32_t getOffset() const {
+ assert((getKind() == LocationKind::Direct ||
+ getKind() == LocationKind::Indirect) &&
+ "Not direct or indirect.");
+ return read<int32_t>(P + SmallConstantOffset);
+ }
+
+ private:
+ LocationAccessor(const uint8_t *P) : P(P) {}
+
+ LocationAccessor next() const {
+ return LocationAccessor(P + LocationAccessorSize);
+ }
+
+ static const int KindOffset = 0;
+ static const int SizeOffset = KindOffset + sizeof(uint16_t);
+ static const int DwarfRegNumOffset = SizeOffset + sizeof(uint16_t);
+ static const int SmallConstantOffset = DwarfRegNumOffset + sizeof(uint32_t);
+ static const int LocationAccessorSize = sizeof(uint64_t) + sizeof(uint32_t);
+
+ const uint8_t *P;
+ };
+
+ /// Accessor for stackmap live-out fields.
+ class LiveOutAccessor {
+ friend class StackMapParser;
+ friend class RecordAccessor;
+
+ public:
+ /// Get the Dwarf register number for this live-out.
+ uint16_t getDwarfRegNum() const {
+ return read<uint16_t>(P + DwarfRegNumOffset);
+ }
+
+ /// Get the size in bytes of live [sub]register.
+ unsigned getSizeInBytes() const {
+ return read<uint8_t>(P + SizeOffset);
+ }
+
+ private:
+ LiveOutAccessor(const uint8_t *P) : P(P) {}
+
+ LiveOutAccessor next() const {
+ return LiveOutAccessor(P + LiveOutAccessorSize);
+ }
+
+ static const int DwarfRegNumOffset = 0;
+ static const int SizeOffset =
+ DwarfRegNumOffset + sizeof(uint16_t) + sizeof(uint8_t);
+ static const int LiveOutAccessorSize = sizeof(uint32_t);
+
+ const uint8_t *P;
+ };
+
+ /// Accessor for stackmap records.
+ class RecordAccessor {
+ friend class StackMapParser;
+
+ public:
+ using location_iterator = AccessorIterator<LocationAccessor>;
+ using liveout_iterator = AccessorIterator<LiveOutAccessor>;
+
+ /// Get the patchpoint/stackmap ID for this record.
+ uint64_t getID() const {
+ return read<uint64_t>(P + PatchpointIDOffset);
+ }
+
+ /// Get the instruction offset (from the start of the containing function)
+ /// for this record.
+ uint32_t getInstructionOffset() const {
+ return read<uint32_t>(P + InstructionOffsetOffset);
+ }
+
+ /// Get the number of locations contained in this record.
+ uint16_t getNumLocations() const {
+ return read<uint16_t>(P + NumLocationsOffset);
+ }
+
+ /// Get the location with the given index.
+ LocationAccessor getLocation(unsigned LocationIndex) const {
+ unsigned LocationOffset =
+ LocationListOffset + LocationIndex * LocationSize;
+ return LocationAccessor(P + LocationOffset);
+ }
+
+ /// Begin iterator for locations.
+ location_iterator location_begin() const {
+ return location_iterator(getLocation(0));
+ }
+
+ /// End iterator for locations.
+ location_iterator location_end() const {
+ return location_iterator(getLocation(getNumLocations()));
+ }
+
+ /// Iterator range for locations.
+ iterator_range<location_iterator> locations() const {
+ return make_range(location_begin(), location_end());
+ }
+
+ /// Get the number of liveouts contained in this record.
+ uint16_t getNumLiveOuts() const {
+ return read<uint16_t>(P + getNumLiveOutsOffset());
+ }
+
+ /// Get the live-out with the given index.
+ LiveOutAccessor getLiveOut(unsigned LiveOutIndex) const {
+ unsigned LiveOutOffset =
+ getNumLiveOutsOffset() + sizeof(uint16_t) + LiveOutIndex * LiveOutSize;
+ return LiveOutAccessor(P + LiveOutOffset);
+ }
+
+ /// Begin iterator for live-outs.
+ liveout_iterator liveouts_begin() const {
+ return liveout_iterator(getLiveOut(0));
+ }
+
+ /// End iterator for live-outs.
+ liveout_iterator liveouts_end() const {
+ return liveout_iterator(getLiveOut(getNumLiveOuts()));
+ }
+
+ /// Iterator range for live-outs.
+ iterator_range<liveout_iterator> liveouts() const {
+ return make_range(liveouts_begin(), liveouts_end());
+ }
+
+ private:
+ RecordAccessor(const uint8_t *P) : P(P) {}
+
+ unsigned getNumLiveOutsOffset() const {
+ unsigned LocOffset =
+ ((LocationListOffset + LocationSize * getNumLocations()) + 7) & ~0x7;
+ return LocOffset + sizeof(uint16_t);
+ }
+
+ unsigned getSizeInBytes() const {
+ unsigned RecordSize =
+ getNumLiveOutsOffset() + sizeof(uint16_t) + getNumLiveOuts() * LiveOutSize;
+ return (RecordSize + 7) & ~0x7;
+ }
+
+ RecordAccessor next() const {
+ return RecordAccessor(P + getSizeInBytes());
+ }
+
+ static const unsigned PatchpointIDOffset = 0;
+ static const unsigned InstructionOffsetOffset =
+ PatchpointIDOffset + sizeof(uint64_t);
+ static const unsigned NumLocationsOffset =
+ InstructionOffsetOffset + sizeof(uint32_t) + sizeof(uint16_t);
+ static const unsigned LocationListOffset =
+ NumLocationsOffset + sizeof(uint16_t);
+ static const unsigned LocationSize = sizeof(uint64_t) + sizeof(uint32_t);
+ static const unsigned LiveOutSize = sizeof(uint32_t);
+
+ const uint8_t *P;
+ };
+
+ /// Construct a parser for a version-3 stackmap. StackMap data will be read
+ /// from the given array.
+ StackMapParser(ArrayRef<uint8_t> StackMapSection)
+ : StackMapSection(StackMapSection) {
+ ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize;
+
+ assert(StackMapSection[0] == 3 &&
+ "StackMapParser can only parse version 3 stackmaps");
+
+ unsigned CurrentRecordOffset =
+ ConstantsListOffset + getNumConstants() * ConstantSize;
+
+ for (unsigned I = 0, E = getNumRecords(); I != E; ++I) {
+ StackMapRecordOffsets.push_back(CurrentRecordOffset);
+ CurrentRecordOffset +=
+ RecordAccessor(&StackMapSection[CurrentRecordOffset]).getSizeInBytes();
+ }
+ }
+
/// Validates the header of the specified stack map section.
static Error validateHeader(ArrayRef<uint8_t> StackMapSection) {
// See the comment for StackMaps::emitStackmapHeader().
@@ -345,134 +345,134 @@ public:
return Error::success();
}
- using function_iterator = AccessorIterator<FunctionAccessor>;
- using constant_iterator = AccessorIterator<ConstantAccessor>;
- using record_iterator = AccessorIterator<RecordAccessor>;
-
- /// Get the version number of this stackmap. (Always returns 3).
- unsigned getVersion() const { return 3; }
-
- /// Get the number of functions in the stack map.
- uint32_t getNumFunctions() const {
- return read<uint32_t>(&StackMapSection[NumFunctionsOffset]);
- }
-
- /// Get the number of large constants in the stack map.
- uint32_t getNumConstants() const {
- return read<uint32_t>(&StackMapSection[NumConstantsOffset]);
- }
-
- /// Get the number of stackmap records in the stackmap.
- uint32_t getNumRecords() const {
- return read<uint32_t>(&StackMapSection[NumRecordsOffset]);
- }
-
- /// Return an FunctionAccessor for the given function index.
- FunctionAccessor getFunction(unsigned FunctionIndex) const {
- return FunctionAccessor(StackMapSection.data() +
- getFunctionOffset(FunctionIndex));
- }
-
- /// Begin iterator for functions.
- function_iterator functions_begin() const {
- return function_iterator(getFunction(0));
- }
-
- /// End iterator for functions.
- function_iterator functions_end() const {
- return function_iterator(
- FunctionAccessor(StackMapSection.data() +
- getFunctionOffset(getNumFunctions())));
- }
-
- /// Iterator range for functions.
- iterator_range<function_iterator> functions() const {
- return make_range(functions_begin(), functions_end());
- }
-
- /// Return the large constant at the given index.
- ConstantAccessor getConstant(unsigned ConstantIndex) const {
- return ConstantAccessor(StackMapSection.data() +
- getConstantOffset(ConstantIndex));
- }
-
- /// Begin iterator for constants.
- constant_iterator constants_begin() const {
- return constant_iterator(getConstant(0));
- }
-
- /// End iterator for constants.
- constant_iterator constants_end() const {
- return constant_iterator(
- ConstantAccessor(StackMapSection.data() +
- getConstantOffset(getNumConstants())));
- }
-
- /// Iterator range for constants.
- iterator_range<constant_iterator> constants() const {
- return make_range(constants_begin(), constants_end());
- }
-
- /// Return a RecordAccessor for the given record index.
- RecordAccessor getRecord(unsigned RecordIndex) const {
- std::size_t RecordOffset = StackMapRecordOffsets[RecordIndex];
- return RecordAccessor(StackMapSection.data() + RecordOffset);
- }
-
- /// Begin iterator for records.
- record_iterator records_begin() const {
- if (getNumRecords() == 0)
- return record_iterator(RecordAccessor(nullptr));
- return record_iterator(getRecord(0));
- }
-
- /// End iterator for records.
- record_iterator records_end() const {
- // Records need to be handled specially, since we cache the start addresses
- // for them: We can't just compute the 1-past-the-end address, we have to
- // look at the last record and use the 'next' method.
- if (getNumRecords() == 0)
- return record_iterator(RecordAccessor(nullptr));
- return record_iterator(getRecord(getNumRecords() - 1).next());
- }
-
- /// Iterator range for records.
- iterator_range<record_iterator> records() const {
- return make_range(records_begin(), records_end());
- }
-
-private:
- template <typename T>
- static T read(const uint8_t *P) {
- return support::endian::read<T, Endianness, 1>(P);
- }
-
- static const unsigned HeaderOffset = 0;
- static const unsigned NumFunctionsOffset = HeaderOffset + sizeof(uint32_t);
- static const unsigned NumConstantsOffset = NumFunctionsOffset + sizeof(uint32_t);
- static const unsigned NumRecordsOffset = NumConstantsOffset + sizeof(uint32_t);
- static const unsigned FunctionListOffset = NumRecordsOffset + sizeof(uint32_t);
-
- static const unsigned FunctionSize = 3 * sizeof(uint64_t);
- static const unsigned ConstantSize = sizeof(uint64_t);
-
- std::size_t getFunctionOffset(unsigned FunctionIndex) const {
- return FunctionListOffset + FunctionIndex * FunctionSize;
- }
-
- std::size_t getConstantOffset(unsigned ConstantIndex) const {
- return ConstantsListOffset + ConstantIndex * ConstantSize;
- }
-
- ArrayRef<uint8_t> StackMapSection;
- unsigned ConstantsListOffset;
- std::vector<unsigned> StackMapRecordOffsets;
-};
-
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_STACKMAPPARSER_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+ using function_iterator = AccessorIterator<FunctionAccessor>;
+ using constant_iterator = AccessorIterator<ConstantAccessor>;
+ using record_iterator = AccessorIterator<RecordAccessor>;
+
+ /// Get the version number of this stackmap. (Always returns 3).
+ unsigned getVersion() const { return 3; }
+
+ /// Get the number of functions in the stack map.
+ uint32_t getNumFunctions() const {
+ return read<uint32_t>(&StackMapSection[NumFunctionsOffset]);
+ }
+
+ /// Get the number of large constants in the stack map.
+ uint32_t getNumConstants() const {
+ return read<uint32_t>(&StackMapSection[NumConstantsOffset]);
+ }
+
+ /// Get the number of stackmap records in the stackmap.
+ uint32_t getNumRecords() const {
+ return read<uint32_t>(&StackMapSection[NumRecordsOffset]);
+ }
+
+ /// Return an FunctionAccessor for the given function index.
+ FunctionAccessor getFunction(unsigned FunctionIndex) const {
+ return FunctionAccessor(StackMapSection.data() +
+ getFunctionOffset(FunctionIndex));
+ }
+
+ /// Begin iterator for functions.
+ function_iterator functions_begin() const {
+ return function_iterator(getFunction(0));
+ }
+
+ /// End iterator for functions.
+ function_iterator functions_end() const {
+ return function_iterator(
+ FunctionAccessor(StackMapSection.data() +
+ getFunctionOffset(getNumFunctions())));
+ }
+
+ /// Iterator range for functions.
+ iterator_range<function_iterator> functions() const {
+ return make_range(functions_begin(), functions_end());
+ }
+
+ /// Return the large constant at the given index.
+ ConstantAccessor getConstant(unsigned ConstantIndex) const {
+ return ConstantAccessor(StackMapSection.data() +
+ getConstantOffset(ConstantIndex));
+ }
+
+ /// Begin iterator for constants.
+ constant_iterator constants_begin() const {
+ return constant_iterator(getConstant(0));
+ }
+
+ /// End iterator for constants.
+ constant_iterator constants_end() const {
+ return constant_iterator(
+ ConstantAccessor(StackMapSection.data() +
+ getConstantOffset(getNumConstants())));
+ }
+
+ /// Iterator range for constants.
+ iterator_range<constant_iterator> constants() const {
+ return make_range(constants_begin(), constants_end());
+ }
+
+ /// Return a RecordAccessor for the given record index.
+ RecordAccessor getRecord(unsigned RecordIndex) const {
+ std::size_t RecordOffset = StackMapRecordOffsets[RecordIndex];
+ return RecordAccessor(StackMapSection.data() + RecordOffset);
+ }
+
+ /// Begin iterator for records.
+ record_iterator records_begin() const {
+ if (getNumRecords() == 0)
+ return record_iterator(RecordAccessor(nullptr));
+ return record_iterator(getRecord(0));
+ }
+
+ /// End iterator for records.
+ record_iterator records_end() const {
+ // Records need to be handled specially, since we cache the start addresses
+ // for them: We can't just compute the 1-past-the-end address, we have to
+ // look at the last record and use the 'next' method.
+ if (getNumRecords() == 0)
+ return record_iterator(RecordAccessor(nullptr));
+ return record_iterator(getRecord(getNumRecords() - 1).next());
+ }
+
+ /// Iterator range for records.
+ iterator_range<record_iterator> records() const {
+ return make_range(records_begin(), records_end());
+ }
+
+private:
+ template <typename T>
+ static T read(const uint8_t *P) {
+ return support::endian::read<T, Endianness, 1>(P);
+ }
+
+ static const unsigned HeaderOffset = 0;
+ static const unsigned NumFunctionsOffset = HeaderOffset + sizeof(uint32_t);
+ static const unsigned NumConstantsOffset = NumFunctionsOffset + sizeof(uint32_t);
+ static const unsigned NumRecordsOffset = NumConstantsOffset + sizeof(uint32_t);
+ static const unsigned FunctionListOffset = NumRecordsOffset + sizeof(uint32_t);
+
+ static const unsigned FunctionSize = 3 * sizeof(uint64_t);
+ static const unsigned ConstantSize = sizeof(uint64_t);
+
+ std::size_t getFunctionOffset(unsigned FunctionIndex) const {
+ return FunctionListOffset + FunctionIndex * FunctionSize;
+ }
+
+ std::size_t getConstantOffset(unsigned ConstantIndex) const {
+ return ConstantsListOffset + ConstantIndex * ConstantSize;
+ }
+
+ ArrayRef<uint8_t> StackMapSection;
+ unsigned ConstantsListOffset;
+ std::vector<unsigned> StackMapRecordOffsets;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_STACKMAPPARSER_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/SymbolSize.h b/contrib/libs/llvm12/include/llvm/Object/SymbolSize.h
index ae0fb0b12ff..6d7b7442af2 100644
--- a/contrib/libs/llvm12/include/llvm/Object/SymbolSize.h
+++ b/contrib/libs/llvm12/include/llvm/Object/SymbolSize.h
@@ -1,44 +1,44 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- SymbolSize.h ---------------------------------------------*- 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
-//
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_SYMBOLSIZE_H
-#define LLVM_OBJECT_SYMBOLSIZE_H
-
-#include "llvm/Object/ObjectFile.h"
-
-namespace llvm {
-namespace object {
-
-struct SymEntry {
- symbol_iterator I;
- uint64_t Address;
- unsigned Number;
- unsigned SectionID;
-};
-
-int compareAddress(const SymEntry *A, const SymEntry *B);
-
-std::vector<std::pair<SymbolRef, uint64_t>>
-computeSymbolSizes(const ObjectFile &O);
-
-}
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- SymbolSize.h ---------------------------------------------*- 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
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLSIZE_H
+#define LLVM_OBJECT_SYMBOLSIZE_H
+
+#include "llvm/Object/ObjectFile.h"
+
+namespace llvm {
+namespace object {
+
+struct SymEntry {
+ symbol_iterator I;
+ uint64_t Address;
+ unsigned Number;
+ unsigned SectionID;
+};
+
+int compareAddress(const SymEntry *A, const SymEntry *B);
+
+std::vector<std::pair<SymbolRef, uint64_t>>
+computeSymbolSizes(const ObjectFile &O);
+
+}
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h b/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h
index 928c0ad8b35..d890fd2aa58 100644
--- a/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/SymbolicFile.h
@@ -1,224 +1,224 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- SymbolicFile.h - Interface that only provides symbols ----*- 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 SymbolicFile interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_SYMBOLICFILE_H
-#define LLVM_OBJECT_SYMBOLICFILE_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/BinaryFormat/Magic.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cinttypes>
-#include <cstdint>
-#include <cstring>
-#include <iterator>
-#include <memory>
-#include <system_error>
-
-namespace llvm {
-namespace object {
-
-union DataRefImpl {
- // This entire union should probably be a
- // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
- struct {
- uint32_t a, b;
- } d;
- uintptr_t p;
-
- DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
-};
-
-template <typename OStream>
-OStream& operator<<(OStream &OS, const DataRefImpl &D) {
- OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
- << ", " << format("0x%08x", D.d.b) << "))";
- return OS;
-}
-
-inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
- // Check bitwise identical. This is the only legal way to compare a union w/o
- // knowing which member is in use.
- return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
-}
-
-inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
- return !operator==(a, b);
-}
-
-inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
- // Check bitwise identical. This is the only legal way to compare a union w/o
- // knowing which member is in use.
- return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
-}
-
-template <class content_type>
-class content_iterator
- : public std::iterator<std::forward_iterator_tag, content_type> {
- content_type Current;
-
-public:
- content_iterator(content_type symb) : Current(std::move(symb)) {}
-
- const content_type *operator->() const { return &Current; }
-
- const content_type &operator*() const { return Current; }
-
- bool operator==(const content_iterator &other) const {
- return Current == other.Current;
- }
-
- bool operator!=(const content_iterator &other) const {
- return !(*this == other);
- }
-
- content_iterator &operator++() { // preincrement
- Current.moveNext();
- return *this;
- }
-};
-
-class SymbolicFile;
-
-/// This is a value type class that represents a single symbol in the list of
-/// symbols in the object file.
-class BasicSymbolRef {
- DataRefImpl SymbolPimpl;
- const SymbolicFile *OwningObject = nullptr;
-
-public:
- enum Flags : unsigned {
- SF_None = 0,
- SF_Undefined = 1U << 0, // Symbol is defined in another object file
- SF_Global = 1U << 1, // Global symbol
- SF_Weak = 1U << 2, // Weak symbol
- SF_Absolute = 1U << 3, // Absolute symbol
- SF_Common = 1U << 4, // Symbol has common linkage
- SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
- SF_Exported = 1U << 6, // Symbol is visible to other DSOs
- SF_FormatSpecific = 1U << 7, // Specific to the object file format
- // (e.g. section symbols)
- SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
- SF_Hidden = 1U << 9, // Symbol has hidden visibility
- SF_Const = 1U << 10, // Symbol value is constant
- SF_Executable = 1U << 11, // Symbol points to an executable section
- // (IR only)
- };
-
- BasicSymbolRef() = default;
- BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
-
- bool operator==(const BasicSymbolRef &Other) const;
- bool operator<(const BasicSymbolRef &Other) const;
-
- void moveNext();
-
- Error printName(raw_ostream &OS) const;
-
- /// Get symbol flags (bitwise OR of SymbolRef::Flags)
- Expected<uint32_t> getFlags() const;
-
- DataRefImpl getRawDataRefImpl() const;
- const SymbolicFile *getObject() const;
-};
-
-using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
-
-class SymbolicFile : public Binary {
-public:
- SymbolicFile(unsigned int Type, MemoryBufferRef Source);
- ~SymbolicFile() override;
-
- // virtual interface.
- virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
-
- virtual Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const = 0;
-
- virtual Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const = 0;
-
- virtual basic_symbol_iterator symbol_begin() const = 0;
-
- virtual basic_symbol_iterator symbol_end() const = 0;
-
- // convenience wrappers.
- using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
- basic_symbol_iterator_range symbols() const {
- return basic_symbol_iterator_range(symbol_begin(), symbol_end());
- }
-
- // construction aux.
- static Expected<std::unique_ptr<SymbolicFile>>
- createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- SymbolicFile.h - Interface that only provides symbols ----*- 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 SymbolicFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_SYMBOLICFILE_H
+#define LLVM_OBJECT_SYMBOLICFILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cinttypes>
+#include <cstdint>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <system_error>
+
+namespace llvm {
+namespace object {
+
+union DataRefImpl {
+ // This entire union should probably be a
+ // char[max(8, sizeof(uintptr_t))] and require the impl to cast.
+ struct {
+ uint32_t a, b;
+ } d;
+ uintptr_t p;
+
+ DataRefImpl() { std::memset(this, 0, sizeof(DataRefImpl)); }
+};
+
+template <typename OStream>
+OStream& operator<<(OStream &OS, const DataRefImpl &D) {
+ OS << "(" << format("0x%08" PRIxPTR, D.p) << " (" << format("0x%08x", D.d.a)
+ << ", " << format("0x%08x", D.d.b) << "))";
+ return OS;
+}
+
+inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
+}
+
+inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
+ return !operator==(a, b);
+}
+
+inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
+ // Check bitwise identical. This is the only legal way to compare a union w/o
+ // knowing which member is in use.
+ return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
+}
+
+template <class content_type>
+class content_iterator
+ : public std::iterator<std::forward_iterator_tag, content_type> {
+ content_type Current;
+
+public:
+ content_iterator(content_type symb) : Current(std::move(symb)) {}
+
+ const content_type *operator->() const { return &Current; }
+
+ const content_type &operator*() const { return Current; }
+
+ bool operator==(const content_iterator &other) const {
+ return Current == other.Current;
+ }
+
+ bool operator!=(const content_iterator &other) const {
+ return !(*this == other);
+ }
+
+ content_iterator &operator++() { // preincrement
+ Current.moveNext();
+ return *this;
+ }
+};
+
+class SymbolicFile;
+
+/// This is a value type class that represents a single symbol in the list of
+/// symbols in the object file.
+class BasicSymbolRef {
+ DataRefImpl SymbolPimpl;
+ const SymbolicFile *OwningObject = nullptr;
+
+public:
+ enum Flags : unsigned {
+ SF_None = 0,
+ SF_Undefined = 1U << 0, // Symbol is defined in another object file
+ SF_Global = 1U << 1, // Global symbol
+ SF_Weak = 1U << 2, // Weak symbol
+ SF_Absolute = 1U << 3, // Absolute symbol
+ SF_Common = 1U << 4, // Symbol has common linkage
+ SF_Indirect = 1U << 5, // Symbol is an alias to another symbol
+ SF_Exported = 1U << 6, // Symbol is visible to other DSOs
+ SF_FormatSpecific = 1U << 7, // Specific to the object file format
+ // (e.g. section symbols)
+ SF_Thumb = 1U << 8, // Thumb symbol in a 32-bit ARM binary
+ SF_Hidden = 1U << 9, // Symbol has hidden visibility
+ SF_Const = 1U << 10, // Symbol value is constant
+ SF_Executable = 1U << 11, // Symbol points to an executable section
+ // (IR only)
+ };
+
+ BasicSymbolRef() = default;
+ BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner);
+
+ bool operator==(const BasicSymbolRef &Other) const;
+ bool operator<(const BasicSymbolRef &Other) const;
+
+ void moveNext();
+
+ Error printName(raw_ostream &OS) const;
+
+ /// Get symbol flags (bitwise OR of SymbolRef::Flags)
+ Expected<uint32_t> getFlags() const;
+
+ DataRefImpl getRawDataRefImpl() const;
+ const SymbolicFile *getObject() const;
+};
+
+using basic_symbol_iterator = content_iterator<BasicSymbolRef>;
+
+class SymbolicFile : public Binary {
+public:
+ SymbolicFile(unsigned int Type, MemoryBufferRef Source);
+ ~SymbolicFile() override;
+
+ // virtual interface.
+ virtual void moveSymbolNext(DataRefImpl &Symb) const = 0;
+
+ virtual Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const = 0;
+
+ virtual Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const = 0;
+
+ virtual basic_symbol_iterator symbol_begin() const = 0;
+
+ virtual basic_symbol_iterator symbol_end() const = 0;
+
+ // convenience wrappers.
+ using basic_symbol_iterator_range = iterator_range<basic_symbol_iterator>;
+ basic_symbol_iterator_range symbols() const {
+ return basic_symbol_iterator_range(symbol_begin(), symbol_end());
+ }
+
+ // construction aux.
+ static Expected<std::unique_ptr<SymbolicFile>>
+ createSymbolicFile(MemoryBufferRef Object, llvm::file_magic Type,
LLVMContext *Context, bool InitContent = true);
-
- static Expected<std::unique_ptr<SymbolicFile>>
- createSymbolicFile(MemoryBufferRef Object) {
- return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
- }
-
- static bool classof(const Binary *v) {
- return v->isSymbolic();
- }
+
+ static Expected<std::unique_ptr<SymbolicFile>>
+ createSymbolicFile(MemoryBufferRef Object) {
+ return createSymbolicFile(Object, llvm::file_magic::unknown, nullptr);
+ }
+
+ static bool classof(const Binary *v) {
+ return v->isSymbolic();
+ }
static bool isSymbolicFile(file_magic Type, const LLVMContext *Context);
-};
-
-inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
- const SymbolicFile *Owner)
- : SymbolPimpl(SymbolP), OwningObject(Owner) {}
-
-inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
- return SymbolPimpl == Other.SymbolPimpl;
-}
-
-inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
- return SymbolPimpl < Other.SymbolPimpl;
-}
-
-inline void BasicSymbolRef::moveNext() {
- return OwningObject->moveSymbolNext(SymbolPimpl);
-}
-
-inline Error BasicSymbolRef::printName(raw_ostream &OS) const {
- return OwningObject->printSymbolName(OS, SymbolPimpl);
-}
-
-inline Expected<uint32_t> BasicSymbolRef::getFlags() const {
- return OwningObject->getSymbolFlags(SymbolPimpl);
-}
-
-inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
- return SymbolPimpl;
-}
-
-inline const SymbolicFile *BasicSymbolRef::getObject() const {
- return OwningObject;
-}
-
-} // end namespace object
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_SYMBOLICFILE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+};
+
+inline BasicSymbolRef::BasicSymbolRef(DataRefImpl SymbolP,
+ const SymbolicFile *Owner)
+ : SymbolPimpl(SymbolP), OwningObject(Owner) {}
+
+inline bool BasicSymbolRef::operator==(const BasicSymbolRef &Other) const {
+ return SymbolPimpl == Other.SymbolPimpl;
+}
+
+inline bool BasicSymbolRef::operator<(const BasicSymbolRef &Other) const {
+ return SymbolPimpl < Other.SymbolPimpl;
+}
+
+inline void BasicSymbolRef::moveNext() {
+ return OwningObject->moveSymbolNext(SymbolPimpl);
+}
+
+inline Error BasicSymbolRef::printName(raw_ostream &OS) const {
+ return OwningObject->printSymbolName(OS, SymbolPimpl);
+}
+
+inline Expected<uint32_t> BasicSymbolRef::getFlags() const {
+ return OwningObject->getSymbolFlags(SymbolPimpl);
+}
+
+inline DataRefImpl BasicSymbolRef::getRawDataRefImpl() const {
+ return SymbolPimpl;
+}
+
+inline const SymbolicFile *BasicSymbolRef::getObject() const {
+ return OwningObject;
+}
+
+} // end namespace object
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_SYMBOLICFILE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/TapiFile.h b/contrib/libs/llvm12/include/llvm/Object/TapiFile.h
index 04c07c01cbc..89b2b18e983 100644
--- a/contrib/libs/llvm12/include/llvm/Object/TapiFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/TapiFile.h
@@ -1,74 +1,74 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- TapiFile.h - Text-based Dynamic Library Stub -------------*- 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 TapiFile interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_TAPI_FILE_H
-#define LLVM_OBJECT_TAPI_FILE_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Object/SymbolicFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/TextAPI/MachO/InterfaceFile.h"
-
-namespace llvm {
-namespace object {
-
-class TapiFile : public SymbolicFile {
-public:
- TapiFile(MemoryBufferRef Source, const MachO::InterfaceFile &interface,
- MachO::Architecture Arch);
- ~TapiFile() override;
-
- void moveSymbolNext(DataRefImpl &DRI) const override;
-
- Error printSymbolName(raw_ostream &OS, DataRefImpl DRI) const override;
-
- Expected<uint32_t> getSymbolFlags(DataRefImpl DRI) const override;
-
- basic_symbol_iterator symbol_begin() const override;
-
- basic_symbol_iterator symbol_end() const override;
-
- static bool classof(const Binary *v) { return v->isTapiFile(); }
-
- bool is64Bit() { return MachO::is64Bit(Arch); }
-
-private:
- struct Symbol {
- StringRef Prefix;
- StringRef Name;
- uint32_t Flags;
-
- constexpr Symbol(StringRef Prefix, StringRef Name, uint32_t Flags)
- : Prefix(Prefix), Name(Name), Flags(Flags) {}
- };
-
- std::vector<Symbol> Symbols;
- MachO::Architecture Arch;
-};
-
-} // end namespace object.
-} // end namespace llvm.
-
-#endif // LLVM_OBJECT_TAPI_FILE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- TapiFile.h - Text-based Dynamic Library Stub -------------*- 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 TapiFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_TAPI_FILE_H
+#define LLVM_OBJECT_TAPI_FILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+
+namespace llvm {
+namespace object {
+
+class TapiFile : public SymbolicFile {
+public:
+ TapiFile(MemoryBufferRef Source, const MachO::InterfaceFile &interface,
+ MachO::Architecture Arch);
+ ~TapiFile() override;
+
+ void moveSymbolNext(DataRefImpl &DRI) const override;
+
+ Error printSymbolName(raw_ostream &OS, DataRefImpl DRI) const override;
+
+ Expected<uint32_t> getSymbolFlags(DataRefImpl DRI) const override;
+
+ basic_symbol_iterator symbol_begin() const override;
+
+ basic_symbol_iterator symbol_end() const override;
+
+ static bool classof(const Binary *v) { return v->isTapiFile(); }
+
+ bool is64Bit() { return MachO::is64Bit(Arch); }
+
+private:
+ struct Symbol {
+ StringRef Prefix;
+ StringRef Name;
+ uint32_t Flags;
+
+ constexpr Symbol(StringRef Prefix, StringRef Name, uint32_t Flags)
+ : Prefix(Prefix), Name(Name), Flags(Flags) {}
+ };
+
+ std::vector<Symbol> Symbols;
+ MachO::Architecture Arch;
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif // LLVM_OBJECT_TAPI_FILE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/TapiUniversal.h b/contrib/libs/llvm12/include/llvm/Object/TapiUniversal.h
index 20eed191dd4..7b7cb43f955 100644
--- a/contrib/libs/llvm12/include/llvm/Object/TapiUniversal.h
+++ b/contrib/libs/llvm12/include/llvm/Object/TapiUniversal.h
@@ -1,132 +1,132 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- TapiUniversal.h - Text-based Dynamic Library Stub -------*- 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 TapiUniversal interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_TAPI_UNIVERSAL_H
-#define LLVM_OBJECT_TAPI_UNIVERSAL_H
-
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/TapiFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/TextAPI/MachO/Architecture.h"
-#include "llvm/TextAPI/MachO/InterfaceFile.h"
-
-namespace llvm {
-namespace object {
-
-class TapiUniversal : public Binary {
-public:
- class ObjectForArch {
- const TapiUniversal *Parent;
- int Index;
-
- public:
- ObjectForArch(const TapiUniversal *Parent, int Index)
- : Parent(Parent), Index(Index) {}
-
- ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
-
- bool operator==(const ObjectForArch &Other) const {
- return (Parent == Other.Parent) && (Index == Other.Index);
- }
-
- uint32_t getCPUType() const {
- auto Result =
- MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
- return Result.first;
- }
-
- uint32_t getCPUSubType() const {
- auto Result =
- MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
- return Result.second;
- }
-
- StringRef getArchFlagName() const {
- return MachO::getArchitectureName(Parent->Libraries[Index].Arch);
- }
-
- std::string getInstallName() const {
- return std::string(Parent->Libraries[Index].InstallName);
- }
-
- bool isTopLevelLib() const {
- return Parent->ParsedFile->getInstallName() == getInstallName();
- }
-
- Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
- };
-
- class object_iterator {
- ObjectForArch Obj;
-
- public:
- object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
- const ObjectForArch *operator->() const { return &Obj; }
- const ObjectForArch &operator*() const { return Obj; }
-
- bool operator==(const object_iterator &Other) const {
- return Obj == Other.Obj;
- }
- bool operator!=(const object_iterator &Other) const {
- return !(*this == Other);
- }
-
- object_iterator &operator++() { // Preincrement
- Obj = Obj.getNext();
- return *this;
- }
- };
-
- TapiUniversal(MemoryBufferRef Source, Error &Err);
- static Expected<std::unique_ptr<TapiUniversal>>
- create(MemoryBufferRef Source);
- ~TapiUniversal() override;
-
- object_iterator begin_objects() const { return ObjectForArch(this, 0); }
- object_iterator end_objects() const {
- return ObjectForArch(this, Libraries.size());
- }
-
- iterator_range<object_iterator> objects() const {
- return make_range(begin_objects(), end_objects());
- }
-
- uint32_t getNumberOfObjects() const { return Libraries.size(); }
-
- static bool classof(const Binary *v) { return v->isTapiUniversal(); }
-
-private:
- struct Library {
- StringRef InstallName;
- MachO::Architecture Arch;
- };
-
- std::unique_ptr<MachO::InterfaceFile> ParsedFile;
- std::vector<Library> Libraries;
-};
-
-} // end namespace object.
-} // end namespace llvm.
-
-#endif // LLVM_OBJECT_TAPI_UNIVERSAL_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- TapiUniversal.h - Text-based Dynamic Library Stub -------*- 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 TapiUniversal interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_TAPI_UNIVERSAL_H
+#define LLVM_OBJECT_TAPI_UNIVERSAL_H
+
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/TapiFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TextAPI/MachO/Architecture.h"
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+
+namespace llvm {
+namespace object {
+
+class TapiUniversal : public Binary {
+public:
+ class ObjectForArch {
+ const TapiUniversal *Parent;
+ int Index;
+
+ public:
+ ObjectForArch(const TapiUniversal *Parent, int Index)
+ : Parent(Parent), Index(Index) {}
+
+ ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
+
+ bool operator==(const ObjectForArch &Other) const {
+ return (Parent == Other.Parent) && (Index == Other.Index);
+ }
+
+ uint32_t getCPUType() const {
+ auto Result =
+ MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
+ return Result.first;
+ }
+
+ uint32_t getCPUSubType() const {
+ auto Result =
+ MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
+ return Result.second;
+ }
+
+ StringRef getArchFlagName() const {
+ return MachO::getArchitectureName(Parent->Libraries[Index].Arch);
+ }
+
+ std::string getInstallName() const {
+ return std::string(Parent->Libraries[Index].InstallName);
+ }
+
+ bool isTopLevelLib() const {
+ return Parent->ParsedFile->getInstallName() == getInstallName();
+ }
+
+ Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
+ };
+
+ class object_iterator {
+ ObjectForArch Obj;
+
+ public:
+ object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
+ const ObjectForArch *operator->() const { return &Obj; }
+ const ObjectForArch &operator*() const { return Obj; }
+
+ bool operator==(const object_iterator &Other) const {
+ return Obj == Other.Obj;
+ }
+ bool operator!=(const object_iterator &Other) const {
+ return !(*this == Other);
+ }
+
+ object_iterator &operator++() { // Preincrement
+ Obj = Obj.getNext();
+ return *this;
+ }
+ };
+
+ TapiUniversal(MemoryBufferRef Source, Error &Err);
+ static Expected<std::unique_ptr<TapiUniversal>>
+ create(MemoryBufferRef Source);
+ ~TapiUniversal() override;
+
+ object_iterator begin_objects() const { return ObjectForArch(this, 0); }
+ object_iterator end_objects() const {
+ return ObjectForArch(this, Libraries.size());
+ }
+
+ iterator_range<object_iterator> objects() const {
+ return make_range(begin_objects(), end_objects());
+ }
+
+ uint32_t getNumberOfObjects() const { return Libraries.size(); }
+
+ static bool classof(const Binary *v) { return v->isTapiUniversal(); }
+
+private:
+ struct Library {
+ StringRef InstallName;
+ MachO::Architecture Arch;
+ };
+
+ std::unique_ptr<MachO::InterfaceFile> ParsedFile;
+ std::vector<Library> Libraries;
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif // LLVM_OBJECT_TAPI_UNIVERSAL_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/Wasm.h b/contrib/libs/llvm12/include/llvm/Object/Wasm.h
index 80e3ddd109f..8f12bd09102 100644
--- a/contrib/libs/llvm12/include/llvm/Object/Wasm.h
+++ b/contrib/libs/llvm12/include/llvm/Object/Wasm.h
@@ -1,381 +1,381 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- Wasm.h - Wasm object file implementation -----------------*- 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 WasmObjectFile class, which implements the ObjectFile
-// interface for Wasm files.
-//
-// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_WASM_H
-#define LLVM_OBJECT_WASM_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Wasm.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/MC/MCSymbolWasm.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include <cstddef>
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-namespace object {
-
-class WasmSymbol {
-public:
- WasmSymbol(const wasm::WasmSymbolInfo &Info,
- const wasm::WasmGlobalType *GlobalType,
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Wasm.h - Wasm object file implementation -----------------*- 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 WasmObjectFile class, which implements the ObjectFile
+// interface for Wasm files.
+//
+// See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_WASM_H
+#define LLVM_OBJECT_WASM_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace object {
+
+class WasmSymbol {
+public:
+ WasmSymbol(const wasm::WasmSymbolInfo &Info,
+ const wasm::WasmGlobalType *GlobalType,
const wasm::WasmTableType *TableType,
- const wasm::WasmEventType *EventType,
- const wasm::WasmSignature *Signature)
+ const wasm::WasmEventType *EventType,
+ const wasm::WasmSignature *Signature)
: Info(Info), GlobalType(GlobalType), TableType(TableType),
EventType(EventType), Signature(Signature) {}
-
- const wasm::WasmSymbolInfo &Info;
- const wasm::WasmGlobalType *GlobalType;
+
+ const wasm::WasmSymbolInfo &Info;
+ const wasm::WasmGlobalType *GlobalType;
const wasm::WasmTableType *TableType;
- const wasm::WasmEventType *EventType;
- const wasm::WasmSignature *Signature;
-
- bool isTypeFunction() const {
- return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
- }
-
+ const wasm::WasmEventType *EventType;
+ const wasm::WasmSignature *Signature;
+
+ bool isTypeFunction() const {
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
+ }
+
bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
- bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
-
- bool isTypeGlobal() const {
- return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
- }
-
- bool isTypeSection() const {
- return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
- }
-
- bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
-
- bool isDefined() const { return !isUndefined(); }
-
- bool isUndefined() const {
- return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
- }
-
- bool isBindingWeak() const {
- return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
- }
-
- bool isBindingGlobal() const {
- return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
- }
-
- bool isBindingLocal() const {
- return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
- }
-
- unsigned getBinding() const {
- return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
- }
-
- bool isHidden() const {
- return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
- }
-
- unsigned getVisibility() const {
- return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
- }
-
- void print(raw_ostream &Out) const;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-struct WasmSection {
- WasmSection() = default;
-
- uint32_t Type = 0; // Section type (See below)
- uint32_t Offset = 0; // Offset with in the file
- StringRef Name; // Section name (User-defined sections only)
+ bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
+
+ bool isTypeGlobal() const {
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
+ }
+
+ bool isTypeSection() const {
+ return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
+ }
+
+ bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
+
+ bool isDefined() const { return !isUndefined(); }
+
+ bool isUndefined() const {
+ return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
+ }
+
+ bool isBindingWeak() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
+ }
+
+ bool isBindingGlobal() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
+ }
+
+ bool isBindingLocal() const {
+ return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
+ }
+
+ unsigned getBinding() const {
+ return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
+ }
+
+ bool isHidden() const {
+ return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
+ }
+
+ unsigned getVisibility() const {
+ return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
+ }
+
+ void print(raw_ostream &Out) const;
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const;
+#endif
+};
+
+struct WasmSection {
+ WasmSection() = default;
+
+ uint32_t Type = 0; // Section type (See below)
+ uint32_t Offset = 0; // Offset with in the file
+ StringRef Name; // Section name (User-defined sections only)
uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
- ArrayRef<uint8_t> Content; // Section content
- std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
-};
-
-struct WasmSegment {
- uint32_t SectionOffset;
- wasm::WasmDataSegment Data;
-};
-
-class WasmObjectFile : public ObjectFile {
-
-public:
- WasmObjectFile(MemoryBufferRef Object, Error &Err);
-
- const wasm::WasmObjectHeader &getHeader() const;
- const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
- const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
- const WasmSection &getWasmSection(const SectionRef &Section) const;
- const wasm::WasmRelocation &getWasmRelocation(const RelocationRef &Ref) const;
-
- static bool classof(const Binary *v) { return v->isWasm(); }
-
- const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
- const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
- ArrayRef<wasm::WasmFeatureEntry> getTargetFeatures() const {
- return TargetFeatures;
- }
- ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
- ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
- ArrayRef<wasm::WasmImport> imports() const { return Imports; }
- ArrayRef<wasm::WasmTable> tables() const { return Tables; }
- ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
- ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
- ArrayRef<wasm::WasmEvent> events() const { return Events; }
- ArrayRef<wasm::WasmExport> exports() const { return Exports; }
- ArrayRef<WasmSymbol> syms() const { return Symbols; }
- const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
- uint32_t getNumberOfSymbols() const { return Symbols.size(); }
- ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
- ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
- ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
+ ArrayRef<uint8_t> Content; // Section content
+ std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
+};
+
+struct WasmSegment {
+ uint32_t SectionOffset;
+ wasm::WasmDataSegment Data;
+};
+
+class WasmObjectFile : public ObjectFile {
+
+public:
+ WasmObjectFile(MemoryBufferRef Object, Error &Err);
+
+ const wasm::WasmObjectHeader &getHeader() const;
+ const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
+ const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
+ const WasmSection &getWasmSection(const SectionRef &Section) const;
+ const wasm::WasmRelocation &getWasmRelocation(const RelocationRef &Ref) const;
+
+ static bool classof(const Binary *v) { return v->isWasm(); }
+
+ const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
+ const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
+ ArrayRef<wasm::WasmFeatureEntry> getTargetFeatures() const {
+ return TargetFeatures;
+ }
+ ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
+ ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
+ ArrayRef<wasm::WasmImport> imports() const { return Imports; }
+ ArrayRef<wasm::WasmTable> tables() const { return Tables; }
+ ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
+ ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
+ ArrayRef<wasm::WasmEvent> events() const { return Events; }
+ ArrayRef<wasm::WasmExport> exports() const { return Exports; }
+ ArrayRef<WasmSymbol> syms() const { return Symbols; }
+ const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
+ uint32_t getNumberOfSymbols() const { return Symbols.size(); }
+ ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
+ ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
+ ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
ArrayRef<wasm::WasmDebugName> debugNames() const { return DebugNames; }
- uint32_t startFunction() const { return StartFunction; }
- uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
+ uint32_t startFunction() const { return StartFunction; }
+ uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
uint32_t getNumImportedTables() const { return NumImportedTables; }
- uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
- uint32_t getNumImportedEvents() const { return NumImportedEvents; }
- uint32_t getNumSections() const { return Sections.size(); }
- void moveSymbolNext(DataRefImpl &Symb) const override;
-
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
-
- basic_symbol_iterator symbol_begin() const override;
-
- basic_symbol_iterator symbol_end() const override;
- Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
-
- Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
- uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const;
- uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
- uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
- uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
- Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
- uint32_t getSymbolSectionId(SymbolRef Sym) const;
-
- // Overrides from SectionRef.
- void moveSectionNext(DataRefImpl &Sec) const override;
- Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
- uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
- uint64_t getSectionSize(DataRefImpl Sec) const override;
- Expected<ArrayRef<uint8_t>>
- getSectionContents(DataRefImpl Sec) const override;
- uint64_t getSectionAlignment(DataRefImpl Sec) const override;
- bool isSectionCompressed(DataRefImpl Sec) const override;
- bool isSectionText(DataRefImpl Sec) const override;
- bool isSectionData(DataRefImpl Sec) const override;
- bool isSectionBSS(DataRefImpl Sec) const override;
- bool isSectionVirtual(DataRefImpl Sec) const override;
- relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
- relocation_iterator section_rel_end(DataRefImpl Sec) const override;
-
- // Overrides from RelocationRef.
- void moveRelocationNext(DataRefImpl &Rel) const override;
- uint64_t getRelocationOffset(DataRefImpl Rel) const override;
- symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- uint64_t getRelocationType(DataRefImpl Rel) const override;
- void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
-
- section_iterator section_begin() const override;
- section_iterator section_end() const override;
- uint8_t getBytesInAddress() const override;
- StringRef getFileFormatName() const override;
- Triple::ArchType getArch() const override;
- SubtargetFeatures getFeatures() const override;
- bool isRelocatableObject() const override;
- bool isSharedObject() const;
-
- struct ReadContext {
- const uint8_t *Start;
- const uint8_t *Ptr;
- const uint8_t *End;
- };
-
-private:
- bool isValidFunctionIndex(uint32_t Index) const;
- bool isDefinedFunctionIndex(uint32_t Index) const;
- bool isValidGlobalIndex(uint32_t Index) const;
+ uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
+ uint32_t getNumImportedEvents() const { return NumImportedEvents; }
+ uint32_t getNumSections() const { return Sections.size(); }
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+
+ basic_symbol_iterator symbol_begin() const override;
+
+ basic_symbol_iterator symbol_end() const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ uint32_t getSymbolSectionId(SymbolRef Sym) const;
+
+ // Overrides from SectionRef.
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ // Overrides from RelocationRef.
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override;
+ bool isRelocatableObject() const override;
+ bool isSharedObject() const;
+
+ struct ReadContext {
+ const uint8_t *Start;
+ const uint8_t *Ptr;
+ const uint8_t *End;
+ };
+
+private:
+ bool isValidFunctionIndex(uint32_t Index) const;
+ bool isDefinedFunctionIndex(uint32_t Index) const;
+ bool isValidGlobalIndex(uint32_t Index) const;
bool isValidTableIndex(uint32_t Index) const;
- bool isDefinedGlobalIndex(uint32_t Index) const;
+ bool isDefinedGlobalIndex(uint32_t Index) const;
bool isDefinedTableIndex(uint32_t Index) const;
- bool isValidEventIndex(uint32_t Index) const;
- bool isDefinedEventIndex(uint32_t Index) const;
- bool isValidFunctionSymbol(uint32_t Index) const;
+ bool isValidEventIndex(uint32_t Index) const;
+ bool isDefinedEventIndex(uint32_t Index) const;
+ bool isValidFunctionSymbol(uint32_t Index) const;
bool isValidTableSymbol(uint32_t Index) const;
- bool isValidGlobalSymbol(uint32_t Index) const;
- bool isValidEventSymbol(uint32_t Index) const;
- bool isValidDataSymbol(uint32_t Index) const;
- bool isValidSectionSymbol(uint32_t Index) const;
- wasm::WasmFunction &getDefinedFunction(uint32_t Index);
- const wasm::WasmFunction &getDefinedFunction(uint32_t Index) const;
- wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
- wasm::WasmEvent &getDefinedEvent(uint32_t Index);
-
- const WasmSection &getWasmSection(DataRefImpl Ref) const;
- const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
- uint32_t getSymbolSectionIdImpl(const WasmSymbol &Symb) const;
-
- Error parseSection(WasmSection &Sec);
- Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx);
-
- // Standard section types
- Error parseTypeSection(ReadContext &Ctx);
- Error parseImportSection(ReadContext &Ctx);
- Error parseFunctionSection(ReadContext &Ctx);
- Error parseTableSection(ReadContext &Ctx);
- Error parseMemorySection(ReadContext &Ctx);
- Error parseEventSection(ReadContext &Ctx);
- Error parseGlobalSection(ReadContext &Ctx);
- Error parseExportSection(ReadContext &Ctx);
- Error parseStartSection(ReadContext &Ctx);
- Error parseElemSection(ReadContext &Ctx);
- Error parseCodeSection(ReadContext &Ctx);
- Error parseDataSection(ReadContext &Ctx);
- Error parseDataCountSection(ReadContext &Ctx);
-
- // Custom section types
- Error parseDylinkSection(ReadContext &Ctx);
- Error parseNameSection(ReadContext &Ctx);
- Error parseLinkingSection(ReadContext &Ctx);
- Error parseLinkingSectionSymtab(ReadContext &Ctx);
- Error parseLinkingSectionComdat(ReadContext &Ctx);
- Error parseProducersSection(ReadContext &Ctx);
- Error parseTargetFeaturesSection(ReadContext &Ctx);
- Error parseRelocSection(StringRef Name, ReadContext &Ctx);
-
- wasm::WasmObjectHeader Header;
- std::vector<WasmSection> Sections;
- wasm::WasmDylinkInfo DylinkInfo;
- wasm::WasmProducerInfo ProducerInfo;
- std::vector<wasm::WasmFeatureEntry> TargetFeatures;
- std::vector<wasm::WasmSignature> Signatures;
- std::vector<uint32_t> FunctionTypes;
- std::vector<wasm::WasmTable> Tables;
- std::vector<wasm::WasmLimits> Memories;
- std::vector<wasm::WasmGlobal> Globals;
- std::vector<wasm::WasmEvent> Events;
- std::vector<wasm::WasmImport> Imports;
- std::vector<wasm::WasmExport> Exports;
- std::vector<wasm::WasmElemSegment> ElemSegments;
- std::vector<WasmSegment> DataSegments;
- llvm::Optional<size_t> DataCount;
- std::vector<wasm::WasmFunction> Functions;
- std::vector<WasmSymbol> Symbols;
+ bool isValidGlobalSymbol(uint32_t Index) const;
+ bool isValidEventSymbol(uint32_t Index) const;
+ bool isValidDataSymbol(uint32_t Index) const;
+ bool isValidSectionSymbol(uint32_t Index) const;
+ wasm::WasmFunction &getDefinedFunction(uint32_t Index);
+ const wasm::WasmFunction &getDefinedFunction(uint32_t Index) const;
+ wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
+ wasm::WasmEvent &getDefinedEvent(uint32_t Index);
+
+ const WasmSection &getWasmSection(DataRefImpl Ref) const;
+ const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
+ uint32_t getSymbolSectionIdImpl(const WasmSymbol &Symb) const;
+
+ Error parseSection(WasmSection &Sec);
+ Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx);
+
+ // Standard section types
+ Error parseTypeSection(ReadContext &Ctx);
+ Error parseImportSection(ReadContext &Ctx);
+ Error parseFunctionSection(ReadContext &Ctx);
+ Error parseTableSection(ReadContext &Ctx);
+ Error parseMemorySection(ReadContext &Ctx);
+ Error parseEventSection(ReadContext &Ctx);
+ Error parseGlobalSection(ReadContext &Ctx);
+ Error parseExportSection(ReadContext &Ctx);
+ Error parseStartSection(ReadContext &Ctx);
+ Error parseElemSection(ReadContext &Ctx);
+ Error parseCodeSection(ReadContext &Ctx);
+ Error parseDataSection(ReadContext &Ctx);
+ Error parseDataCountSection(ReadContext &Ctx);
+
+ // Custom section types
+ Error parseDylinkSection(ReadContext &Ctx);
+ Error parseNameSection(ReadContext &Ctx);
+ Error parseLinkingSection(ReadContext &Ctx);
+ Error parseLinkingSectionSymtab(ReadContext &Ctx);
+ Error parseLinkingSectionComdat(ReadContext &Ctx);
+ Error parseProducersSection(ReadContext &Ctx);
+ Error parseTargetFeaturesSection(ReadContext &Ctx);
+ Error parseRelocSection(StringRef Name, ReadContext &Ctx);
+
+ wasm::WasmObjectHeader Header;
+ std::vector<WasmSection> Sections;
+ wasm::WasmDylinkInfo DylinkInfo;
+ wasm::WasmProducerInfo ProducerInfo;
+ std::vector<wasm::WasmFeatureEntry> TargetFeatures;
+ std::vector<wasm::WasmSignature> Signatures;
+ std::vector<uint32_t> FunctionTypes;
+ std::vector<wasm::WasmTable> Tables;
+ std::vector<wasm::WasmLimits> Memories;
+ std::vector<wasm::WasmGlobal> Globals;
+ std::vector<wasm::WasmEvent> Events;
+ std::vector<wasm::WasmImport> Imports;
+ std::vector<wasm::WasmExport> Exports;
+ std::vector<wasm::WasmElemSegment> ElemSegments;
+ std::vector<WasmSegment> DataSegments;
+ llvm::Optional<size_t> DataCount;
+ std::vector<wasm::WasmFunction> Functions;
+ std::vector<WasmSymbol> Symbols;
std::vector<wasm::WasmDebugName> DebugNames;
- uint32_t StartFunction = -1;
- bool HasLinkingSection = false;
- bool HasDylinkSection = false;
- bool SeenCodeSection = false;
+ uint32_t StartFunction = -1;
+ bool HasLinkingSection = false;
+ bool HasDylinkSection = false;
+ bool SeenCodeSection = false;
bool HasMemory64 = false;
- wasm::WasmLinkingData LinkingData;
- uint32_t NumImportedGlobals = 0;
+ wasm::WasmLinkingData LinkingData;
+ uint32_t NumImportedGlobals = 0;
uint32_t NumImportedTables = 0;
- uint32_t NumImportedFunctions = 0;
- uint32_t NumImportedEvents = 0;
- uint32_t CodeSection = 0;
- uint32_t DataSection = 0;
- uint32_t EventSection = 0;
- uint32_t GlobalSection = 0;
+ uint32_t NumImportedFunctions = 0;
+ uint32_t NumImportedEvents = 0;
+ uint32_t CodeSection = 0;
+ uint32_t DataSection = 0;
+ uint32_t EventSection = 0;
+ uint32_t GlobalSection = 0;
uint32_t TableSection = 0;
-};
-
-class WasmSectionOrderChecker {
-public:
- // We define orders for all core wasm sections and known custom sections.
- enum : int {
- // Sentinel, must be zero
- WASM_SEC_ORDER_NONE = 0,
-
- // Core sections
- WASM_SEC_ORDER_TYPE,
- WASM_SEC_ORDER_IMPORT,
- WASM_SEC_ORDER_FUNCTION,
- WASM_SEC_ORDER_TABLE,
- WASM_SEC_ORDER_MEMORY,
- WASM_SEC_ORDER_EVENT,
- WASM_SEC_ORDER_GLOBAL,
- WASM_SEC_ORDER_EXPORT,
- WASM_SEC_ORDER_START,
- WASM_SEC_ORDER_ELEM,
- WASM_SEC_ORDER_DATACOUNT,
- WASM_SEC_ORDER_CODE,
- WASM_SEC_ORDER_DATA,
-
- // Custom sections
- // "dylink" should be the very first section in the module
- WASM_SEC_ORDER_DYLINK,
- // "linking" section requires DATA section in order to validate data symbols
- WASM_SEC_ORDER_LINKING,
- // Must come after "linking" section in order to validate reloc indexes.
- WASM_SEC_ORDER_RELOC,
- // "name" section must appear after DATA. Comes after "linking" to allow
- // symbol table to set default function name.
- WASM_SEC_ORDER_NAME,
- // "producers" section must appear after "name" section.
- WASM_SEC_ORDER_PRODUCERS,
- // "target_features" section must appear after producers section
- WASM_SEC_ORDER_TARGET_FEATURES,
-
- // Must be last
- WASM_NUM_SEC_ORDERS
-
- };
-
- // Sections that may or may not be present, but cannot be predecessors
- static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS];
-
- bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName = "");
-
-private:
- bool Seen[WASM_NUM_SEC_ORDERS] = {}; // Sections that have been seen already
-
- // Returns -1 for unknown sections.
- int getSectionOrder(unsigned ID, StringRef CustomSectionName = "");
-};
-
-} // end namespace object
-
-inline raw_ostream &operator<<(raw_ostream &OS, const object::WasmSymbol &Sym) {
- Sym.print(OS);
- return OS;
-}
-
-} // end namespace llvm
-
-#endif // LLVM_OBJECT_WASM_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+};
+
+class WasmSectionOrderChecker {
+public:
+ // We define orders for all core wasm sections and known custom sections.
+ enum : int {
+ // Sentinel, must be zero
+ WASM_SEC_ORDER_NONE = 0,
+
+ // Core sections
+ WASM_SEC_ORDER_TYPE,
+ WASM_SEC_ORDER_IMPORT,
+ WASM_SEC_ORDER_FUNCTION,
+ WASM_SEC_ORDER_TABLE,
+ WASM_SEC_ORDER_MEMORY,
+ WASM_SEC_ORDER_EVENT,
+ WASM_SEC_ORDER_GLOBAL,
+ WASM_SEC_ORDER_EXPORT,
+ WASM_SEC_ORDER_START,
+ WASM_SEC_ORDER_ELEM,
+ WASM_SEC_ORDER_DATACOUNT,
+ WASM_SEC_ORDER_CODE,
+ WASM_SEC_ORDER_DATA,
+
+ // Custom sections
+ // "dylink" should be the very first section in the module
+ WASM_SEC_ORDER_DYLINK,
+ // "linking" section requires DATA section in order to validate data symbols
+ WASM_SEC_ORDER_LINKING,
+ // Must come after "linking" section in order to validate reloc indexes.
+ WASM_SEC_ORDER_RELOC,
+ // "name" section must appear after DATA. Comes after "linking" to allow
+ // symbol table to set default function name.
+ WASM_SEC_ORDER_NAME,
+ // "producers" section must appear after "name" section.
+ WASM_SEC_ORDER_PRODUCERS,
+ // "target_features" section must appear after producers section
+ WASM_SEC_ORDER_TARGET_FEATURES,
+
+ // Must be last
+ WASM_NUM_SEC_ORDERS
+
+ };
+
+ // Sections that may or may not be present, but cannot be predecessors
+ static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS];
+
+ bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName = "");
+
+private:
+ bool Seen[WASM_NUM_SEC_ORDERS] = {}; // Sections that have been seen already
+
+ // Returns -1 for unknown sections.
+ int getSectionOrder(unsigned ID, StringRef CustomSectionName = "");
+};
+
+} // end namespace object
+
+inline raw_ostream &operator<<(raw_ostream &OS, const object::WasmSymbol &Sym) {
+ Sym.print(OS);
+ return OS;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_OBJECT_WASM_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/WindowsMachineFlag.h b/contrib/libs/llvm12/include/llvm/Object/WindowsMachineFlag.h
index c6e06c47d09..2de58aa32db 100644
--- a/contrib/libs/llvm12/include/llvm/Object/WindowsMachineFlag.h
+++ b/contrib/libs/llvm12/include/llvm/Object/WindowsMachineFlag.h
@@ -1,44 +1,44 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- WindowsMachineFlag.h -------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Functions for implementing the /machine: flag.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLDRIVERS_MACHINEFLAG_MACHINEFLAG_H
-#define LLVM_TOOLDRIVERS_MACHINEFLAG_MACHINEFLAG_H
-
-namespace llvm {
-
-class StringRef;
-namespace COFF {
-enum MachineTypes : unsigned;
-}
-
-// Returns a user-readable string for ARMNT, ARM64, AMD64, I386.
-// Other MachineTypes values must not be passed in.
-StringRef machineToStr(COFF::MachineTypes MT);
-
-// Maps /machine: arguments to a MachineTypes value.
-// Only returns ARMNT, ARM64, AMD64, I386, or IMAGE_FILE_MACHINE_UNKNOWN.
-COFF::MachineTypes getMachineType(StringRef S);
-
-}
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- WindowsMachineFlag.h -------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Functions for implementing the /machine: flag.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLDRIVERS_MACHINEFLAG_MACHINEFLAG_H
+#define LLVM_TOOLDRIVERS_MACHINEFLAG_MACHINEFLAG_H
+
+namespace llvm {
+
+class StringRef;
+namespace COFF {
+enum MachineTypes : unsigned;
+}
+
+// Returns a user-readable string for ARMNT, ARM64, AMD64, I386.
+// Other MachineTypes values must not be passed in.
+StringRef machineToStr(COFF::MachineTypes MT);
+
+// Maps /machine: arguments to a MachineTypes value.
+// Only returns ARMNT, ARM64, AMD64, I386, or IMAGE_FILE_MACHINE_UNKNOWN.
+COFF::MachineTypes getMachineType(StringRef S);
+
+}
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/WindowsResource.h b/contrib/libs/llvm12/include/llvm/Object/WindowsResource.h
index 42f6885aef9..8920c528a33 100644
--- a/contrib/libs/llvm12/include/llvm/Object/WindowsResource.h
+++ b/contrib/libs/llvm12/include/llvm/Object/WindowsResource.h
@@ -1,282 +1,282 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===-- WindowsResource.h ---------------------------------------*- 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 .res file class. .res files are intermediate
-// products of the typical resource-compilation process on Windows. This
-// process is as follows:
-//
-// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
-//
-// .rc files are human-readable scripts that list all resources a program uses.
-//
-// They are compiled into .res files, which are a list of the resources in
-// binary form.
-//
-// Finally the data stored in the .res is compiled into a COFF file, where it
-// is organized in a directory tree structure for optimized access by the
-// program during runtime.
-//
-// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
-#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/Object/Binary.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/Error.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-
-#include <map>
-
-namespace llvm {
-
-class raw_ostream;
-class ScopedPrinter;
-
-namespace object {
-
-class WindowsResource;
-class ResourceSectionRef;
-
-const size_t WIN_RES_MAGIC_SIZE = 16;
-const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
-const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
-const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
-const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
-
-struct WinResHeaderPrefix {
- support::ulittle32_t DataSize;
- support::ulittle32_t HeaderSize;
-};
-
-// Type and Name may each either be an integer ID or a string. This struct is
-// only used in the case where they are both IDs.
-struct WinResIDs {
- uint16_t TypeFlag;
- support::ulittle16_t TypeID;
- uint16_t NameFlag;
- support::ulittle16_t NameID;
-
- void setType(uint16_t ID) {
- TypeFlag = 0xffff;
- TypeID = ID;
- }
-
- void setName(uint16_t ID) {
- NameFlag = 0xffff;
- NameID = ID;
- }
-};
-
-struct WinResHeaderSuffix {
- support::ulittle32_t DataVersion;
- support::ulittle16_t MemoryFlags;
- support::ulittle16_t Language;
- support::ulittle32_t Version;
- support::ulittle32_t Characteristics;
-};
-
-class EmptyResError : public GenericBinaryError {
-public:
- EmptyResError(Twine Msg, object_error ECOverride)
- : GenericBinaryError(Msg, ECOverride) {}
-};
-
-class ResourceEntryRef {
-public:
- Error moveNext(bool &End);
- bool checkTypeString() const { return IsStringType; }
- ArrayRef<UTF16> getTypeString() const { return Type; }
- uint16_t getTypeID() const { return TypeID; }
- bool checkNameString() const { return IsStringName; }
- ArrayRef<UTF16> getNameString() const { return Name; }
- uint16_t getNameID() const { return NameID; }
- uint16_t getDataVersion() const { return Suffix->DataVersion; }
- uint16_t getLanguage() const { return Suffix->Language; }
- uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
- uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
- uint16_t getMinorVersion() const { return Suffix->Version; }
- uint32_t getCharacteristics() const { return Suffix->Characteristics; }
- ArrayRef<uint8_t> getData() const { return Data; }
-
-private:
- friend class WindowsResource;
-
- ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
- Error loadNext();
-
- static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
- const WindowsResource *Owner);
-
- BinaryStreamReader Reader;
- const WindowsResource *Owner;
- bool IsStringType;
- ArrayRef<UTF16> Type;
- uint16_t TypeID;
- bool IsStringName;
- ArrayRef<UTF16> Name;
- uint16_t NameID;
- const WinResHeaderSuffix *Suffix = nullptr;
- ArrayRef<uint8_t> Data;
-};
-
-class WindowsResource : public Binary {
-public:
- Expected<ResourceEntryRef> getHeadEntry();
-
- static bool classof(const Binary *V) { return V->isWinRes(); }
-
- static Expected<std::unique_ptr<WindowsResource>>
- createWindowsResource(MemoryBufferRef Source);
-
-private:
- friend class ResourceEntryRef;
-
- WindowsResource(MemoryBufferRef Source);
-
- BinaryByteStream BBS;
-};
-
-class WindowsResourceParser {
-public:
- class TreeNode;
- WindowsResourceParser(bool MinGW = false);
- Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
- Error parse(ResourceSectionRef &RSR, StringRef Filename,
- std::vector<std::string> &Duplicates);
- void cleanUpManifests(std::vector<std::string> &Duplicates);
- void printTree(raw_ostream &OS) const;
- const TreeNode &getTree() const { return Root; }
- const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
- const ArrayRef<std::vector<UTF16>> getStringTable() const {
- return StringTable;
- }
-
- class TreeNode {
- public:
- template <typename T>
- using Children = std::map<T, std::unique_ptr<TreeNode>>;
-
- void print(ScopedPrinter &Writer, StringRef Name) const;
- uint32_t getTreeSize() const;
- uint32_t getStringIndex() const { return StringIndex; }
- uint32_t getDataIndex() const { return DataIndex; }
- uint16_t getMajorVersion() const { return MajorVersion; }
- uint16_t getMinorVersion() const { return MinorVersion; }
- uint32_t getCharacteristics() const { return Characteristics; }
- bool checkIsDataNode() const { return IsDataNode; }
- const Children<uint32_t> &getIDChildren() const { return IDChildren; }
- const Children<std::string> &getStringChildren() const {
- return StringChildren;
- }
-
- private:
- friend class WindowsResourceParser;
-
- // Index is the StringTable vector index for this node's name.
- static std::unique_ptr<TreeNode> createStringNode(uint32_t Index);
- static std::unique_ptr<TreeNode> createIDNode();
- // DataIndex is the Data vector index that the data node points at.
- static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
- uint16_t MinorVersion,
- uint32_t Characteristics,
- uint32_t Origin,
- uint32_t DataIndex);
-
- explicit TreeNode(uint32_t StringIndex);
- TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
- uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex);
-
- bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
- std::vector<std::vector<uint8_t>> &Data,
- std::vector<std::vector<UTF16>> &StringTable,
- TreeNode *&Result);
- TreeNode &addTypeNode(const ResourceEntryRef &Entry,
- std::vector<std::vector<UTF16>> &StringTable);
- TreeNode &addNameNode(const ResourceEntryRef &Entry,
- std::vector<std::vector<UTF16>> &StringTable);
- bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
- std::vector<std::vector<uint8_t>> &Data,
- TreeNode *&Result);
- bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
- uint32_t Characteristics, uint32_t Origin,
- uint32_t DataIndex, TreeNode *&Result);
- TreeNode &addIDChild(uint32_t ID);
- TreeNode &addNameChild(ArrayRef<UTF16> NameRef,
- std::vector<std::vector<UTF16>> &StringTable);
- void shiftDataIndexDown(uint32_t Index);
-
- bool IsDataNode = false;
- uint32_t StringIndex;
- uint32_t DataIndex;
- Children<uint32_t> IDChildren;
- Children<std::string> StringChildren;
- uint16_t MajorVersion = 0;
- uint16_t MinorVersion = 0;
- uint32_t Characteristics = 0;
-
- // The .res file that defined this TreeNode, for diagnostics.
- // Index into InputFilenames.
- uint32_t Origin;
- };
-
- struct StringOrID {
- bool IsString;
- ArrayRef<UTF16> String;
- uint32_t ID;
-
- StringOrID(uint32_t ID) : IsString(false), ID(ID) {}
- StringOrID(ArrayRef<UTF16> String) : IsString(true), String(String) {}
- };
-
-private:
- Error addChildren(TreeNode &Node, ResourceSectionRef &RSR,
- const coff_resource_dir_table &Table, uint32_t Origin,
- std::vector<StringOrID> &Context,
- std::vector<std::string> &Duplicates);
- bool shouldIgnoreDuplicate(const ResourceEntryRef &Entry) const;
- bool shouldIgnoreDuplicate(const std::vector<StringOrID> &Context) const;
-
- TreeNode Root;
- std::vector<std::vector<uint8_t>> Data;
- std::vector<std::vector<UTF16>> StringTable;
-
- std::vector<std::string> InputFilenames;
-
- bool MinGW;
-};
-
-Expected<std::unique_ptr<MemoryBuffer>>
-writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
- const WindowsResourceParser &Parser,
- uint32_t TimeDateStamp);
-
-void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
-} // namespace object
-} // namespace llvm
-
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-- WindowsResource.h ---------------------------------------*- 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 .res file class. .res files are intermediate
+// products of the typical resource-compilation process on Windows. This
+// process is as follows:
+//
+// .rc file(s) ---(rc.exe)---> .res file(s) ---(cvtres.exe)---> COFF file
+//
+// .rc files are human-readable scripts that list all resources a program uses.
+//
+// They are compiled into .res files, which are a list of the resources in
+// binary form.
+//
+// Finally the data stored in the .res is compiled into a COFF file, where it
+// is organized in a directory tree structure for optimized access by the
+// program during runtime.
+//
+// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648007(v=vs.85).aspx
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
+#define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+
+#include <map>
+
+namespace llvm {
+
+class raw_ostream;
+class ScopedPrinter;
+
+namespace object {
+
+class WindowsResource;
+class ResourceSectionRef;
+
+const size_t WIN_RES_MAGIC_SIZE = 16;
+const size_t WIN_RES_NULL_ENTRY_SIZE = 16;
+const uint32_t WIN_RES_HEADER_ALIGNMENT = 4;
+const uint32_t WIN_RES_DATA_ALIGNMENT = 4;
+const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030;
+
+struct WinResHeaderPrefix {
+ support::ulittle32_t DataSize;
+ support::ulittle32_t HeaderSize;
+};
+
+// Type and Name may each either be an integer ID or a string. This struct is
+// only used in the case where they are both IDs.
+struct WinResIDs {
+ uint16_t TypeFlag;
+ support::ulittle16_t TypeID;
+ uint16_t NameFlag;
+ support::ulittle16_t NameID;
+
+ void setType(uint16_t ID) {
+ TypeFlag = 0xffff;
+ TypeID = ID;
+ }
+
+ void setName(uint16_t ID) {
+ NameFlag = 0xffff;
+ NameID = ID;
+ }
+};
+
+struct WinResHeaderSuffix {
+ support::ulittle32_t DataVersion;
+ support::ulittle16_t MemoryFlags;
+ support::ulittle16_t Language;
+ support::ulittle32_t Version;
+ support::ulittle32_t Characteristics;
+};
+
+class EmptyResError : public GenericBinaryError {
+public:
+ EmptyResError(Twine Msg, object_error ECOverride)
+ : GenericBinaryError(Msg, ECOverride) {}
+};
+
+class ResourceEntryRef {
+public:
+ Error moveNext(bool &End);
+ bool checkTypeString() const { return IsStringType; }
+ ArrayRef<UTF16> getTypeString() const { return Type; }
+ uint16_t getTypeID() const { return TypeID; }
+ bool checkNameString() const { return IsStringName; }
+ ArrayRef<UTF16> getNameString() const { return Name; }
+ uint16_t getNameID() const { return NameID; }
+ uint16_t getDataVersion() const { return Suffix->DataVersion; }
+ uint16_t getLanguage() const { return Suffix->Language; }
+ uint16_t getMemoryFlags() const { return Suffix->MemoryFlags; }
+ uint16_t getMajorVersion() const { return Suffix->Version >> 16; }
+ uint16_t getMinorVersion() const { return Suffix->Version; }
+ uint32_t getCharacteristics() const { return Suffix->Characteristics; }
+ ArrayRef<uint8_t> getData() const { return Data; }
+
+private:
+ friend class WindowsResource;
+
+ ResourceEntryRef(BinaryStreamRef Ref, const WindowsResource *Owner);
+ Error loadNext();
+
+ static Expected<ResourceEntryRef> create(BinaryStreamRef Ref,
+ const WindowsResource *Owner);
+
+ BinaryStreamReader Reader;
+ const WindowsResource *Owner;
+ bool IsStringType;
+ ArrayRef<UTF16> Type;
+ uint16_t TypeID;
+ bool IsStringName;
+ ArrayRef<UTF16> Name;
+ uint16_t NameID;
+ const WinResHeaderSuffix *Suffix = nullptr;
+ ArrayRef<uint8_t> Data;
+};
+
+class WindowsResource : public Binary {
+public:
+ Expected<ResourceEntryRef> getHeadEntry();
+
+ static bool classof(const Binary *V) { return V->isWinRes(); }
+
+ static Expected<std::unique_ptr<WindowsResource>>
+ createWindowsResource(MemoryBufferRef Source);
+
+private:
+ friend class ResourceEntryRef;
+
+ WindowsResource(MemoryBufferRef Source);
+
+ BinaryByteStream BBS;
+};
+
+class WindowsResourceParser {
+public:
+ class TreeNode;
+ WindowsResourceParser(bool MinGW = false);
+ Error parse(WindowsResource *WR, std::vector<std::string> &Duplicates);
+ Error parse(ResourceSectionRef &RSR, StringRef Filename,
+ std::vector<std::string> &Duplicates);
+ void cleanUpManifests(std::vector<std::string> &Duplicates);
+ void printTree(raw_ostream &OS) const;
+ const TreeNode &getTree() const { return Root; }
+ const ArrayRef<std::vector<uint8_t>> getData() const { return Data; }
+ const ArrayRef<std::vector<UTF16>> getStringTable() const {
+ return StringTable;
+ }
+
+ class TreeNode {
+ public:
+ template <typename T>
+ using Children = std::map<T, std::unique_ptr<TreeNode>>;
+
+ void print(ScopedPrinter &Writer, StringRef Name) const;
+ uint32_t getTreeSize() const;
+ uint32_t getStringIndex() const { return StringIndex; }
+ uint32_t getDataIndex() const { return DataIndex; }
+ uint16_t getMajorVersion() const { return MajorVersion; }
+ uint16_t getMinorVersion() const { return MinorVersion; }
+ uint32_t getCharacteristics() const { return Characteristics; }
+ bool checkIsDataNode() const { return IsDataNode; }
+ const Children<uint32_t> &getIDChildren() const { return IDChildren; }
+ const Children<std::string> &getStringChildren() const {
+ return StringChildren;
+ }
+
+ private:
+ friend class WindowsResourceParser;
+
+ // Index is the StringTable vector index for this node's name.
+ static std::unique_ptr<TreeNode> createStringNode(uint32_t Index);
+ static std::unique_ptr<TreeNode> createIDNode();
+ // DataIndex is the Data vector index that the data node points at.
+ static std::unique_ptr<TreeNode> createDataNode(uint16_t MajorVersion,
+ uint16_t MinorVersion,
+ uint32_t Characteristics,
+ uint32_t Origin,
+ uint32_t DataIndex);
+
+ explicit TreeNode(uint32_t StringIndex);
+ TreeNode(uint16_t MajorVersion, uint16_t MinorVersion,
+ uint32_t Characteristics, uint32_t Origin, uint32_t DataIndex);
+
+ bool addEntry(const ResourceEntryRef &Entry, uint32_t Origin,
+ std::vector<std::vector<uint8_t>> &Data,
+ std::vector<std::vector<UTF16>> &StringTable,
+ TreeNode *&Result);
+ TreeNode &addTypeNode(const ResourceEntryRef &Entry,
+ std::vector<std::vector<UTF16>> &StringTable);
+ TreeNode &addNameNode(const ResourceEntryRef &Entry,
+ std::vector<std::vector<UTF16>> &StringTable);
+ bool addLanguageNode(const ResourceEntryRef &Entry, uint32_t Origin,
+ std::vector<std::vector<uint8_t>> &Data,
+ TreeNode *&Result);
+ bool addDataChild(uint32_t ID, uint16_t MajorVersion, uint16_t MinorVersion,
+ uint32_t Characteristics, uint32_t Origin,
+ uint32_t DataIndex, TreeNode *&Result);
+ TreeNode &addIDChild(uint32_t ID);
+ TreeNode &addNameChild(ArrayRef<UTF16> NameRef,
+ std::vector<std::vector<UTF16>> &StringTable);
+ void shiftDataIndexDown(uint32_t Index);
+
+ bool IsDataNode = false;
+ uint32_t StringIndex;
+ uint32_t DataIndex;
+ Children<uint32_t> IDChildren;
+ Children<std::string> StringChildren;
+ uint16_t MajorVersion = 0;
+ uint16_t MinorVersion = 0;
+ uint32_t Characteristics = 0;
+
+ // The .res file that defined this TreeNode, for diagnostics.
+ // Index into InputFilenames.
+ uint32_t Origin;
+ };
+
+ struct StringOrID {
+ bool IsString;
+ ArrayRef<UTF16> String;
+ uint32_t ID;
+
+ StringOrID(uint32_t ID) : IsString(false), ID(ID) {}
+ StringOrID(ArrayRef<UTF16> String) : IsString(true), String(String) {}
+ };
+
+private:
+ Error addChildren(TreeNode &Node, ResourceSectionRef &RSR,
+ const coff_resource_dir_table &Table, uint32_t Origin,
+ std::vector<StringOrID> &Context,
+ std::vector<std::string> &Duplicates);
+ bool shouldIgnoreDuplicate(const ResourceEntryRef &Entry) const;
+ bool shouldIgnoreDuplicate(const std::vector<StringOrID> &Context) const;
+
+ TreeNode Root;
+ std::vector<std::vector<uint8_t>> Data;
+ std::vector<std::vector<UTF16>> StringTable;
+
+ std::vector<std::string> InputFilenames;
+
+ bool MinGW;
+};
+
+Expected<std::unique_ptr<MemoryBuffer>>
+writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType,
+ const WindowsResourceParser &Parser,
+ uint32_t TimeDateStamp);
+
+void printResourceTypeName(uint16_t TypeID, raw_ostream &OS);
+} // namespace object
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h b/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h
index ba11d43c43d..87f5ef02429 100644
--- a/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h
+++ b/contrib/libs/llvm12/include/llvm/Object/XCOFFObjectFile.h
@@ -1,407 +1,407 @@
-#pragma once
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#endif
-
-//===- XCOFFObjectFile.h - XCOFF object file implementation -----*- 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 XCOFFObjectFile class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
-#define LLVM_OBJECT_XCOFFOBJECTFILE_H
-
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- XCOFFObjectFile.h - XCOFF object file implementation -----*- 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 XCOFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_XCOFFOBJECTFILE_H
+#define LLVM_OBJECT_XCOFFOBJECTFILE_H
+
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/BinaryFormat/XCOFF.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Endian.h"
-#include <limits>
-
-namespace llvm {
-namespace object {
-
-struct XCOFFFileHeader32 {
- support::ubig16_t Magic;
- support::ubig16_t NumberOfSections;
-
- // Unix time value, value of 0 indicates no timestamp.
- // Negative values are reserved.
- support::big32_t TimeStamp;
-
- support::ubig32_t SymbolTableOffset; // File offset to symbol table.
- support::big32_t NumberOfSymTableEntries;
- support::ubig16_t AuxHeaderSize;
- support::ubig16_t Flags;
-};
-
-struct XCOFFFileHeader64 {
- support::ubig16_t Magic;
- support::ubig16_t NumberOfSections;
-
- // Unix time value, value of 0 indicates no timestamp.
- // Negative values are reserved.
- support::big32_t TimeStamp;
-
- support::ubig64_t SymbolTableOffset; // File offset to symbol table.
- support::ubig16_t AuxHeaderSize;
- support::ubig16_t Flags;
- support::ubig32_t NumberOfSymTableEntries;
-};
-
-template <typename T> struct XCOFFSectionHeader {
- // Least significant 3 bits are reserved.
- static constexpr unsigned SectionFlagsReservedMask = 0x7;
-
- // The low order 16 bits of section flags denotes the section type.
- static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
-
-public:
- StringRef getName() const;
- uint16_t getSectionType() const;
- bool isReservedSectionType() const;
-};
-
-// Explicit extern template declarations.
-struct XCOFFSectionHeader32;
-struct XCOFFSectionHeader64;
-extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
-extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
-
-struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> {
- char Name[XCOFF::NameSize];
- support::ubig32_t PhysicalAddress;
- support::ubig32_t VirtualAddress;
- support::ubig32_t SectionSize;
- support::ubig32_t FileOffsetToRawData;
- support::ubig32_t FileOffsetToRelocationInfo;
- support::ubig32_t FileOffsetToLineNumberInfo;
- support::ubig16_t NumberOfRelocations;
- support::ubig16_t NumberOfLineNumbers;
- support::big32_t Flags;
-};
-
-struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
- char Name[XCOFF::NameSize];
- support::ubig64_t PhysicalAddress;
- support::ubig64_t VirtualAddress;
- support::ubig64_t SectionSize;
- support::big64_t FileOffsetToRawData;
- support::big64_t FileOffsetToRelocationInfo;
- support::big64_t FileOffsetToLineNumberInfo;
- support::ubig32_t NumberOfRelocations;
- support::ubig32_t NumberOfLineNumbers;
- support::big32_t Flags;
- char Padding[4];
-};
-
-struct XCOFFSymbolEntry {
- enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
- typedef struct {
- support::big32_t Magic; // Zero indicates name in string table.
- support::ubig32_t Offset;
- } NameInStrTblType;
-
- typedef struct {
- uint8_t LanguageId;
- uint8_t CpuTypeId;
- } CFileLanguageIdAndTypeIdType;
-
- union {
- char SymbolName[XCOFF::NameSize];
- NameInStrTblType NameInStrTbl;
- };
-
- support::ubig32_t Value; // Symbol value; storage class-dependent.
- support::big16_t SectionNumber;
-
- union {
- support::ubig16_t SymbolType;
- CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
- };
-
- XCOFF::StorageClass StorageClass;
- uint8_t NumberOfAuxEntries;
-};
-
-struct XCOFFStringTable {
- uint32_t Size;
- const char *Data;
-};
-
-struct XCOFFCsectAuxEnt32 {
- static constexpr uint8_t SymbolTypeMask = 0x07;
- static constexpr uint8_t SymbolAlignmentMask = 0xF8;
- static constexpr size_t SymbolAlignmentBitOffset = 3;
-
- support::ubig32_t
- SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
- // length.
- // If the symbol type is XTY_LD, the symbol table
- // index of the containing csect.
- // If the symbol type is XTY_ER, 0.
- support::ubig32_t ParameterHashIndex;
- support::ubig16_t TypeChkSectNum;
- uint8_t SymbolAlignmentAndType;
- XCOFF::StorageMappingClass StorageMappingClass;
- support::ubig32_t StabInfoIndex;
- support::ubig16_t StabSectNum;
-
- uint16_t getAlignmentLog2() const {
- return (SymbolAlignmentAndType & SymbolAlignmentMask) >>
- SymbolAlignmentBitOffset;
- }
-
- uint8_t getSymbolType() const {
- return SymbolAlignmentAndType & SymbolTypeMask;
- }
-
- bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
-};
-
-struct XCOFFFileAuxEnt {
- typedef struct {
- support::big32_t Magic; // Zero indicates name in string table.
- support::ubig32_t Offset;
- char NamePad[XCOFF::FileNamePadSize];
- } NameInStrTblType;
- union {
- char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
- NameInStrTblType NameInStrTbl;
- };
- XCOFF::CFileStringType Type;
- uint8_t ReservedZeros[2];
- uint8_t AuxType; // 64-bit XCOFF file only.
-};
-
-struct XCOFFSectAuxEntForStat {
- support::ubig32_t SectionLength;
- support::ubig16_t NumberOfRelocEnt;
- support::ubig16_t NumberOfLineNum;
- uint8_t Pad[10];
-};
-
-struct XCOFFRelocation32 {
- // Masks for packing/unpacking the r_rsize field of relocations.
-
- // The msb is used to indicate if the bits being relocated are signed or
- // unsigned.
- static constexpr uint8_t XR_SIGN_INDICATOR_MASK = 0x80;
-
- // The 2nd msb is used to indicate that the binder has replaced/modified the
- // original instruction.
- static constexpr uint8_t XR_FIXUP_INDICATOR_MASK = 0x40;
-
- // The remaining bits specify the bit length of the relocatable reference
- // minus one.
- static constexpr uint8_t XR_BIASED_LENGTH_MASK = 0x3f;
-
-public:
- support::ubig32_t VirtualAddress;
- support::ubig32_t SymbolIndex;
-
- // Packed field, see XR_* masks for details of packing.
- uint8_t Info;
-
- XCOFF::RelocationType Type;
-
-public:
- bool isRelocationSigned() const;
- bool isFixupIndicated() const;
-
- // Returns the number of bits being relocated.
- uint8_t getRelocatedLength() const;
-};
-
-class XCOFFObjectFile : public ObjectFile {
-private:
- const void *FileHeader = nullptr;
- const void *SectionHeaderTable = nullptr;
-
- const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
- XCOFFStringTable StringTable = {0, nullptr};
-
- const XCOFFFileHeader32 *fileHeader32() const;
- const XCOFFFileHeader64 *fileHeader64() const;
-
- const XCOFFSectionHeader32 *sectionHeaderTable32() const;
- const XCOFFSectionHeader64 *sectionHeaderTable64() const;
-
- size_t getFileHeaderSize() const;
- size_t getSectionHeaderSize() const;
-
- const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
- const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
- uintptr_t getSectionHeaderTableAddress() const;
- uintptr_t getEndOfSymbolTableAddress() const;
-
- // This returns a pointer to the start of the storage for the name field of
- // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
- // null-terminated.
- const char *getSectionNameInternal(DataRefImpl Sec) const;
-
- // This function returns string table entry.
- Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
-
- static bool isReservedSectionNumber(int16_t SectionNumber);
-
- // Constructor and "create" factory function. The constructor is only a thin
- // wrapper around the base constructor. The "create" function fills out the
- // XCOFF-specific information and performs the error checking along the way.
- XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
- static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
- MemoryBufferRef MBR);
-
- // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
- // and an XCOFFStringTable if parsing succeeded.
- static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
- uint64_t Offset);
-
- // Make a friend so it can call the private 'create' function.
- friend Expected<std::unique_ptr<ObjectFile>>
- ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
-
- void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
-
-public:
- static constexpr uint64_t InvalidRelocOffset =
- std::numeric_limits<uint64_t>::max();
-
- // Interface inherited from base classes.
- void moveSymbolNext(DataRefImpl &Symb) const override;
- Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
- basic_symbol_iterator symbol_begin() const override;
- basic_symbol_iterator symbol_end() const override;
-
- Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
- Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
- uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
- uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
- Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
-
- void moveSectionNext(DataRefImpl &Sec) const override;
- Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
- uint64_t getSectionAddress(DataRefImpl Sec) const override;
- uint64_t getSectionIndex(DataRefImpl Sec) const override;
- uint64_t getSectionSize(DataRefImpl Sec) const override;
- Expected<ArrayRef<uint8_t>>
- getSectionContents(DataRefImpl Sec) const override;
- uint64_t getSectionAlignment(DataRefImpl Sec) const override;
- bool isSectionCompressed(DataRefImpl Sec) const override;
- bool isSectionText(DataRefImpl Sec) const override;
- bool isSectionData(DataRefImpl Sec) const override;
- bool isSectionBSS(DataRefImpl Sec) const override;
-
- bool isSectionVirtual(DataRefImpl Sec) const override;
- relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
- relocation_iterator section_rel_end(DataRefImpl Sec) const override;
-
- void moveRelocationNext(DataRefImpl &Rel) const override;
-
- /// \returns the relocation offset with the base address of the containing
- /// section as zero, or InvalidRelocOffset on errors (such as a relocation
- /// that does not refer to an address in any section).
- uint64_t getRelocationOffset(DataRefImpl Rel) const override;
- symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
- uint64_t getRelocationType(DataRefImpl Rel) const override;
- void getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const override;
-
- section_iterator section_begin() const override;
- section_iterator section_end() const override;
- uint8_t getBytesInAddress() const override;
- StringRef getFileFormatName() const override;
- Triple::ArchType getArch() const override;
- SubtargetFeatures getFeatures() const override;
- Expected<uint64_t> getStartAddress() const override;
- bool isRelocatableObject() const override;
-
- // Below here is the non-inherited interface.
- bool is64Bit() const;
-
- const XCOFFSymbolEntry *getPointerToSymbolTable() const {
- assert(!is64Bit() && "Symbol table handling not supported yet.");
- return SymbolTblPtr;
- }
-
- Expected<StringRef>
- getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
-
- const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
-
- // File header related interfaces.
- uint16_t getMagic() const;
- uint16_t getNumberOfSections() const;
- int32_t getTimeStamp() const;
-
- // Symbol table offset and entry count are handled differently between
- // XCOFF32 and XCOFF64.
- uint32_t getSymbolTableOffset32() const;
- uint64_t getSymbolTableOffset64() const;
-
- // Note that this value is signed and might return a negative value. Negative
- // values are reserved for future use.
- int32_t getRawNumberOfSymbolTableEntries32() const;
-
- // The sanitized value appropriate to use as an index into the symbol table.
- uint32_t getLogicalNumberOfSymbolTableEntries32() const;
-
- uint32_t getNumberOfSymbolTableEntries64() const;
- uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
- Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
-
- Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
- uint16_t getOptionalHeaderSize() const;
- uint16_t getFlags() const;
-
- // Section header table related interfaces.
- ArrayRef<XCOFFSectionHeader32> sections32() const;
- ArrayRef<XCOFFSectionHeader64> sections64() const;
-
- int32_t getSectionFlags(DataRefImpl Sec) const;
- Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
-
- void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
-
- // Relocation-related interfaces.
- Expected<uint32_t>
- getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32 &Sec) const;
-
- Expected<ArrayRef<XCOFFRelocation32>>
- relocations(const XCOFFSectionHeader32 &) const;
+#include "llvm/BinaryFormat/XCOFF.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Endian.h"
+#include <limits>
+
+namespace llvm {
+namespace object {
+
+struct XCOFFFileHeader32 {
+ support::ubig16_t Magic;
+ support::ubig16_t NumberOfSections;
+
+ // Unix time value, value of 0 indicates no timestamp.
+ // Negative values are reserved.
+ support::big32_t TimeStamp;
+
+ support::ubig32_t SymbolTableOffset; // File offset to symbol table.
+ support::big32_t NumberOfSymTableEntries;
+ support::ubig16_t AuxHeaderSize;
+ support::ubig16_t Flags;
+};
+
+struct XCOFFFileHeader64 {
+ support::ubig16_t Magic;
+ support::ubig16_t NumberOfSections;
+
+ // Unix time value, value of 0 indicates no timestamp.
+ // Negative values are reserved.
+ support::big32_t TimeStamp;
+
+ support::ubig64_t SymbolTableOffset; // File offset to symbol table.
+ support::ubig16_t AuxHeaderSize;
+ support::ubig16_t Flags;
+ support::ubig32_t NumberOfSymTableEntries;
+};
+
+template <typename T> struct XCOFFSectionHeader {
+ // Least significant 3 bits are reserved.
+ static constexpr unsigned SectionFlagsReservedMask = 0x7;
+
+ // The low order 16 bits of section flags denotes the section type.
+ static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
+
+public:
+ StringRef getName() const;
+ uint16_t getSectionType() const;
+ bool isReservedSectionType() const;
+};
+
+// Explicit extern template declarations.
+struct XCOFFSectionHeader32;
+struct XCOFFSectionHeader64;
+extern template struct XCOFFSectionHeader<XCOFFSectionHeader32>;
+extern template struct XCOFFSectionHeader<XCOFFSectionHeader64>;
+
+struct XCOFFSectionHeader32 : XCOFFSectionHeader<XCOFFSectionHeader32> {
+ char Name[XCOFF::NameSize];
+ support::ubig32_t PhysicalAddress;
+ support::ubig32_t VirtualAddress;
+ support::ubig32_t SectionSize;
+ support::ubig32_t FileOffsetToRawData;
+ support::ubig32_t FileOffsetToRelocationInfo;
+ support::ubig32_t FileOffsetToLineNumberInfo;
+ support::ubig16_t NumberOfRelocations;
+ support::ubig16_t NumberOfLineNumbers;
+ support::big32_t Flags;
+};
+
+struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
+ char Name[XCOFF::NameSize];
+ support::ubig64_t PhysicalAddress;
+ support::ubig64_t VirtualAddress;
+ support::ubig64_t SectionSize;
+ support::big64_t FileOffsetToRawData;
+ support::big64_t FileOffsetToRelocationInfo;
+ support::big64_t FileOffsetToLineNumberInfo;
+ support::ubig32_t NumberOfRelocations;
+ support::ubig32_t NumberOfLineNumbers;
+ support::big32_t Flags;
+ char Padding[4];
+};
+
+struct XCOFFSymbolEntry {
+ enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
+ typedef struct {
+ support::big32_t Magic; // Zero indicates name in string table.
+ support::ubig32_t Offset;
+ } NameInStrTblType;
+
+ typedef struct {
+ uint8_t LanguageId;
+ uint8_t CpuTypeId;
+ } CFileLanguageIdAndTypeIdType;
+
+ union {
+ char SymbolName[XCOFF::NameSize];
+ NameInStrTblType NameInStrTbl;
+ };
+
+ support::ubig32_t Value; // Symbol value; storage class-dependent.
+ support::big16_t SectionNumber;
+
+ union {
+ support::ubig16_t SymbolType;
+ CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+ };
+
+ XCOFF::StorageClass StorageClass;
+ uint8_t NumberOfAuxEntries;
+};
+
+struct XCOFFStringTable {
+ uint32_t Size;
+ const char *Data;
+};
+
+struct XCOFFCsectAuxEnt32 {
+ static constexpr uint8_t SymbolTypeMask = 0x07;
+ static constexpr uint8_t SymbolAlignmentMask = 0xF8;
+ static constexpr size_t SymbolAlignmentBitOffset = 3;
+
+ support::ubig32_t
+ SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
+ // length.
+ // If the symbol type is XTY_LD, the symbol table
+ // index of the containing csect.
+ // If the symbol type is XTY_ER, 0.
+ support::ubig32_t ParameterHashIndex;
+ support::ubig16_t TypeChkSectNum;
+ uint8_t SymbolAlignmentAndType;
+ XCOFF::StorageMappingClass StorageMappingClass;
+ support::ubig32_t StabInfoIndex;
+ support::ubig16_t StabSectNum;
+
+ uint16_t getAlignmentLog2() const {
+ return (SymbolAlignmentAndType & SymbolAlignmentMask) >>
+ SymbolAlignmentBitOffset;
+ }
+
+ uint8_t getSymbolType() const {
+ return SymbolAlignmentAndType & SymbolTypeMask;
+ }
+
+ bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
+};
+
+struct XCOFFFileAuxEnt {
+ typedef struct {
+ support::big32_t Magic; // Zero indicates name in string table.
+ support::ubig32_t Offset;
+ char NamePad[XCOFF::FileNamePadSize];
+ } NameInStrTblType;
+ union {
+ char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
+ NameInStrTblType NameInStrTbl;
+ };
+ XCOFF::CFileStringType Type;
+ uint8_t ReservedZeros[2];
+ uint8_t AuxType; // 64-bit XCOFF file only.
+};
+
+struct XCOFFSectAuxEntForStat {
+ support::ubig32_t SectionLength;
+ support::ubig16_t NumberOfRelocEnt;
+ support::ubig16_t NumberOfLineNum;
+ uint8_t Pad[10];
+};
+
+struct XCOFFRelocation32 {
+ // Masks for packing/unpacking the r_rsize field of relocations.
+
+ // The msb is used to indicate if the bits being relocated are signed or
+ // unsigned.
+ static constexpr uint8_t XR_SIGN_INDICATOR_MASK = 0x80;
+
+ // The 2nd msb is used to indicate that the binder has replaced/modified the
+ // original instruction.
+ static constexpr uint8_t XR_FIXUP_INDICATOR_MASK = 0x40;
+
+ // The remaining bits specify the bit length of the relocatable reference
+ // minus one.
+ static constexpr uint8_t XR_BIASED_LENGTH_MASK = 0x3f;
+
+public:
+ support::ubig32_t VirtualAddress;
+ support::ubig32_t SymbolIndex;
+
+ // Packed field, see XR_* masks for details of packing.
+ uint8_t Info;
+
+ XCOFF::RelocationType Type;
+
+public:
+ bool isRelocationSigned() const;
+ bool isFixupIndicated() const;
+
+ // Returns the number of bits being relocated.
+ uint8_t getRelocatedLength() const;
+};
+
+class XCOFFObjectFile : public ObjectFile {
+private:
+ const void *FileHeader = nullptr;
+ const void *SectionHeaderTable = nullptr;
+
+ const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
+ XCOFFStringTable StringTable = {0, nullptr};
+
+ const XCOFFFileHeader32 *fileHeader32() const;
+ const XCOFFFileHeader64 *fileHeader64() const;
+
+ const XCOFFSectionHeader32 *sectionHeaderTable32() const;
+ const XCOFFSectionHeader64 *sectionHeaderTable64() const;
+
+ size_t getFileHeaderSize() const;
+ size_t getSectionHeaderSize() const;
+
+ const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
+ const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
+ uintptr_t getSectionHeaderTableAddress() const;
+ uintptr_t getEndOfSymbolTableAddress() const;
+
+ // This returns a pointer to the start of the storage for the name field of
+ // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
+ // null-terminated.
+ const char *getSectionNameInternal(DataRefImpl Sec) const;
+
+ // This function returns string table entry.
+ Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
+
+ static bool isReservedSectionNumber(int16_t SectionNumber);
+
+ // Constructor and "create" factory function. The constructor is only a thin
+ // wrapper around the base constructor. The "create" function fills out the
+ // XCOFF-specific information and performs the error checking along the way.
+ XCOFFObjectFile(unsigned Type, MemoryBufferRef Object);
+ static Expected<std::unique_ptr<XCOFFObjectFile>> create(unsigned Type,
+ MemoryBufferRef MBR);
+
+ // Helper for parsing the StringTable. Returns an 'Error' if parsing failed
+ // and an XCOFFStringTable if parsing succeeded.
+ static Expected<XCOFFStringTable> parseStringTable(const XCOFFObjectFile *Obj,
+ uint64_t Offset);
+
+ // Make a friend so it can call the private 'create' function.
+ friend Expected<std::unique_ptr<ObjectFile>>
+ ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
+
+ void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
+
+public:
+ static constexpr uint64_t InvalidRelocOffset =
+ std::numeric_limits<uint64_t>::max();
+
+ // Interface inherited from base classes.
+ void moveSymbolNext(DataRefImpl &Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
+ basic_symbol_iterator symbol_begin() const override;
+ basic_symbol_iterator symbol_end() const override;
+
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
+ uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+
+ void moveSectionNext(DataRefImpl &Sec) const override;
+ Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
+ uint64_t getSectionAddress(DataRefImpl Sec) const override;
+ uint64_t getSectionIndex(DataRefImpl Sec) const override;
+ uint64_t getSectionSize(DataRefImpl Sec) const override;
+ Expected<ArrayRef<uint8_t>>
+ getSectionContents(DataRefImpl Sec) const override;
+ uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
+ bool isSectionText(DataRefImpl Sec) const override;
+ bool isSectionData(DataRefImpl Sec) const override;
+ bool isSectionBSS(DataRefImpl Sec) const override;
+
+ bool isSectionVirtual(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
+ relocation_iterator section_rel_end(DataRefImpl Sec) const override;
+
+ void moveRelocationNext(DataRefImpl &Rel) const override;
+
+ /// \returns the relocation offset with the base address of the containing
+ /// section as zero, or InvalidRelocOffset on errors (such as a relocation
+ /// that does not refer to an address in any section).
+ uint64_t getRelocationOffset(DataRefImpl Rel) const override;
+ symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
+ uint64_t getRelocationType(DataRefImpl Rel) const override;
+ void getRelocationTypeName(DataRefImpl Rel,
+ SmallVectorImpl<char> &Result) const override;
+
+ section_iterator section_begin() const override;
+ section_iterator section_end() const override;
+ uint8_t getBytesInAddress() const override;
+ StringRef getFileFormatName() const override;
+ Triple::ArchType getArch() const override;
+ SubtargetFeatures getFeatures() const override;
+ Expected<uint64_t> getStartAddress() const override;
+ bool isRelocatableObject() const override;
+
+ // Below here is the non-inherited interface.
+ bool is64Bit() const;
+
+ const XCOFFSymbolEntry *getPointerToSymbolTable() const {
+ assert(!is64Bit() && "Symbol table handling not supported yet.");
+ return SymbolTblPtr;
+ }
+
+ Expected<StringRef>
+ getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
+
+ const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
+
+ // File header related interfaces.
+ uint16_t getMagic() const;
+ uint16_t getNumberOfSections() const;
+ int32_t getTimeStamp() const;
+
+ // Symbol table offset and entry count are handled differently between
+ // XCOFF32 and XCOFF64.
+ uint32_t getSymbolTableOffset32() const;
+ uint64_t getSymbolTableOffset64() const;
+
+ // Note that this value is signed and might return a negative value. Negative
+ // values are reserved for future use.
+ int32_t getRawNumberOfSymbolTableEntries32() const;
+
+ // The sanitized value appropriate to use as an index into the symbol table.
+ uint32_t getLogicalNumberOfSymbolTableEntries32() const;
+
+ uint32_t getNumberOfSymbolTableEntries64() const;
+ uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
+ Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
+
+ Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
+ uint16_t getOptionalHeaderSize() const;
+ uint16_t getFlags() const;
+
+ // Section header table related interfaces.
+ ArrayRef<XCOFFSectionHeader32> sections32() const;
+ ArrayRef<XCOFFSectionHeader64> sections64() const;
+
+ int32_t getSectionFlags(DataRefImpl Sec) const;
+ Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
+
+ void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
+
+ // Relocation-related interfaces.
+ Expected<uint32_t>
+ getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32 &Sec) const;
+
+ Expected<ArrayRef<XCOFFRelocation32>>
+ relocations(const XCOFFSectionHeader32 &) const;
static bool classof(const Binary *B) { return B->isXCOFF(); }
-}; // XCOFFObjectFile
-
-class XCOFFSymbolRef {
- const DataRefImpl SymEntDataRef;
- const XCOFFObjectFile *const OwningObjectPtr;
-
-public:
- XCOFFSymbolRef(DataRefImpl SymEntDataRef,
- const XCOFFObjectFile *OwningObjectPtr)
- : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
-
- XCOFF::StorageClass getStorageClass() const;
- uint8_t getNumberOfAuxEntries() const;
- const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
- uint16_t getType() const;
- int16_t getSectionNumber() const;
-
- bool hasCsectAuxEnt() const;
- bool isFunction() const;
-};
-
+}; // XCOFFObjectFile
+
+class XCOFFSymbolRef {
+ const DataRefImpl SymEntDataRef;
+ const XCOFFObjectFile *const OwningObjectPtr;
+
+public:
+ XCOFFSymbolRef(DataRefImpl SymEntDataRef,
+ const XCOFFObjectFile *OwningObjectPtr)
+ : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
+
+ XCOFF::StorageClass getStorageClass() const;
+ uint8_t getNumberOfAuxEntries() const;
+ const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
+ uint16_t getType() const;
+ int16_t getSectionNumber() const;
+
+ bool hasCsectAuxEnt() const;
+ bool isFunction() const;
+};
+
class TBVectorExt {
friend class XCOFFTracebackTable;
@@ -499,11 +499,11 @@ public:
};
bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes);
-} // namespace object
-} // namespace llvm
-
-#endif // LLVM_OBJECT_XCOFFOBJECTFILE_H
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
+} // namespace object
+} // namespace llvm
+
+#endif // LLVM_OBJECT_XCOFFOBJECTFILE_H
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif