Skip to content

Commit 545f6cf

Browse files
committed
scripts/sorttable: Replace Elf_Shdr Macro with a union
In order to remove the double #include of sorttable.h for 64 and 32 bit to create duplicate functions for both, replace the Elf_Shdr macro with a union that defines both Elf64_Shdr and Elf32_Shdr, with field e64 for the 64bit version, and e32 for the 32bit version. It can then use the macro etype to get the proper value. This will eventually be replaced with just single functions that can handle both 32bit and 64bit ELF parsing. Cc: bpf <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Masahiro Yamada <[email protected]> Cc: Nathan Chancellor <[email protected]> Cc: Nicolas Schier <[email protected]> Cc: Zheng Yejian <[email protected]> Cc: Martin Kelly <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Josh Poimboeuf <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 157fb5b commit 545f6cf

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

scripts/sorttable.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ typedef union {
6969
Elf64_Ehdr e64;
7070
} Elf_Ehdr;
7171

72+
typedef union {
73+
Elf32_Shdr e32;
74+
Elf64_Shdr e64;
75+
} Elf_Shdr;
76+
7277
static uint32_t (*r)(const uint32_t *);
7378
static uint16_t (*r2)(const uint16_t *);
7479
static uint64_t (*r8)(const uint64_t *);
@@ -198,6 +203,11 @@ static int compare_extable_64(const void *a, const void *b)
198203
return av > bv;
199204
}
200205

206+
static inline void *get_index(void *start, int entsize, int index)
207+
{
208+
return start + (entsize * index);
209+
}
210+
201211
/* 32 bit and 64 bit are very similar */
202212
#include "sorttable.h"
203213
#define SORTTABLE_64

