Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/GsymReader.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/GsymReader.h
new file mode 100644
index 0000000..2a4eac7
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/GsymReader.h
@@ -0,0 +1,313 @@
+//===- GsymReader.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_DEBUGINFO_GSYM_GSYMREADER_H
+#define LLVM_DEBUGINFO_GSYM_GSYMREADER_H
+
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/Header.h"
+#include "llvm/DebugInfo/GSYM/LineEntry.h"
+#include "llvm/DebugInfo/GSYM/StringTable.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorOr.h"
+
+#include <inttypes.h>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace llvm {
+class MemoryBuffer;
+class raw_ostream;
+
+namespace gsym {
+
+/// GsymReader is used to read GSYM data from a file or buffer.
+///
+/// This class is optimized for very quick lookups when the endianness matches
+/// the host system. The Header, address table, address info offsets, and file
+/// table is designed to be mmap'ed as read only into memory and used without
+/// any parsing needed. If the endianness doesn't match, we swap these objects
+/// and tables into GsymReader::SwappedData and then point our header and
+/// ArrayRefs to this swapped internal data.
+///
+/// GsymReader objects must use one of the static functions to create an
+/// instance: GsymReader::openFile(...) and GsymReader::copyBuffer(...).
+
+class GsymReader {
+ GsymReader(std::unique_ptr<MemoryBuffer> Buffer);
+ llvm::Error parse();
+
+ std::unique_ptr<MemoryBuffer> MemBuffer;
+ StringRef GsymBytes;
+ llvm::support::endianness Endian;
+ const Header *Hdr = nullptr;
+ ArrayRef<uint8_t> AddrOffsets;
+ ArrayRef<uint32_t> AddrInfoOffsets;
+ ArrayRef<FileEntry> Files;
+ StringTable StrTab;
+ /// When the GSYM file's endianness doesn't match the host system then
+ /// we must decode all data structures that need to be swapped into
+ /// local storage and set point the ArrayRef objects above to these swapped
+ /// copies.
+ struct SwappedData {
+ Header Hdr;
+ std::vector<uint8_t> AddrOffsets;
+ std::vector<uint32_t> AddrInfoOffsets;
+ std::vector<FileEntry> Files;
+ };
+ std::unique_ptr<SwappedData> Swap;
+
+public:
+ GsymReader(GsymReader &&RHS);
+ ~GsymReader();
+
+ /// Construct a GsymReader from a file on disk.
+ ///
+ /// \param Path The file path the GSYM file to read.
+ /// \returns An expected GsymReader that contains the object or an error
+ /// object that indicates reason for failing to read the GSYM.
+ static llvm::Expected<GsymReader> openFile(StringRef Path);
+
+ /// Construct a GsymReader from a buffer.
+ ///
+ /// \param Bytes A set of bytes that will be copied and owned by the
+ /// returned object on success.
+ /// \returns An expected GsymReader that contains the object or an error
+ /// object that indicates reason for failing to read the GSYM.
+ static llvm::Expected<GsymReader> copyBuffer(StringRef Bytes);
+
+ /// Access the GSYM header.
+ /// \returns A native endian version of the GSYM header.
+ const Header &getHeader() const;
+
+ /// Get the full function info for an address.
+ ///
+ /// This should be called when a client will store a copy of the complete
+ /// FunctionInfo for a given address. For one off lookups, use the lookup()
+ /// function below.
+ ///
+ /// Symbolication server processes might want to parse the entire function
+ /// info for a given address and cache it if the process stays around to
+ /// service many symbolication addresses, like for parsing profiling
+ /// information.
+ ///
+ /// \param Addr A virtual address from the orignal object file to lookup.
+ ///
+ /// \returns An expected FunctionInfo that contains the function info object
+ /// or an error object that indicates reason for failing to lookup the
+ /// address.
+ llvm::Expected<FunctionInfo> getFunctionInfo(uint64_t Addr) const;
+
+ /// Lookup an address in the a GSYM.
+ ///
+ /// Lookup just the information needed for a specific address \a Addr. This
+ /// function is faster that calling getFunctionInfo() as it will only return
+ /// information that pertains to \a Addr and allows the parsing to skip any
+ /// extra information encoded for other addresses. For example the line table
+ /// parsing can stop when a matching LineEntry has been fouhnd, and the
+ /// InlineInfo can stop parsing early once a match has been found and also
+ /// skip information that doesn't match. This avoids memory allocations and
+ /// is much faster for lookups.
+ ///
+ /// \param Addr A virtual address from the orignal object file to lookup.
+ /// \returns An expected LookupResult that contains only the information
+ /// needed for the current address, or an error object that indicates reason
+ /// for failing to lookup the address.
+ llvm::Expected<LookupResult> lookup(uint64_t Addr) const;
+
+ /// Get a string from the string table.
+ ///
+ /// \param Offset The string table offset for the string to retrieve.
+ /// \returns The string from the strin table.
+ StringRef getString(uint32_t Offset) const { return StrTab[Offset]; }
+
+ /// Get the a file entry for the suppplied file index.
+ ///
+ /// Used to convert any file indexes in the FunctionInfo data back into
+ /// files. This function can be used for iteration, but is more commonly used
+ /// for random access when doing lookups.
+ ///
+ /// \param Index An index into the file table.
+ /// \returns An optional FileInfo that will be valid if the file index is
+ /// valid, or llvm::None if the file index is out of bounds,
+ Optional<FileEntry> getFile(uint32_t Index) const {
+ if (Index < Files.size())
+ return Files[Index];
+ return llvm::None;
+ }
+
+ /// Dump the entire Gsym data contained in this object.
+ ///
+ /// \param OS The output stream to dump to.
+ void dump(raw_ostream &OS);
+
+ /// Dump a FunctionInfo object.
+ ///
+ /// This function will convert any string table indexes and file indexes
+ /// into human readable format.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param FI The object to dump.
+ void dump(raw_ostream &OS, const FunctionInfo &FI);
+
+ /// Dump a LineTable object.
+ ///
+ /// This function will convert any string table indexes and file indexes
+ /// into human readable format.
+ ///
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param LT The object to dump.
+ void dump(raw_ostream &OS, const LineTable <);
+
+ /// Dump a InlineInfo object.
+ ///
+ /// This function will convert any string table indexes and file indexes
+ /// into human readable format.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param II The object to dump.
+ ///
+ /// \param Indent The indentation as number of spaces. Used for recurive
+ /// dumping.
+ void dump(raw_ostream &OS, const InlineInfo &II, uint32_t Indent = 0);
+
+ /// Dump a FileEntry object.
+ ///
+ /// This function will convert any string table indexes into human readable
+ /// format.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param FE The object to dump.
+ void dump(raw_ostream &OS, Optional<FileEntry> FE);
+
+ /// Get the number of addresses in this Gsym file.
+ uint32_t getNumAddresses() const {
+ return Hdr->NumAddresses;
+ }
+
+ /// Gets an address from the address table.
+ ///
+ /// Addresses are stored as offsets frrom the gsym::Header::BaseAddress.
+ ///
+ /// \param Index A index into the address table.
+ /// \returns A resolved virtual address for adddress in the address table
+ /// or llvm::None if Index is out of bounds.
+ Optional<uint64_t> getAddress(size_t Index) const;
+
+protected:
+
+ /// Get an appropriate address info offsets array.
+ ///
+ /// The address table in the GSYM file is stored as array of 1, 2, 4 or 8
+ /// byte offsets from the The gsym::Header::BaseAddress. The table is stored
+ /// internally as a array of bytes that are in the correct endianness. When
+ /// we access this table we must get an array that matches those sizes. This
+ /// templatized helper function is used when accessing address offsets in the
+ /// AddrOffsets member variable.
+ ///
+ /// \returns An ArrayRef of an appropriate address offset size.
+ template <class T> ArrayRef<T>
+ getAddrOffsets() const {
+ return ArrayRef<T>(reinterpret_cast<const T *>(AddrOffsets.data()),
+ AddrOffsets.size()/sizeof(T));
+ }
+
+ /// Get an appropriate address from the address table.
+ ///
+ /// The address table in the GSYM file is stored as array of 1, 2, 4 or 8
+ /// byte address offsets from the The gsym::Header::BaseAddress. The table is
+ /// stored internally as a array of bytes that are in the correct endianness.
+ /// In order to extract an address from the address table we must access the
+ /// address offset using the correct size and then add it to the BaseAddress
+ /// in the header.
+ ///
+ /// \param Index An index into the AddrOffsets array.
+ /// \returns An virtual address that matches the original object file for the
+ /// address as the specified index, or llvm::None if Index is out of bounds.
+ template <class T> Optional<uint64_t>
+ addressForIndex(size_t Index) const {
+ ArrayRef<T> AIO = getAddrOffsets<T>();
+ if (Index < AIO.size())
+ return AIO[Index] + Hdr->BaseAddress;
+ return llvm::None;
+ }
+ /// Lookup an address offset in the AddrOffsets table.
+ ///
+ /// Given an address offset, look it up using a binary search of the
+ /// AddrOffsets table.
+ ///
+ /// \param AddrOffset An address offset, that has already been computed by
+ /// subtracting the gsym::Header::BaseAddress.
+ /// \returns The matching address offset index. This index will be used to
+ /// extract the FunctionInfo data's offset from the AddrInfoOffsets array.
+ template <class T>
+ llvm::Optional<uint64_t> getAddressOffsetIndex(const uint64_t AddrOffset) const {
+ ArrayRef<T> AIO = getAddrOffsets<T>();
+ const auto Begin = AIO.begin();
+ const auto End = AIO.end();
+ auto Iter = std::lower_bound(Begin, End, AddrOffset);
+ // Watch for addresses that fall between the gsym::Header::BaseAddress and
+ // the first address offset.
+ if (Iter == Begin && AddrOffset < *Begin)
+ return llvm::None;
+ if (Iter == End || AddrOffset < *Iter)
+ --Iter;
+ return std::distance(Begin, Iter);
+ }
+
+ /// Create a GSYM from a memory buffer.
+ ///
+ /// Called by both openFile() and copyBuffer(), this function does all of the
+ /// work of parsing the GSYM file and returning an error.
+ ///
+ /// \param MemBuffer A memory buffer that will transfer ownership into the
+ /// GsymReader.
+ /// \returns An expected GsymReader that contains the object or an error
+ /// object that indicates reason for failing to read the GSYM.
+ static llvm::Expected<llvm::gsym::GsymReader>
+ create(std::unique_ptr<MemoryBuffer> &MemBuffer);
+
+
+ /// Given an address, find the address index.
+ ///
+ /// Binary search the address table and find the matching address index.
+ ///
+ /// \param Addr A virtual address that matches the original object file
+ /// to lookup.
+ /// \returns An index into the address table. This index can be used to
+ /// extract the FunctionInfo data's offset from the AddrInfoOffsets array.
+ /// Returns an error if the address isn't in the GSYM with details of why.
+ Expected<uint64_t> getAddressIndex(const uint64_t Addr) const;
+
+ /// Given an address index, get the offset for the FunctionInfo.
+ ///
+ /// Looking up an address is done by finding the corresponding address
+ /// index for the address. This index is then used to get the offset of the
+ /// FunctionInfo data that we will decode using this function.
+ ///
+ /// \param Index An index into the address table.
+ /// \returns An optional GSYM data offset for the offset of the FunctionInfo
+ /// that needs to be decoded.
+ Optional<uint64_t> getAddressInfoOffset(size_t Index) const;
+};
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_GSYMREADER_H