1414
1515#undef extable_ent_size
1616#undef compare_extable
17- #undef do_func
17+ #undef do_sort
1818#undef Elf_Addr
1919#undef Elf_Ehdr
2020#undef Elf_Shdr
3636#ifdef SORTEXTABLE_64
3737# define extable_ent_size 16
3838# define compare_extable compare_extable_64
39- # define do_func do64
39+ # define do_sort do_sort_64
4040# define Elf_Addr Elf64_Addr
4141# define Elf_Ehdr Elf64_Ehdr
4242# define Elf_Shdr Elf64_Shdr
5757#else
5858# define extable_ent_size 8
5959# define compare_extable compare_extable_32
60- # define do_func do32
60+ # define do_sort do_sort_32
6161# define Elf_Addr Elf32_Addr
6262# define Elf_Ehdr Elf32_Ehdr
6363# define Elf_Shdr Elf32_Shdr
@@ -89,81 +89,81 @@ static int compare_extable(const void *a, const void *b)
8989 return 0 ;
9090}
9191
92- static int do_func (Elf_Ehdr * ehdr ,
92+ static int do_sort (Elf_Ehdr * ehdr ,
9393 char const * const fname ,
9494 table_sort_t custom_sort )
9595{
96- Elf_Shdr * shdr ;
97- Elf_Shdr * shstrtab_sec ;
96+ Elf_Shdr * s , * shdr = (Elf_Shdr * )((char * )ehdr + _r (& ehdr -> e_shoff ));
9897 Elf_Shdr * strtab_sec = NULL ;
9998 Elf_Shdr * symtab_sec = NULL ;
10099 Elf_Shdr * extab_sec = NULL ;
101100 Elf_Sym * sym ;
102101 const Elf_Sym * symtab ;
103- Elf32_Word * symtab_shndx_start = NULL ;
104- Elf_Sym * sort_needed_sym ;
102+ Elf32_Word * symtab_shndx = NULL ;
103+ Elf_Sym * sort_needed_sym = NULL ;
105104 Elf_Shdr * sort_needed_sec ;
106105 Elf_Rel * relocs = NULL ;
107106 int relocs_size = 0 ;
108- uint32_t * sort_done_location ;
109- const char * secstrtab ;
107+ uint32_t * sort_needed_loc ;
108+ const char * secstrings ;
110109 const char * strtab ;
111110 char * extab_image ;
112111 int extab_index = 0 ;
113112 int i ;
114113 int idx ;
115- unsigned int num_sections ;
116- unsigned int secindex_strings ;
114+ unsigned int shnum ;
115+ unsigned int shstrndx ;
117116
118- shdr = (Elf_Shdr * )((char * )ehdr + _r (& ehdr -> e_shoff ));
117+ shstrndx = r2 (& ehdr -> e_shstrndx );
118+ if (shstrndx == SHN_XINDEX )
119+ shstrndx = r (& shdr [0 ].sh_link );
120+ secstrings = (const char * )ehdr + _r (& shdr [shstrndx ].sh_offset );
119121
120- num_sections = r2 (& ehdr -> e_shnum );
121- if (num_sections == SHN_UNDEF )
122- num_sections = _r (& shdr [0 ].sh_size );
122+ shnum = r2 (& ehdr -> e_shnum );
123+ if (shnum == SHN_UNDEF )
124+ shnum = _r (& shdr [0 ].sh_size );
123125
124- secindex_strings = r2 (& ehdr -> e_shstrndx );
125- if (secindex_strings == SHN_XINDEX )
126- secindex_strings = r (& shdr [0 ].sh_link );
127-
128- shstrtab_sec = shdr + secindex_strings ;
129- secstrtab = (const char * )ehdr + _r (& shstrtab_sec -> sh_offset );
130- for (i = 0 ; i < num_sections ; i ++ ) {
131- idx = r (& shdr [i ].sh_name );
132- if (!strcmp (secstrtab + idx , "__ex_table" )) {
133- extab_sec = shdr + i ;
126+ for (i = 0 , s = shdr ; s < shdr + shnum ; i ++ , s ++ ) {
127+ idx = r (& s -> sh_name );
128+ if (!strcmp (secstrings + idx , "__ex_table" )) {
129+ extab_sec = s ;
134130 extab_index = i ;
135131 }
136- if ((r (& shdr [i ].sh_type ) == SHT_REL ||
137- r (& shdr [i ].sh_type ) == SHT_RELA ) &&
138- r (& shdr [i ].sh_info ) == extab_index ) {
139- relocs = (void * )ehdr + _r (& shdr [i ].sh_offset );
140- relocs_size = _r (& shdr [i ].sh_size );
132+ if (!strcmp (secstrings + idx , ".symtab" ))
133+ symtab_sec = s ;
134+ if (!strcmp (secstrings + idx , ".strtab" ))
135+ strtab_sec = s ;
136+
137+ if ((r (& s -> sh_type ) == SHT_REL ||
138+ r (& s -> sh_type ) == SHT_RELA ) &&
139+ r (& s -> sh_info ) == extab_index ) {
140+ relocs = (void * )ehdr + _r (& s -> sh_offset );
141+ relocs_size = _r (& s -> sh_size );
141142 }
142- if (!strcmp (secstrtab + idx , ".symtab" ))
143- symtab_sec = shdr + i ;
144- if (!strcmp (secstrtab + idx , ".strtab" ))
145- strtab_sec = shdr + i ;
146- if (r (& shdr [i ].sh_type ) == SHT_SYMTAB_SHNDX )
147- symtab_shndx_start = (Elf32_Word * )(
148- (const char * )ehdr + _r (& shdr [i ].sh_offset ));
143+ if (r (& s -> sh_type ) == SHT_SYMTAB_SHNDX )
144+ symtab_shndx = (Elf32_Word * )((const char * )ehdr +
145+ _r (& s -> sh_offset ));
149146 }
150- if (!strtab_sec ) {
151- fprintf (stderr , "no .strtab in file: %s\n" , fname );
147+
148+ if (!extab_sec ) {
149+ fprintf (stderr , "no __ex_table in file: %s\n" , fname );
152150 return -1 ;
153151 }
152+
154153 if (!symtab_sec ) {
155154 fprintf (stderr , "no .symtab in file: %s\n" , fname );
156155 return -1 ;
157156 }
158- symtab = (const Elf_Sym * )((const char * )ehdr +
159- _r (& symtab_sec -> sh_offset ));
160- if (!extab_sec ) {
161- fprintf (stderr , "no __ex_table in file: %s\n" , fname );
157+
158+ if (!strtab_sec ) {
159+ fprintf (stderr , "no .strtab in file: %s\n" , fname );
162160 return -1 ;
163161 }
164- strtab = (const char * )ehdr + _r (& strtab_sec -> sh_offset );
165162
166163 extab_image = (void * )ehdr + _r (& extab_sec -> sh_offset );
164+ strtab = (const char * )ehdr + _r (& strtab_sec -> sh_offset );
165+ symtab = (const Elf_Sym * )((const char * )ehdr +
166+ _r (& symtab_sec -> sh_offset ));
167167
168168 if (custom_sort ) {
169169 custom_sort (extab_image , _r (& extab_sec -> sh_size ));
@@ -172,38 +172,41 @@ static int do_func(Elf_Ehdr *ehdr,
172172 qsort (extab_image , num_entries ,
173173 extable_ent_size , compare_extable );
174174 }
175+
175176 /* If there were relocations, we no longer need them. */
176177 if (relocs )
177178 memset (relocs , 0 , relocs_size );
178179
179- /* find main_extable_sort_needed */
180- sort_needed_sym = NULL ;
181- for (i = 0 ; i < _r (& symtab_sec -> sh_size ) / sizeof (Elf_Sym ); i ++ ) {
182- sym = (void * )ehdr + _r (& symtab_sec -> sh_offset );
183- sym += i ;
180+ /* find the flag main_extable_sort_needed */
181+ for (sym = (void * )ehdr + _r (& symtab_sec -> sh_offset );
182+ sym < sym + _r (& symtab_sec -> sh_size ) / sizeof (Elf_Sym );
183+ sym ++ ) {
184184 if (ELF_ST_TYPE (sym -> st_info ) != STT_OBJECT )
185185 continue ;
186- idx = r (& sym -> st_name );
187- if (! strcmp ( strtab + idx , "main_extable_sort_needed" )) {
186+ if (! strcmp ( strtab + r (& sym -> st_name ),
187+ "main_extable_sort_needed" )) {
188188 sort_needed_sym = sym ;
189189 break ;
190190 }
191191 }
192+
192193 if (!sort_needed_sym ) {
193194 fprintf (stderr ,
194195 "no main_extable_sort_needed symbol in file: %s\n" ,
195196 fname );
196197 return -1 ;
197198 }
199+
198200 sort_needed_sec = & shdr [get_secindex (r2 (& sym -> st_shndx ),
199201 sort_needed_sym - symtab ,
200- symtab_shndx_start )];
201- sort_done_location = (void * )ehdr +
202+ symtab_shndx )];
203+ sort_needed_loc = (void * )ehdr +
202204 _r (& sort_needed_sec -> sh_offset ) +
203205 _r (& sort_needed_sym -> st_value ) -
204206 _r (& sort_needed_sec -> sh_addr );
205207
206- /* We sorted it, clear the flag. */
207- w (0 , sort_done_location );
208+ /* extable has been sorted, clear the flag */
209+ w (0 , sort_needed_loc );
210+
208211 return 0 ;
209212}
0 commit comments