[memprof] Extend llvm-profdata to display MemProf profile summaries.

This commit adds initial support to llvm-profdata to read and print
summaries of raw memprof profiles.
Summary of changes:
* Refactor shared defs to MemProfData.inc
* Extend show_main to display memprof profile summaries.
* Add a simple raw memprof profile reader.
* Add a couple of tests to tools/llvm-profdata.

Differential Revision: https://reviews.llvm.org/D114286

GitOrigin-RevId: 7cca33b40f77c2d8bcd4241bcd0e4c45a0209683
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 7b415f0..2040871 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -23,6 +23,7 @@
 if (COMPILER_RT_BUILD_MEMPROF)
   set(MEMPROF_HEADERS
     sanitizer/memprof_interface.h
+    profile/MemProfData.inc
     )
 endif(COMPILER_RT_BUILD_MEMPROF)
 
diff --git a/include/profile/MemProfData.inc b/include/profile/MemProfData.inc
new file mode 100644
index 0000000..d64227e
--- /dev/null
+++ b/include/profile/MemProfData.inc
@@ -0,0 +1,61 @@
+#ifndef MEMPROF_DATA_INC
+#define MEMPROF_DATA_INC
+/*===-- MemProfData.inc - MemProf profiling runtime structures -*- 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 is the main file that defines all the data structure, signature,
+ * constant literals that are shared across profiling runtime library,
+ * and host tools (reader/writer).
+ *
+ * This file has two identical copies. The primary copy lives in LLVM and
+ * the other one sits in compiler-rt/include/profile directory. To make changes
+ * in this file, first modify the primary copy and copy it over to compiler-rt.
+ * Testing of any change in this file can start only after the two copies are
+ * synced up.
+ *
+\*===----------------------------------------------------------------------===*/
+
+
+#ifdef _MSC_VER
+#define PACKED(__decl__) __pragma(pack(push,1)) __decl__ __pragma(pack(pop))
+#else
+#define PACKED(__decl__) __decl__ __attribute__((__packed__))
+#endif
+
+// A 64-bit magic number to uniquely identify the raw binary memprof profile file.
+#define MEMPROF_RAW_MAGIC_64                                                                        \
+  ((uint64_t)255 << 56 | (uint64_t)'m' << 48 | (uint64_t)'p' << 40 | (uint64_t)'r' << 32 |          \
+   (uint64_t)'o' << 24 | (uint64_t)'f' << 16 | (uint64_t)'r' << 8 | (uint64_t)129)
+
+// The version number of the raw binary format.
+#define MEMPROF_RAW_VERSION 1ULL
+
+namespace llvm {
+namespace memprof {
+// A struct describing the header used for the raw binary memprof profile format.
+PACKED(struct Header {
+  uint64_t Magic;
+  uint64_t Version;
+  uint64_t TotalSize;
+  uint64_t SegmentOffset;
+  uint64_t MIBOffset;
+  uint64_t StackOffset;
+});
+
+// A struct describing the information necessary to describe a /proc/maps
+// segment entry for a particular binary/library identified by its build id.
+PACKED(struct SegmentEntry {
+  uint64_t Start;
+  uint64_t End;
+  uint64_t Offset;
+  uint8_t BuildId[32];
+});
+} // namespace memprof
+} // namespace llvm
+
+#endif
diff --git a/lib/memprof/CMakeLists.txt b/lib/memprof/CMakeLists.txt
index f797610..20d6992 100644
--- a/lib/memprof/CMakeLists.txt
+++ b/lib/memprof/CMakeLists.txt
@@ -46,6 +46,7 @@
   )
 
 include_directories(..)
+include_directories(../../include)
 
 set(MEMPROF_CFLAGS ${SANITIZER_COMMON_CFLAGS})
 set(MEMPROF_COMMON_DEFINITIONS "")
diff --git a/lib/memprof/memprof_rawprofile.cpp b/lib/memprof/memprof_rawprofile.cpp
index 96f315f..48e579c 100644
--- a/lib/memprof/memprof_rawprofile.cpp
+++ b/lib/memprof/memprof_rawprofile.cpp
@@ -1,5 +1,10 @@
-#include "memprof_rawprofile.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "memprof_meminfoblock.h"
+#include "memprof_rawprofile.h"
+#include "profile/MemProfData.inc"
 #include "sanitizer_common/sanitizer_allocator_internal.h"
 #include "sanitizer_common/sanitizer_linux.h"
 #include "sanitizer_common/sanitizer_procmaps.h"
@@ -8,29 +13,12 @@
 #include "sanitizer_common/sanitizer_stacktrace.h"
 #include "sanitizer_common/sanitizer_vector.h"
 
-#include <stdlib.h>
-#include <string.h>
-
 namespace __memprof {
 using ::__sanitizer::Vector;
+using SegmentEntry = ::llvm::memprof::SegmentEntry;
+using Header = ::llvm::memprof::Header;
 
 namespace {
-typedef struct __attribute__((__packed__)) {
-  u64 start;
-  u64 end;
-  u64 offset;
-  u8 buildId[32];
-} SegmentEntry;
-
-typedef struct __attribute__((__packed__)) {
-  u64 magic;
-  u64 version;
-  u64 total_size;
-  u64 segment_offset;
-  u64 mib_offset;
-  u64 stack_offset;
-} Header;
-
 template <class T> char *WriteBytes(T Pod, char *&Buffer) {
   *(T *)Buffer = Pod;
   return Buffer + sizeof(T);
@@ -76,12 +64,12 @@
 
   for (Layout.Reset(); Layout.Next(&segment);) {
     if (segment.IsReadable() && segment.IsExecutable()) {
-      SegmentEntry entry{};
-      entry.start = segment.start;
-      entry.end = segment.end;
-      entry.offset = segment.offset;
-      memcpy(entry.buildId, segment.uuid, sizeof(segment.uuid));
-      memcpy(Ptr, &entry, sizeof(SegmentEntry));
+      SegmentEntry Entry{};
+      Entry.Start = segment.start;
+      Entry.End = segment.end;
+      Entry.Offset = segment.offset;
+      memcpy(Entry.BuildId, segment.uuid, sizeof(segment.uuid));
+      memcpy(Ptr, &Entry, sizeof(SegmentEntry));
       Ptr += sizeof(SegmentEntry);
       NumSegmentsRecorded++;
     }
diff --git a/lib/memprof/memprof_rawprofile.h b/lib/memprof/memprof_rawprofile.h
index 052bac3..575104e 100644
--- a/lib/memprof/memprof_rawprofile.h
+++ b/lib/memprof/memprof_rawprofile.h
@@ -5,17 +5,10 @@
 #include "sanitizer_common/sanitizer_procmaps.h"
 
 namespace __memprof {
-
-// TODO: pull these in from MemProfData.inc
-#define MEMPROF_RAW_MAGIC_64                                                   \
-  (u64)255 << 56 | (u64)'m' << 48 | (u64)'p' << 40 | (u64)'r' << 32 |          \
-      (u64)'o' << 24 | (u64)'f' << 16 | (u64)'r' << 8 | (u64)129
-
-#define MEMPROF_RAW_VERSION 1ULL
-
+// Serialize the in-memory representation of the memprof profile to the raw
+// binary format. The format itself is documented memprof_rawprofile.cpp.
 u64 SerializeToRawProfile(MIBMapTy &BlockCache, MemoryMappingLayoutBase &Layout,
                           char *&Buffer);
-
 } // namespace __memprof
 
 #endif // MEMPROF_RAWPROFILE_H_