Commit 57cafdf2 authored by Shile Zhang's avatar Shile Zhang Committed by Ingo Molnar

scripts/sortextable: Refactor the do_func() function

Refine the loop, naming and code structure, make the code more readable
and extendable. No functional changes intended.
Signed-off-by: default avatarShile Zhang <shile.zhang@linux.alibaba.com>
Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Michal Marek <michal.lkml@markovi.net>
Cc: linux-kbuild@vger.kernel.org
Link: https://lkml.kernel.org/r/20191204004633.88660-5-shile.zhang@linux.alibaba.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent abe4f92c
...@@ -320,7 +320,7 @@ static int do_file(char const *const fname, void *addr) ...@@ -320,7 +320,7 @@ static int do_file(char const *const fname, void *addr)
"unrecognized ET_EXEC/ET_DYN file: %s\n", fname); "unrecognized ET_EXEC/ET_DYN file: %s\n", fname);
break; break;
} }
rc = do32(ehdr, fname, custom_sort); rc = do_sort_32(ehdr, fname, custom_sort);
break; break;
case ELFCLASS64: case ELFCLASS64:
{ {
...@@ -332,7 +332,7 @@ static int do_file(char const *const fname, void *addr) ...@@ -332,7 +332,7 @@ static int do_file(char const *const fname, void *addr)
fname); fname);
break; break;
} }
rc = do64(ghdr, fname, custom_sort); rc = do_sort_64(ghdr, fname, custom_sort);
} }
break; break;
default: default:
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#undef extable_ent_size #undef extable_ent_size
#undef compare_extable #undef compare_extable
#undef do_func #undef do_sort
#undef Elf_Addr #undef Elf_Addr
#undef Elf_Ehdr #undef Elf_Ehdr
#undef Elf_Shdr #undef Elf_Shdr
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#ifdef SORTEXTABLE_64 #ifdef SORTEXTABLE_64
# define extable_ent_size 16 # define extable_ent_size 16
# define compare_extable compare_extable_64 # define compare_extable compare_extable_64
# define do_func do64 # define do_sort do_sort_64
# define Elf_Addr Elf64_Addr # define Elf_Addr Elf64_Addr
# define Elf_Ehdr Elf64_Ehdr # define Elf_Ehdr Elf64_Ehdr
# define Elf_Shdr Elf64_Shdr # define Elf_Shdr Elf64_Shdr
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#else #else
# define extable_ent_size 8 # define extable_ent_size 8
# define compare_extable compare_extable_32 # define compare_extable compare_extable_32
# define do_func do32 # define do_sort do_sort_32
# define Elf_Addr Elf32_Addr # define Elf_Addr Elf32_Addr
# define Elf_Ehdr Elf32_Ehdr # define Elf_Ehdr Elf32_Ehdr
# define Elf_Shdr Elf32_Shdr # define Elf_Shdr Elf32_Shdr
...@@ -87,81 +87,81 @@ static int compare_extable(const void *a, const void *b) ...@@ -87,81 +87,81 @@ static int compare_extable(const void *a, const void *b)
return 0; return 0;
} }
static int do_func(Elf_Ehdr *ehdr, static int do_sort(Elf_Ehdr *ehdr,
char const *const fname, char const *const fname,
table_sort_t custom_sort) table_sort_t custom_sort)
{ {
Elf_Shdr *shdr; Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
Elf_Shdr *shstrtab_sec;
Elf_Shdr *strtab_sec = NULL; Elf_Shdr *strtab_sec = NULL;
Elf_Shdr *symtab_sec = NULL; Elf_Shdr *symtab_sec = NULL;
Elf_Shdr *extab_sec = NULL; Elf_Shdr *extab_sec = NULL;
Elf_Sym *sym; Elf_Sym *sym;
const Elf_Sym *symtab; const Elf_Sym *symtab;
Elf32_Word *symtab_shndx_start = NULL; Elf32_Word *symtab_shndx = NULL;
Elf_Sym *sort_needed_sym; Elf_Sym *sort_needed_sym = NULL;
Elf_Shdr *sort_needed_sec; Elf_Shdr *sort_needed_sec;
Elf_Rel *relocs = NULL; Elf_Rel *relocs = NULL;
int relocs_size = 0; int relocs_size = 0;
uint32_t *sort_done_location; uint32_t *sort_needed_loc;
const char *secstrtab; const char *secstrings;
const char *strtab; const char *strtab;
char *extab_image; char *extab_image;
int extab_index = 0; int extab_index = 0;
int i; int i;
int idx; int idx;
unsigned int num_sections; unsigned int shnum;
unsigned int secindex_strings; unsigned int shstrndx;
shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); shstrndx = r2(&ehdr->e_shstrndx);
if (shstrndx == SHN_XINDEX)
shstrndx = r(&shdr[0].sh_link);
secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
num_sections = r2(&ehdr->e_shnum); shnum = r2(&ehdr->e_shnum);
if (num_sections == SHN_UNDEF) if (shnum == SHN_UNDEF)
num_sections = _r(&shdr[0].sh_size); shnum = _r(&shdr[0].sh_size);
secindex_strings = r2(&ehdr->e_shstrndx); for (i = 0, s = shdr; s < shdr + shnum; i++, s++) {
if (secindex_strings == SHN_XINDEX) idx = r(&s->sh_name);
secindex_strings = r(&shdr[0].sh_link); if (!strcmp(secstrings + idx, "__ex_table")) {
extab_sec = s;
shstrtab_sec = shdr + secindex_strings;
secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset);
for (i = 0; i < num_sections; i++) {
idx = r(&shdr[i].sh_name);
if (!strcmp(secstrtab + idx, "__ex_table")) {
extab_sec = shdr + i;
extab_index = i; extab_index = i;
} }
if ((r(&shdr[i].sh_type) == SHT_REL || if (!strcmp(secstrings + idx, ".symtab"))
r(&shdr[i].sh_type) == SHT_RELA) && symtab_sec = s;
r(&shdr[i].sh_info) == extab_index) { if (!strcmp(secstrings + idx, ".strtab"))
relocs = (void *)ehdr + _r(&shdr[i].sh_offset); strtab_sec = s;
relocs_size = _r(&shdr[i].sh_size);
if ((r(&s->sh_type) == SHT_REL ||
r(&s->sh_type) == SHT_RELA) &&
r(&s->sh_info) == extab_index) {
relocs = (void *)ehdr + _r(&s->sh_offset);
relocs_size = _r(&s->sh_size);
} }
if (!strcmp(secstrtab + idx, ".symtab")) if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
symtab_sec = shdr + i; symtab_shndx = (Elf32_Word *)((const char *)ehdr +
if (!strcmp(secstrtab + idx, ".strtab")) _r(&s->sh_offset));
strtab_sec = shdr + i;
if (r(&shdr[i].sh_type) == SHT_SYMTAB_SHNDX)
symtab_shndx_start = (Elf32_Word *)(
(const char *)ehdr + _r(&shdr[i].sh_offset));
} }
if (!strtab_sec) {
fprintf(stderr, "no .strtab in file: %s\n", fname); if (!extab_sec) {
fprintf(stderr, "no __ex_table in file: %s\n", fname);
return -1; return -1;
} }
if (!symtab_sec) { if (!symtab_sec) {
fprintf(stderr, "no .symtab in file: %s\n", fname); fprintf(stderr, "no .symtab in file: %s\n", fname);
return -1; return -1;
} }
symtab = (const Elf_Sym *)((const char *)ehdr +
_r(&symtab_sec->sh_offset)); if (!strtab_sec) {
if (!extab_sec) { fprintf(stderr, "no .strtab in file: %s\n", fname);
fprintf(stderr, "no __ex_table in file: %s\n", fname);
return -1; return -1;
} }
strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
extab_image = (void *)ehdr + _r(&extab_sec->sh_offset); extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
symtab = (const Elf_Sym *)((const char *)ehdr +
_r(&symtab_sec->sh_offset));
if (custom_sort) { if (custom_sort) {
custom_sort(extab_image, _r(&extab_sec->sh_size)); custom_sort(extab_image, _r(&extab_sec->sh_size));
...@@ -170,38 +170,41 @@ static int do_func(Elf_Ehdr *ehdr, ...@@ -170,38 +170,41 @@ static int do_func(Elf_Ehdr *ehdr,
qsort(extab_image, num_entries, qsort(extab_image, num_entries,
extable_ent_size, compare_extable); extable_ent_size, compare_extable);
} }
/* If there were relocations, we no longer need them. */ /* If there were relocations, we no longer need them. */
if (relocs) if (relocs)
memset(relocs, 0, relocs_size); memset(relocs, 0, relocs_size);
/* find main_extable_sort_needed */ /* find the flag main_extable_sort_needed */
sort_needed_sym = NULL; for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
for (i = 0; i < _r(&symtab_sec->sh_size) / sizeof(Elf_Sym); i++) { sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
sym = (void *)ehdr + _r(&symtab_sec->sh_offset); sym++) {
sym += i;
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
continue; continue;
idx = r(&sym->st_name); if (!strcmp(strtab + r(&sym->st_name),
if (!strcmp(strtab + idx, "main_extable_sort_needed")) { "main_extable_sort_needed")) {
sort_needed_sym = sym; sort_needed_sym = sym;
break; break;
} }
} }
if (!sort_needed_sym) { if (!sort_needed_sym) {
fprintf(stderr, fprintf(stderr,
"no main_extable_sort_needed symbol in file: %s\n", "no main_extable_sort_needed symbol in file: %s\n",
fname); fname);
return -1; return -1;
} }
sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx), sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
sort_needed_sym - symtab, sort_needed_sym - symtab,
symtab_shndx_start)]; symtab_shndx)];
sort_done_location = (void *)ehdr + sort_needed_loc = (void *)ehdr +
_r(&sort_needed_sec->sh_offset) + _r(&sort_needed_sec->sh_offset) +
_r(&sort_needed_sym->st_value) - _r(&sort_needed_sym->st_value) -
_r(&sort_needed_sec->sh_addr); _r(&sort_needed_sec->sh_addr);
/* We sorted it, clear the flag. */ /* extable has been sorted, clear the flag */
w(0, sort_done_location); w(0, sort_needed_loc);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment