aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/sortextable.c24
-rw-r--r--scripts/sortextable.h26
2 files changed, 47 insertions, 3 deletions
diff --git a/scripts/sortextable.c b/scripts/sortextable.c
index 7c2310c5b996..5f7a8b663cb9 100644
--- a/scripts/sortextable.c
+++ b/scripts/sortextable.c
@@ -152,6 +152,30 @@ static void (*w2)(uint16_t, uint16_t *);
152 152
153typedef void (*table_sort_t)(char *, int); 153typedef void (*table_sort_t)(char *, int);
154 154
155/*
156 * Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
157 * the way to -256..-1, to avoid conflicting with real section
158 * indices.
159 */
160#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
161
162static inline int is_shndx_special(unsigned int i)
163{
164 return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
165}
166
167/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
168static inline unsigned int get_secindex(unsigned int shndx,
169 unsigned int sym_offs,
170 const Elf32_Word *symtab_shndx_start)
171{
172 if (is_shndx_special(shndx))
173 return SPECIAL(shndx);
174 if (shndx != SHN_XINDEX)
175 return shndx;
176 return r(&symtab_shndx_start[sym_offs]);
177}
178
155/* 32 bit and 64 bit are very similar */ 179/* 32 bit and 64 bit are very similar */
156#include "sortextable.h" 180#include "sortextable.h"
157#define SORTEXTABLE_64 181#define SORTEXTABLE_64
diff --git a/scripts/sortextable.h b/scripts/sortextable.h
index f5eb43d42926..8fac3fd697a6 100644
--- a/scripts/sortextable.h
+++ b/scripts/sortextable.h
@@ -98,6 +98,8 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort)
98 Elf_Shdr *symtab_sec = NULL; 98 Elf_Shdr *symtab_sec = NULL;
99 Elf_Shdr *extab_sec = NULL; 99 Elf_Shdr *extab_sec = NULL;
100 Elf_Sym *sym; 100 Elf_Sym *sym;
101 const Elf_Sym *symtab;
102 Elf32_Word *symtab_shndx_start = NULL;
101 Elf_Sym *sort_needed_sym; 103 Elf_Sym *sort_needed_sym;
102 Elf_Shdr *sort_needed_sec; 104 Elf_Shdr *sort_needed_sec;
103 Elf_Rel *relocs = NULL; 105 Elf_Rel *relocs = NULL;
@@ -109,11 +111,22 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort)
109 int extab_index = 0; 111 int extab_index = 0;
110 int i; 112 int i;
111 int idx; 113 int idx;
114 unsigned int num_sections;
115 unsigned int secindex_strings;
112 116
113 shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); 117 shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
114 shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); 118
119 num_sections = r2(&ehdr->e_shnum);
120 if (num_sections == SHN_UNDEF)
121 num_sections = _r(&shdr[0].sh_size);
122
123 secindex_strings = r2(&ehdr->e_shstrndx);
124 if (secindex_strings == SHN_XINDEX)
125 secindex_strings = r(&shdr[0].sh_link);
126
127 shstrtab_sec = shdr + secindex_strings;
115 secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset); 128 secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset);
116 for (i = 0; i < r2(&ehdr->e_shnum); i++) { 129 for (i = 0; i < num_sections; i++) {
117 idx = r(&shdr[i].sh_name); 130 idx = r(&shdr[i].sh_name);
118 if (strcmp(secstrtab + idx, "__ex_table") == 0) { 131 if (strcmp(secstrtab + idx, "__ex_table") == 0) {
119 extab_sec = shdr + i; 132 extab_sec = shdr + i;
@@ -129,6 +142,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort)
129 symtab_sec = shdr + i; 142 symtab_sec = shdr + i;
130 if (strcmp(secstrtab + idx, ".strtab") == 0) 143 if (strcmp(secstrtab + idx, ".strtab") == 0)
131 strtab_sec = shdr + i; 144 strtab_sec = shdr + i;
145 if (r(&shdr[i].sh_type) == SHT_SYMTAB_SHNDX)
146 symtab_shndx_start = (Elf32_Word *)(
147 (const char *)ehdr + _r(&shdr[i].sh_offset));
132 } 148 }
133 if (strtab_sec == NULL) { 149 if (strtab_sec == NULL) {
134 fprintf(stderr, "no .strtab in file: %s\n", fname); 150 fprintf(stderr, "no .strtab in file: %s\n", fname);
@@ -138,6 +154,8 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort)
138 fprintf(stderr, "no .symtab in file: %s\n", fname); 154 fprintf(stderr, "no .symtab in file: %s\n", fname);
139 fail_file(); 155 fail_file();
140 } 156 }
157 symtab = (const Elf_Sym *)((const char *)ehdr +
158 _r(&symtab_sec->sh_offset));
141 if (extab_sec == NULL) { 159 if (extab_sec == NULL) {
142 fprintf(stderr, "no __ex_table in file: %s\n", fname); 160 fprintf(stderr, "no __ex_table in file: %s\n", fname);
143 fail_file(); 161 fail_file();
@@ -176,7 +194,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort)
176 fname); 194 fname);
177 fail_file(); 195 fail_file();
178 } 196 }
179 sort_needed_sec = &shdr[r2(&sort_needed_sym->st_shndx)]; 197 sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
198 sort_needed_sym - symtab,
199 symtab_shndx_start)];
180 sort_done_location = (void *)ehdr + 200 sort_done_location = (void *)ehdr +
181 _r(&sort_needed_sec->sh_offset) + 201 _r(&sort_needed_sec->sh_offset) +
182 _r(&sort_needed_sym->st_value) - 202 _r(&sort_needed_sym->st_value) -