forked from google/autofdo
-
Notifications
You must be signed in to change notification settings - Fork 1
/
llvm_propeller_binary_content.h
111 lines (93 loc) · 4.13 KB
/
llvm_propeller_binary_content.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#ifndef AUTOFDOLLVM_PROPELLER_BINARY_CONTENT_H_
#define AUTOFDOLLVM_PROPELLER_BINARY_CONTENT_H_
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "third_party/abseil/absl/container/flat_hash_map.h"
#include "third_party/abseil/absl/status/status.h"
#include "third_party/abseil/absl/status/statusor.h"
#include "third_party/abseil/absl/strings/string_view.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ObjectFile.h"
namespace devtools_crosstool_autofdo {
// BinaryContent represents information for an ELF executable or a shared
// object, the data contained include (loadable) segments, file name, file
// content and DYN tag (is_pie).
struct BinaryContent {
struct Segment {
uint64_t offset;
uint64_t vaddr;
uint64_t memsz;
};
struct KernelModule {
// The section index of the first section which has EXEC and ALLOC flags set
// and has name ".text". This field is only meant for
// ELFObjectFile::readBBAddrMap.
int text_section_index;
// The module's metadata stored as (key, value) pairs in ".modinfo" section.
// The "name" and "description" will be printed out via LOG statements.
// Ideally we shall read
// ".gnu.linkonce.this_module" section, which has a more thorough
// information for the module, however, that would need to build this tool
// again kernel headers.
// https://source.corp.google.com/h/prodkernel/kernel/release/11xx/+/next:include/linux/module.h;l=365;bpv=1;bpt=0;drc=f2a96a349893fdff944b710ee86d1106de088a40
absl::flat_hash_map<absl::string_view, absl::string_view> modinfo;
};
std::string file_name;
// If not empty, it is the existing dwp file for the binary.
std::string dwp_file_name;
std::unique_ptr<llvm::MemoryBuffer> file_content = nullptr;
std::unique_ptr<llvm::object::ObjectFile> object_file = nullptr;
std::unique_ptr<llvm::DWARFContext> dwarf_context = nullptr;
bool is_pie = false;
// Propeller accepts relocatable object files as input only if it is a kernel
// module.
bool is_relocatable = false;
std::vector<Segment> segments;
std::string build_id;
// Only not-null when input is *.ko and `ELFFileUtil::InitializeKernelModule`
// returns ok status.
std::optional<KernelModule> kernel_module = std::nullopt;
};
// Utility class that wraps utility functions that need templated
// ELFFile<ELFT> support.
class ELFFileUtilBase {
protected:
ELFFileUtilBase() = default;
public:
virtual ~ELFFileUtilBase() = default;
virtual std::string GetBuildId() = 0;
// Reads loadable and executable segment information into
// BinaryContent::segments.
virtual absl::Status ReadLoadableSegments(BinaryContent &binary_content) = 0;
// Initializes BinaryContent::KernelModule::modinfo from the .modinfo section,
// if binary_content does not contain a valid kernel module, return error
// status.
virtual absl::Status InitializeKernelModule(
BinaryContent &binary_content) = 0;
// Parses (key, value) pairs in `section_content` and store them in `modinfo`.
static absl::StatusOr<
absl::flat_hash_map<absl::string_view, absl::string_view>>
ParseModInfoSectionContent(absl::string_view section_content);
protected:
static constexpr llvm::StringRef kModInfoSectionName = ".modinfo";
static constexpr llvm::StringRef kLinkOnceSectionName =
".gnu.linkonce.this_module";
static constexpr llvm::StringRef kBuildIDSectionName = ".note.gnu.build-id";
// Kernel images built via gbuild use section name ".notes" for buildid.
static constexpr llvm::StringRef kKernelBuildIDSectionName = ".notes";
static constexpr llvm::StringRef kBuildIdNoteName = "GNU";
friend std::unique_ptr<ELFFileUtilBase> CreateELFFileUtil(
llvm::object::ObjectFile *object_file);
};
std::unique_ptr<ELFFileUtilBase> CreateELFFileUtil(
llvm::object::ObjectFile *object_file);
absl::StatusOr<std::unique_ptr<BinaryContent>> GetBinaryContent(
absl::string_view binary_file_name);
} // namespace devtools_crosstool_autofdo
#endif // AUTOFDOLLVM_PROPELLER_BINARY_CONTENT_H_