Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * sorttable.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Added ORC unwind tables sort support and other updates:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 1999-2019 Alibaba Group Holding Limited. by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Shile Zhang <shile.zhang@linux.alibaba.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright 2011 - 2012 Cavium, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Some of code was taken out of arch/x86/kernel/unwind_orc.c, written by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * Some of this code was taken out of recordmcount.h written by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #undef extable_ent_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #undef compare_extable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #undef do_sort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #undef Elf_Addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #undef Elf_Ehdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #undef Elf_Shdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #undef Elf_Rel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #undef Elf_Rela
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #undef Elf_Sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #undef ELF_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #undef Elf_r_sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #undef ELF_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #undef Elf_r_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #undef ELF_ST_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #undef ELF_ST_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #undef fn_ELF_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #undef fn_ELF_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #undef uint_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #undef _r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #undef _w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #ifdef SORTTABLE_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) # define extable_ent_size	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) # define compare_extable	compare_extable_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) # define do_sort		do_sort_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) # define Elf_Addr		Elf64_Addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) # define Elf_Ehdr		Elf64_Ehdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) # define Elf_Shdr		Elf64_Shdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) # define Elf_Rel		Elf64_Rel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) # define Elf_Rela		Elf64_Rela
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) # define Elf_Sym		Elf64_Sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) # define ELF_R_SYM		ELF64_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) # define Elf_r_sym		Elf64_r_sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) # define ELF_R_INFO		ELF64_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) # define Elf_r_info		Elf64_r_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) # define ELF_ST_BIND		ELF64_ST_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) # define ELF_ST_TYPE		ELF64_ST_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) # define fn_ELF_R_SYM		fn_ELF64_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) # define fn_ELF_R_INFO		fn_ELF64_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) # define uint_t			uint64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) # define _r			r8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) # define _w			w8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) # define extable_ent_size	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) # define compare_extable	compare_extable_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) # define do_sort		do_sort_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) # define Elf_Addr		Elf32_Addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) # define Elf_Ehdr		Elf32_Ehdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) # define Elf_Shdr		Elf32_Shdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) # define Elf_Rel		Elf32_Rel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) # define Elf_Rela		Elf32_Rela
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) # define Elf_Sym		Elf32_Sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) # define ELF_R_SYM		ELF32_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) # define Elf_r_sym		Elf32_r_sym
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) # define ELF_R_INFO		ELF32_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) # define Elf_r_info		Elf32_r_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) # define ELF_ST_BIND		ELF32_ST_BIND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) # define ELF_ST_TYPE		ELF32_ST_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) # define fn_ELF_R_SYM		fn_ELF32_R_SYM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) # define fn_ELF_R_INFO		fn_ELF32_R_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) # define uint_t			uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) # define _r			r
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) # define _w			w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /* ORC unwinder only support X86_64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #include <pthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #include <asm/orc_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define ERRSTR_MAXSZ	256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) char g_err[ERRSTR_MAXSZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) int *g_orc_ip_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) struct orc_entry *g_orc_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) pthread_t orc_sort_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static inline unsigned long orc_ip(const int *ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return (unsigned long)ip + *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int orc_sort_cmp(const void *_a, const void *_b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct orc_entry *orc_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	const int *a = g_orc_ip_table + *(int *)_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	const int *b = g_orc_ip_table + *(int *)_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	unsigned long a_val = orc_ip(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	unsigned long b_val = orc_ip(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (a_val > b_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (a_val < b_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 * The "weak" section terminator entries need to always be on the left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 * to ensure the lookup code skips them in favor of real entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * These terminator entries exist to handle any gaps created by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * whitelisted .o files which didn't get objtool generation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	orc_a = g_orc_table + (a - g_orc_ip_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return orc_a->sp_reg == ORC_REG_UNDEFINED && !orc_a->end ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void *sort_orctable(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int *idxs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int *tmp_orc_ip_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	struct orc_entry *tmp_orc_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	unsigned int *orc_ip_size = (unsigned int *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	unsigned int num_entries = *orc_ip_size / sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	unsigned int orc_size = num_entries * sizeof(struct orc_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	idxs = (int *)malloc(*orc_ip_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (!idxs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		snprintf(g_err, ERRSTR_MAXSZ, "malloc idxs: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			 strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		pthread_exit(g_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	tmp_orc_ip_table = (int *)malloc(*orc_ip_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!tmp_orc_ip_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_ip_table: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			 strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		pthread_exit(g_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	tmp_orc_table = (struct orc_entry *)malloc(orc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (!tmp_orc_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_table: %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			 strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		pthread_exit(g_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/* initialize indices array, convert ip_table to absolute address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	for (i = 0; i < num_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		idxs[i] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		tmp_orc_ip_table[i] = g_orc_ip_table[i] + i * sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	memcpy(tmp_orc_table, g_orc_table, orc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	qsort(idxs, num_entries, sizeof(int), orc_sort_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	for (i = 0; i < num_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		if (idxs[i] == i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		/* convert back to relative address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		g_orc_ip_table[i] = tmp_orc_ip_table[idxs[i]] - i * sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		g_orc_table[i] = tmp_orc_table[idxs[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	free(idxs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	free(tmp_orc_ip_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	free(tmp_orc_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	pthread_exit(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int compare_extable(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	Elf_Addr av = _r(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	Elf_Addr bv = _r(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	if (av < bv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (av > bv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int do_sort(Elf_Ehdr *ehdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		   char const *const fname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		   table_sort_t custom_sort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	int rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	Elf_Shdr *strtab_sec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	Elf_Shdr *symtab_sec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	Elf_Shdr *extab_sec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	Elf_Sym *sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	const Elf_Sym *symtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	Elf32_Word *symtab_shndx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	Elf_Sym *sort_needed_sym = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	Elf_Shdr *sort_needed_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	Elf_Rel *relocs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	int relocs_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	uint32_t *sort_needed_loc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	const char *secstrings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	const char *strtab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	char *extab_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	int extab_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	unsigned int shnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	unsigned int shstrndx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	unsigned int orc_ip_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	unsigned int orc_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	unsigned int orc_num_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	shstrndx = r2(&ehdr->e_shstrndx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (shstrndx == SHN_XINDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		shstrndx = r(&shdr[0].sh_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	shnum = r2(&ehdr->e_shnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (shnum == SHN_UNDEF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		shnum = _r(&shdr[0].sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	for (i = 0, s = shdr; s < shdr + shnum; i++, s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		idx = r(&s->sh_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		if (!strcmp(secstrings + idx, "__ex_table")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			extab_sec = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			extab_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		if (!strcmp(secstrings + idx, ".symtab"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			symtab_sec = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		if (!strcmp(secstrings + idx, ".strtab"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			strtab_sec = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		if ((r(&s->sh_type) == SHT_REL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		     r(&s->sh_type) == SHT_RELA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		    r(&s->sh_info) == extab_index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			relocs = (void *)ehdr + _r(&s->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			relocs_size = _r(&s->sh_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			symtab_shndx = (Elf32_Word *)((const char *)ehdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 						      _r(&s->sh_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		/* locate the ORC unwind tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			orc_ip_size = s->sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			g_orc_ip_table = (int *)((void *)ehdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 						   s->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		if (!strcmp(secstrings + idx, ".orc_unwind")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			orc_size = s->sh_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			g_orc_table = (struct orc_entry *)((void *)ehdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 							     s->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	} /* for loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (!g_orc_ip_table || !g_orc_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			"incomplete ORC unwind tables in file: %s\n", fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	orc_num_entries = orc_ip_size / sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (orc_ip_size % sizeof(int) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	    orc_size % sizeof(struct orc_entry) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	    orc_num_entries != orc_size / sizeof(struct orc_entry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			"inconsistent ORC unwind table entries in file: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	/* create thread to sort ORC unwind tables concurrently */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (pthread_create(&orc_sort_thread, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			   sort_orctable, &orc_ip_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			"pthread_create orc_sort_thread failed '%s': %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			strerror(errno), fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	if (!extab_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		fprintf(stderr,	"no __ex_table in file: %s\n", fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (!symtab_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		fprintf(stderr,	"no .symtab in file: %s\n", fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (!strtab_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		fprintf(stderr,	"no .strtab in file: %s\n", fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	symtab = (const Elf_Sym *)((const char *)ehdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 						  _r(&symtab_sec->sh_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (custom_sort) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		custom_sort(extab_image, _r(&extab_sec->sh_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		int num_entries = _r(&extab_sec->sh_size) / extable_ent_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		qsort(extab_image, num_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		      extable_ent_size, compare_extable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	/* If there were relocations, we no longer need them. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (relocs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		memset(relocs, 0, relocs_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	/* find the flag main_extable_sort_needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	     sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	     sym++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		if (!strcmp(strtab + r(&sym->st_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			    "main_extable_sort_needed")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			sort_needed_sym = sym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (!sort_needed_sym) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			"no main_extable_sort_needed symbol in file: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 					     sort_needed_sym - symtab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 					     symtab_shndx)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	sort_needed_loc = (void *)ehdr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		_r(&sort_needed_sec->sh_offset) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		_r(&sort_needed_sym->st_value) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		_r(&sort_needed_sec->sh_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	/* extable has been sorted, clear the flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	w(0, sort_needed_loc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	if (orc_sort_thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		void *retval = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		/* wait for ORC tables sort done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		rc = pthread_join(orc_sort_thread, &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				"pthread_join failed '%s': %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 				strerror(errno), fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		else if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				"failed to sort ORC tables '%s': %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 				(char *)retval, fname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }