forked from google/LLpatch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
elf_symbol.h
143 lines (121 loc) · 4.35 KB
/
elf_symbol.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Author: Yonghyun Hwang <[email protected]>
*/
#ifndef ELF_SYMBOL_H_
#define ELF_SYMBOL_H_
#include <gelf.h>
#include <cstdint>
#include <limits>
#include <iterator>
#include <string_view>
#include "llvm/ADT/StringRef.h"
namespace llvm
{
class Function;
}
// This class creates an iterator to browse through all symbols in elf
// binary and handles the symbols in it.
class ElfSymbol final {
public:
enum class SectionIndex : std::uint16_t {
UNDEF = 0, /* Undefined section */
LORESERVE = 0xff00, /* Start of reserved indices */
LOPROC = 0xff00, /* Start of processor-specific */
HIPROC = 0xff1f, /* End of processor-specific */
LIVEPATCH = 0xff20, /* Special for kernel livepatch */
HIOS = 0xff3f, /* End of OS-specific */
ABS = 0xfff1, /* Associated symbol is absolute */
COMMON = 0xfff2, /* Associated symbol is common */
XINDEX = 0xffff, /* Index is in extra table. */
HIRESERVE = 0xffff /* End of reserved indices */
};
// Symbol types. enum values, STT_*, come from gelf.h
enum class SymbolType : std::uint8_t {
NOTYPE = STT_NOTYPE,
OBJECT = STT_OBJECT,
FUNC = STT_FUNC,
SECTION = STT_SECTION,
FILE = STT_FILE,
COMMON = STT_COMMON,
TLS = STT_TLS,
NUM = STT_NUM,
LOOS = STT_LOOS,
HIOS = STT_HIOS,
LOPROC = STT_LOPROC,
HIPROC = STT_HIPROC
};
ElfSymbol(Elf *elf) noexcept(false);
~ElfSymbol() = default;
// Don't allow copy.
ElfSymbol(const ElfSymbol &rhs) = delete;
ElfSymbol &operator=(const ElfSymbol &rhs) = delete;
// Iterator to browse through all symbols. This iterator does not
// support backward move. This is mainly used for ranged-for.
class Iterator final
: public std::iterator<std::forward_iterator_tag, ElfSymbol *> {
public:
Iterator(ElfSymbol *symbol);
~Iterator() = default;
bool operator==(const Iterator &other) const;
bool operator!=(const Iterator &other) const;
ElfSymbol *operator*() const;
Iterator &operator++();
private:
ElfSymbol *symbol_ = nullptr;
};
Iterator begin();
Iterator end();
std::string_view Name() const noexcept(false);
std::string_view Name(size_t cursor) const noexcept(false);
// Symbol entry in a symbol table has an offset in string section
// for symbols' name. Unfortunately, gelf doesn't provide a good
// abstraction for renaming symbol, which requires a clear
// understanding on the structure of ELF binary. For now, This
// function takes a new offset for symbol name and simply updates
// its index. Therefore, outside of this class, string section
// should be modified, which is ugly.
void Rename(uint32_t name_offset) noexcept(false);
SymbolType Type() noexcept(false);
SymbolType Type(size_t cursor) noexcept(false);
size_t GetStringSectionIndex();
bool HasSectionIndex(SectionIndex idx);
bool HasSectionIndex(SectionIndex idx, size_t cursor);
void SetSectionIndex(SectionIndex idx);
void SetSectionIndex(SectionIndex idx, size_t cursor);
bool IsKLPLocalSymbol() const noexcept(false);
bool IsLLpatchSymbol() const noexcept(false);
std::string_view GetLLpatchSymbolAlias() const;
static std::string CreateKlpLocalSymName(llvm::StringRef sym_name);
static std::string
CreateLivepatchedFunctionName(const llvm::Function &fn,
llvm::StringRef base_path);
static std::string
CreateLivepatchedSymbolName(llvm::StringRef orig_name,
llvm::StringRef filename,
llvm::StringRef base_path);
private:
void GetGElfSymbol(GElf_Sym *sym) const noexcept(false);
void GetGElfSymbol(GElf_Sym *sym, size_t cursor) const noexcept(false);
void SetGElfSymbol(GElf_Sym *sym) noexcept(false);
void SetGElfSymbol(GElf_Sym *sym, size_t cursor) noexcept(false);
Elf *elf_ = nullptr;
size_t str_sec_idx_ = 0;
Elf_Data *symtab_ = nullptr;
size_t sym_cursor_ = std::numeric_limits<size_t>::max();
size_t sym_count_ = 0;
};
#endif // ELF_SYMBOL_H_