hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/tools/objtool/elf.h
....@@ -1,18 +1,6 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * Copyright (C) 2015 Josh Poimboeuf <jpoimboe@redhat.com>
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License
6
- * as published by the Free Software Foundation; either version 2
7
- * of the License, or (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
164 */
175
186 #ifndef _OBJTOOL_ELF_H
....@@ -22,6 +10,8 @@
2210 #include <gelf.h>
2311 #include <linux/list.h>
2412 #include <linux/hashtable.h>
13
+#include <linux/rbtree.h>
14
+#include <linux/jhash.h>
2515
2616 #ifdef LIBELF_USE_DEPRECATED
2717 # define elf_getshdrnum elf_getshnum
....@@ -37,23 +27,26 @@
3727
3828 struct section {
3929 struct list_head list;
30
+ struct hlist_node hash;
31
+ struct hlist_node name_hash;
4032 GElf_Shdr sh;
33
+ struct rb_root symbol_tree;
4134 struct list_head symbol_list;
42
- DECLARE_HASHTABLE(symbol_hash, 8);
43
- struct list_head rela_list;
44
- DECLARE_HASHTABLE(rela_hash, 16);
45
- struct section *base, *rela;
35
+ struct list_head reloc_list;
36
+ struct section *base, *reloc;
4637 struct symbol *sym;
4738 Elf_Data *data;
4839 char *name;
4940 int idx;
5041 unsigned int len;
51
- bool changed, text, rodata;
42
+ bool changed, text, rodata, noinstr;
5243 };
5344
5445 struct symbol {
5546 struct list_head list;
47
+ struct rb_node node;
5648 struct hlist_node hash;
49
+ struct hlist_node name_hash;
5750 GElf_Sym sym;
5851 struct section *sec;
5952 char *name;
....@@ -61,46 +54,103 @@
6154 unsigned char bind, type;
6255 unsigned long offset;
6356 unsigned int len;
64
- struct symbol *pfunc, *cfunc;
57
+ struct symbol *pfunc, *cfunc, *alias;
58
+ u8 uaccess_safe : 1;
59
+ u8 static_call_tramp : 1;
60
+ u8 retpoline_thunk : 1;
61
+ u8 return_thunk : 1;
62
+ u8 fentry : 1;
63
+ u8 kcov : 1;
64
+ u8 embedded_insn : 1;
6565 };
6666
67
-struct rela {
67
+struct reloc {
6868 struct list_head list;
6969 struct hlist_node hash;
70
- GElf_Rela rela;
71
- struct section *rela_sec;
70
+ union {
71
+ GElf_Rela rela;
72
+ GElf_Rel rel;
73
+ };
74
+ struct section *sec;
7275 struct symbol *sym;
73
- unsigned int type;
7476 unsigned long offset;
75
- int addend;
77
+ unsigned int type;
78
+ s64 addend;
79
+ int idx;
80
+ bool jump_table_start;
7681 };
82
+
83
+#define ELF_HASH_BITS 20
7784
7885 struct elf {
7986 Elf *elf;
8087 GElf_Ehdr ehdr;
8188 int fd;
89
+ bool changed;
8290 char *name;
8391 struct list_head sections;
84
- DECLARE_HASHTABLE(rela_hash, 16);
92
+ DECLARE_HASHTABLE(symbol_hash, ELF_HASH_BITS);
93
+ DECLARE_HASHTABLE(symbol_name_hash, ELF_HASH_BITS);
94
+ DECLARE_HASHTABLE(section_hash, ELF_HASH_BITS);
95
+ DECLARE_HASHTABLE(section_name_hash, ELF_HASH_BITS);
96
+ DECLARE_HASHTABLE(reloc_hash, ELF_HASH_BITS);
8597 };
8698
99
+#define OFFSET_STRIDE_BITS 4
100
+#define OFFSET_STRIDE (1UL << OFFSET_STRIDE_BITS)
101
+#define OFFSET_STRIDE_MASK (~(OFFSET_STRIDE - 1))
87102
88
-struct elf *elf_open(const char *name, int flags);
89
-struct section *find_section_by_name(struct elf *elf, const char *name);
90
-struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
91
-struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
92
-struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
93
-struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
94
-struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
95
- unsigned int len);
96
-struct symbol *find_containing_func(struct section *sec, unsigned long offset);
97
-struct section *elf_create_section(struct elf *elf, const char *name, size_t
98
- entsize, int nr);
99
-struct section *elf_create_rela_section(struct elf *elf, struct section *base);
100
-int elf_rebuild_rela_section(struct section *sec);
103
+#define for_offset_range(_offset, _start, _end) \
104
+ for (_offset = ((_start) & OFFSET_STRIDE_MASK); \
105
+ _offset >= ((_start) & OFFSET_STRIDE_MASK) && \
106
+ _offset <= ((_end) & OFFSET_STRIDE_MASK); \
107
+ _offset += OFFSET_STRIDE)
108
+
109
+static inline u32 sec_offset_hash(struct section *sec, unsigned long offset)
110
+{
111
+ u32 ol, oh, idx = sec->idx;
112
+
113
+ offset &= OFFSET_STRIDE_MASK;
114
+
115
+ ol = offset;
116
+ oh = (offset >> 16) >> 16;
117
+
118
+ __jhash_mix(ol, oh, idx);
119
+
120
+ return ol;
121
+}
122
+
123
+static inline u32 reloc_hash(struct reloc *reloc)
124
+{
125
+ return sec_offset_hash(reloc->sec, reloc->offset);
126
+}
127
+
128
+struct elf *elf_open_read(const char *name, int flags);
129
+struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
130
+
131
+int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
132
+ unsigned int type, struct symbol *sym, s64 addend);
133
+int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
134
+ unsigned long offset, unsigned int type,
135
+ struct section *insn_sec, unsigned long insn_off);
136
+
137
+int elf_write_insn(struct elf *elf, struct section *sec,
138
+ unsigned long offset, unsigned int len,
139
+ const char *insn);
140
+int elf_write_reloc(struct elf *elf, struct reloc *reloc);
101141 int elf_write(struct elf *elf);
102142 void elf_close(struct elf *elf);
103143
144
+struct section *find_section_by_name(const struct elf *elf, const char *name);
145
+struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
146
+struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
147
+struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
148
+struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
149
+struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
150
+struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
151
+ unsigned long offset, unsigned int len);
152
+struct symbol *find_func_containing(struct section *sec, unsigned long offset);
153
+
104154 #define for_each_sec(file, sec) \
105155 list_for_each_entry(sec, &file->elf->sections, list)
106156