scripts/sorttable.h

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#undef sort_mcount_loc
2424
#undef elf_mcount_loc
2525
#undef do_sort
26-
#undef Elf_Shdr
2726
#undef Elf_Sym
2827
#undef ELF_ST_TYPE
2928
#undef uint_t
@@ -37,7 +36,6 @@
3736
# define sort_mcount_loc sort_mcount_loc_64
3837
# define elf_mcount_loc elf_mcount_loc_64
3938
# define do_sort do_sort_64
40-
# define Elf_Shdr Elf64_Shdr
4139
# define Elf_Sym Elf64_Sym
4240
# define ELF_ST_TYPE ELF64_ST_TYPE
4341
# define uint_t uint64_t
@@ -50,7 +48,6 @@
5048
# define sort_mcount_loc sort_mcount_loc_32
5149
# define elf_mcount_loc elf_mcount_loc_32
5250
# define do_sort do_sort_32
53-
# define Elf_Shdr Elf32_Shdr
5451
# define Elf_Sym Elf32_Sym
5552
# define ELF_ST_TYPE ELF32_ST_TYPE
5653
# define uint_t uint32_t
@@ -171,8 +168,8 @@ struct elf_mcount_loc {
171168
static void *sort_mcount_loc(void *arg)
172169
{
173170
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
174-
uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->sh_addr)
175-
+ _r(&(emloc->init_data_sec)->sh_offset);
171+
uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
172+
+ _r(&(emloc->init_data_sec)->etype.sh_offset);
176173
uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
177174
unsigned char *start_loc = (void *)emloc->ehdr + offset;
178175

@@ -222,10 +219,11 @@ static int do_sort(Elf_Ehdr *ehdr,
222219
table_sort_t custom_sort)
223220
{
224221
int rc = -1;
225-
Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
222+
Elf_Shdr *shdr_start;
226223
Elf_Shdr *strtab_sec = NULL;
227224
Elf_Shdr *symtab_sec = NULL;
228225
Elf_Shdr *extab_sec = NULL;
226+
Elf_Shdr *string_sec;
229227
Elf_Sym *sym;
230228
const Elf_Sym *symtab;
231229
Elf32_Word *symtab_shndx = NULL;
@@ -235,7 +233,10 @@ static int do_sort(Elf_Ehdr *ehdr,
235233
const char *secstrings;
236234
const char *strtab;
237235
char *extab_image;
236+
int sort_need_index;
237+
int shentsize;
238238
int idx;
239+
int i;
239240
unsigned int shnum;
240241
unsigned int shstrndx;
241242
#ifdef MCOUNT_SORT_ENABLED
@@ -249,34 +250,40 @@ static int do_sort(Elf_Ehdr *ehdr,
249250
unsigned int orc_num_entries = 0;
250251
#endif
251252

253+
shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
254+
shentsize = r2(&ehdr->etype.e_shentsize);
255+
252256
shstrndx = r2(&ehdr->etype.e_shstrndx);
253257
if (shstrndx == SHN_XINDEX)
254-
shstrndx = r(&shdr[0].sh_link);
255-
secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
258+
shstrndx = r(&shdr_start->etype.sh_link);
259+
string_sec = get_index(shdr_start, shentsize, shstrndx);
260+
secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
256261

257262
shnum = r2(&ehdr->etype.e_shnum);
258263
if (shnum == SHN_UNDEF)
259-
shnum = _r(&shdr[0].sh_size);
264+
shnum = _r(&shdr_start->etype.sh_size);
265+
266+
for (i = 0; i < shnum; i++) {
267+
Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
260268

261-
for (s = shdr; s < shdr + shnum; s++) {
262-
idx = r(&s->sh_name);
269+
idx = r(&shdr->etype.sh_name);
263270
if (!strcmp(secstrings + idx, "__ex_table"))
264-
extab_sec = s;
271+
extab_sec = shdr;
265272
if (!strcmp(secstrings + idx, ".symtab"))
266-
symtab_sec = s;
273+
symtab_sec = shdr;
267274
if (!strcmp(secstrings + idx, ".strtab"))
268-
strtab_sec = s;
275+
strtab_sec = shdr;
269276

270-
if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
277+
if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
271278
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
272-
_r(&s->sh_offset));
279+
_r(&shdr->etype.sh_offset));
273280

274281
#ifdef MCOUNT_SORT_ENABLED
275282
/* locate the .init.data section in vmlinux */
276283
if (!strcmp(secstrings + idx, ".init.data")) {
277284
get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
278285
mstruct.ehdr = ehdr;
279-
mstruct.init_data_sec = s;
286+
mstruct.init_data_sec = shdr;
280287
mstruct.start_mcount_loc = _start_mcount_loc;
281288
mstruct.stop_mcount_loc = _stop_mcount_loc;
282289
}
@@ -285,14 +292,14 @@ static int do_sort(Elf_Ehdr *ehdr,
285292
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
286293
/* locate the ORC unwind tables */
287294
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
288-
orc_ip_size = _r(&s->sh_size);
295+
orc_ip_size = _r(&shdr->etype.sh_size);
289296
g_orc_ip_table = (int *)((void *)ehdr +
290-
_r(&s->sh_offset));
297+
_r(&shdr->etype.sh_offset));
291298
}
292299
if (!strcmp(secstrings + idx, ".orc_unwind")) {
293-
orc_size = _r(&s->sh_size);
300+
orc_size = _r(&shdr->etype.sh_size);
294301
g_orc_table = (struct orc_entry *)((void *)ehdr +
295-
_r(&s->sh_offset));
302+
_r(&shdr->etype.sh_offset));
296303
}
297304
#endif
298305
} /* for loop */
@@ -355,22 +362,22 @@ static int do_sort(Elf_Ehdr *ehdr,
355362
goto out;
356363
}
357364

358-
extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
359-
strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
365+
extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
366+
strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
360367
symtab = (const Elf_Sym *)((const char *)ehdr +
361-
_r(&symtab_sec->sh_offset));
368+
_r(&symtab_sec->etype.sh_offset));
362369

363370
if (custom_sort) {
364-
custom_sort(extab_image, _r(&extab_sec->sh_size));
371+
custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
365372
} else {
366-
int num_entries = _r(&extab_sec->sh_size) / extable_ent_size;
373+
int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
367374
qsort(extab_image, num_entries,
368375
extable_ent_size, compare_extable);
369376
}
370377

371378
/* find the flag main_extable_sort_needed */
372-
for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
373-
sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
379+
for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
380+
sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
374381
sym++) {
375382
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
376383
continue;
@@ -388,13 +395,14 @@ static int do_sort(Elf_Ehdr *ehdr,
388395
goto out;
389396
}
390397

391-
sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
392-
sort_needed_sym - symtab,
393-
symtab_shndx)];
398+
sort_need_index = get_secindex(r2(&sym->st_shndx),
399+
sort_needed_sym - symtab,
400+
symtab_shndx);
401+
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
394402
sort_needed_loc = (void *)ehdr +
395-
_r(&sort_needed_sec->sh_offset) +
403+
_r(&sort_needed_sec->etype.sh_offset) +
396404
_r(&sort_needed_sym->st_value) -
397-
_r(&sort_needed_sec->sh_addr);
405+
_r(&sort_needed_sec->etype.sh_addr);
398406

399407
/* extable has been sorted, clear the flag */
400408
w(0, sort_needed_loc);

0 commit comments

Comments
 (0)