forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 958e46acc8e900e8569dd467c1af9b8d2d019394
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,102 @@
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;
6564 };
6665
67
-struct rela {
66
+struct reloc {
6867 struct list_head list;
6968 struct hlist_node hash;
70
- GElf_Rela rela;
71
- struct section *rela_sec;
69
+ union {
70
+ GElf_Rela rela;
71
+ GElf_Rel rel;
72
+ };
73
+ struct section *sec;
7274 struct symbol *sym;
73
- unsigned int type;
7475 unsigned long offset;
75
- int addend;
76
+ unsigned int type;
77
+ s64 addend;
78
+ int idx;
79
+ bool jump_table_start;
7680 };
81
+
82
+#define ELF_HASH_BITS 20
7783
7884 struct elf {
7985 Elf *elf;
8086 GElf_Ehdr ehdr;
8187 int fd;
88
+ bool changed;
8289 char *name;
8390 struct list_head sections;
84
- DECLARE_HASHTABLE(rela_hash, 16);
91
+ DECLARE_HASHTABLE(symbol_hash, ELF_HASH_BITS);
92
+ DECLARE_HASHTABLE(symbol_name_hash, ELF_HASH_BITS);
93
+ DECLARE_HASHTABLE(section_hash, ELF_HASH_BITS);
94
+ DECLARE_HASHTABLE(section_name_hash, ELF_HASH_BITS);
95
+ DECLARE_HASHTABLE(reloc_hash, ELF_HASH_BITS);
8596 };
8697
98
+#define OFFSET_STRIDE_BITS 4
99
+#define OFFSET_STRIDE (1UL << OFFSET_STRIDE_BITS)
100
+#define OFFSET_STRIDE_MASK (~(OFFSET_STRIDE - 1))
87101
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);
102
+#define for_offset_range(_offset, _start, _end) \
103
+ for (_offset = ((_start) & OFFSET_STRIDE_MASK); \
104
+ _offset >= ((_start) & OFFSET_STRIDE_MASK) && \
105
+ _offset <= ((_end) & OFFSET_STRIDE_MASK); \
106
+ _offset += OFFSET_STRIDE)
107
+
108
+static inline u32 sec_offset_hash(struct section *sec, unsigned long offset)
109
+{
110
+ u32 ol, oh, idx = sec->idx;
111
+
112
+ offset &= OFFSET_STRIDE_MASK;
113
+
114
+ ol = offset;
115
+ oh = (offset >> 16) >> 16;
116
+
117
+ __jhash_mix(ol, oh, idx);
118
+
119
+ return ol;
120
+}
121
+
122
+static inline u32 reloc_hash(struct reloc *reloc)
123
+{
124
+ return sec_offset_hash(reloc->sec, reloc->offset);
125
+}
126
+
127
+struct elf *elf_open_read(const char *name, int flags);
128
+struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
129
+
130
+int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
131
+ unsigned int type, struct symbol *sym, s64 addend);
132
+int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
133
+ unsigned long offset, unsigned int type,
134
+ struct section *insn_sec, unsigned long insn_off);
135
+
136
+int elf_write_insn(struct elf *elf, struct section *sec,
137
+ unsigned long offset, unsigned int len,
138
+ const char *insn);
139
+int elf_write_reloc(struct elf *elf, struct reloc *reloc);
101140 int elf_write(struct elf *elf);
102141 void elf_close(struct elf *elf);
103142
143
+struct section *find_section_by_name(const struct elf *elf, const char *name);
144
+struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
145
+struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
146
+struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
147
+struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
148
+struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
149
+struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
150
+ unsigned long offset, unsigned int len);
151
+struct symbol *find_func_containing(struct section *sec, unsigned long offset);
152
+
104153 #define for_each_sec(file, sec) \
105154 list_for_each_entry(sec, &file->elf->sections, list)
106155