@@ -85,6 +85,25 @@ static uint64_t (*r8)(const uint64_t *);
8585static void (* w )(uint32_t , uint32_t * );
8686typedef void (* table_sort_t )(char * , int );
8787
88+ static struct elf_funcs {
89+ int (* compare_extable )(const void * a , const void * b );
90+ uint64_t (* ehdr_shoff )(Elf_Ehdr * ehdr );
91+ uint16_t (* ehdr_shstrndx )(Elf_Ehdr * ehdr );
92+ uint16_t (* ehdr_shentsize )(Elf_Ehdr * ehdr );
93+ uint16_t (* ehdr_shnum )(Elf_Ehdr * ehdr );
94+ uint64_t (* shdr_addr )(Elf_Shdr * shdr );
95+ uint64_t (* shdr_offset )(Elf_Shdr * shdr );
96+ uint64_t (* shdr_size )(Elf_Shdr * shdr );
97+ uint64_t (* shdr_entsize )(Elf_Shdr * shdr );
98+ uint32_t (* shdr_link )(Elf_Shdr * shdr );
99+ uint32_t (* shdr_name )(Elf_Shdr * shdr );
100+ uint32_t (* shdr_type )(Elf_Shdr * shdr );
101+ uint8_t (* sym_type )(Elf_Sym * sym );
102+ uint32_t (* sym_name )(Elf_Sym * sym );
103+ uint64_t (* sym_value )(Elf_Sym * sym );
104+ uint16_t (* sym_shndx )(Elf_Sym * sym );
105+ } e ;
106+
88107static uint64_t ehdr64_shoff (Elf_Ehdr * ehdr )
89108{
90109 return r8 (& ehdr -> e64 .e_shoff );
@@ -95,6 +114,11 @@ static uint64_t ehdr32_shoff(Elf_Ehdr *ehdr)
95114 return r (& ehdr -> e32 .e_shoff );
96115}
97116
117+ static uint64_t ehdr_shoff (Elf_Ehdr * ehdr )
118+ {
119+ return e .ehdr_shoff (ehdr );
120+ }
121+
98122#define EHDR_HALF (fn_name ) \
99123static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
100124{ \
@@ -104,6 +128,11 @@ static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
104128static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
105129{ \
106130 return r2(&ehdr->e32.e_##fn_name); \
131+ } \
132+ \
133+ static uint16_t ehdr_##fn_name(Elf_Ehdr *ehdr) \
134+ { \
135+ return e.ehdr_##fn_name(ehdr); \
107136}
108137
109138EHDR_HALF (shentsize )
@@ -119,6 +148,11 @@ static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
119148static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
120149{ \
121150 return r(&shdr->e32.sh_##fn_name); \
151+ } \
152+ \
153+ static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
154+ { \
155+ return e.shdr_##fn_name(shdr); \
122156}
123157
124158#define SHDR_ADDR (fn_name ) \
@@ -130,6 +164,11 @@ static uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \
130164static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
131165{ \
132166 return r(&shdr->e32.sh_##fn_name); \
167+ } \
168+ \
169+ static uint64_t shdr_##fn_name(Elf_Shdr *shdr) \
170+ { \
171+ return e.shdr_##fn_name(shdr); \
133172}
134173
135174#define SHDR_WORD (fn_name ) \
@@ -141,6 +180,10 @@ static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
141180static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
142181{ \
143182 return r(&shdr->e32.sh_##fn_name); \
183+ } \
184+ static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
185+ { \
186+ return e.shdr_##fn_name(shdr); \
144187}
145188
146189SHDR_ADDR (addr )
@@ -161,6 +204,11 @@ static uint64_t sym64_##fn_name(Elf_Sym *sym) \
161204static uint64_t sym32_##fn_name(Elf_Sym *sym) \
162205{ \
163206 return r(&sym->e32.st_##fn_name); \
207+ } \
208+ \
209+ static uint64_t sym_##fn_name(Elf_Sym *sym) \
210+ { \
211+ return e.sym_##fn_name(sym); \
164212}
165213
166214#define SYM_WORD (fn_name ) \
@@ -172,6 +220,11 @@ static uint32_t sym64_##fn_name(Elf_Sym *sym) \
172220static uint32_t sym32_##fn_name(Elf_Sym *sym) \
173221{ \
174222 return r(&sym->e32.st_##fn_name); \
223+ } \
224+ \
225+ static uint32_t sym_##fn_name(Elf_Sym *sym) \
226+ { \
227+ return e.sym_##fn_name(sym); \
175228}
176229
177230#define SYM_HALF (fn_name ) \
@@ -183,6 +236,11 @@ static uint16_t sym64_##fn_name(Elf_Sym *sym) \
183236static uint16_t sym32_##fn_name(Elf_Sym *sym) \
184237{ \
185238 return r2(&sym->e32.st_##fn_name); \
239+ } \
240+ \
241+ static uint16_t sym_##fn_name(Elf_Sym *sym) \
242+ { \
243+ return e.sym_##fn_name(sym); \
186244}
187245
188246static uint8_t sym64_type (Elf_Sym * sym )
@@ -195,6 +253,11 @@ static uint8_t sym32_type(Elf_Sym *sym)
195253 return ELF32_ST_TYPE (sym -> e32 .st_info );
196254}
197255
256+ static uint8_t sym_type (Elf_Sym * sym )
257+ {
258+ return e .sym_type (sym );
259+ }
260+
198261SYM_ADDR (value )
199262SYM_WORD (name )
200263SYM_HALF (shndx )
@@ -322,29 +385,16 @@ static int compare_extable_64(const void *a, const void *b)
322385 return av > bv ;
323386}
324387
388+ static int compare_extable (const void * a , const void * b )
389+ {
390+ return e .compare_extable (a , b );
391+ }
392+
325393static inline void * get_index (void * start , int entsize , int index )
326394{
327395 return start + (entsize * index );
328396}
329397
330-
331- static int (* compare_extable )(const void * a , const void * b );
332- static uint64_t (* ehdr_shoff )(Elf_Ehdr * ehdr );
333- static uint16_t (* ehdr_shstrndx )(Elf_Ehdr * ehdr );
334- static uint16_t (* ehdr_shentsize )(Elf_Ehdr * ehdr );
335- static uint16_t (* ehdr_shnum )(Elf_Ehdr * ehdr );
336- static uint64_t (* shdr_addr )(Elf_Shdr * shdr );
337- static uint64_t (* shdr_offset )(Elf_Shdr * shdr );
338- static uint64_t (* shdr_size )(Elf_Shdr * shdr );
339- static uint64_t (* shdr_entsize )(Elf_Shdr * shdr );
340- static uint32_t (* shdr_link )(Elf_Shdr * shdr );
341- static uint32_t (* shdr_name )(Elf_Shdr * shdr );
342- static uint32_t (* shdr_type )(Elf_Shdr * shdr );
343- static uint8_t (* sym_type )(Elf_Sym * sym );
344- static uint32_t (* sym_name )(Elf_Sym * sym );
345- static uint64_t (* sym_value )(Elf_Sym * sym );
346- static uint16_t (* sym_shndx )(Elf_Sym * sym );
347-
348398static int extable_ent_size ;
349399static int long_size ;
350400
@@ -864,34 +914,63 @@ static int do_file(char const *const fname, void *addr)
864914 }
865915
866916 switch (ehdr -> e32 .e_ident [EI_CLASS ]) {
867- case ELFCLASS32 :
917+ case ELFCLASS32 : {
918+ struct elf_funcs efuncs = {
919+ .compare_extable = compare_extable_32 ,
920+ .ehdr_shoff = ehdr32_shoff ,
921+ .ehdr_shentsize = ehdr32_shentsize ,
922+ .ehdr_shstrndx = ehdr32_shstrndx ,
923+ .ehdr_shnum = ehdr32_shnum ,
924+ .shdr_addr = shdr32_addr ,
925+ .shdr_offset = shdr32_offset ,
926+ .shdr_link = shdr32_link ,
927+ .shdr_size = shdr32_size ,
928+ .shdr_name = shdr32_name ,
929+ .shdr_type = shdr32_type ,
930+ .shdr_entsize = shdr32_entsize ,
931+ .sym_type = sym32_type ,
932+ .sym_name = sym32_name ,
933+ .sym_value = sym32_value ,
934+ .sym_shndx = sym32_shndx ,
935+ };
936+
937+ e = efuncs ;
938+ long_size = 4 ;
939+ extable_ent_size = 8 ;
940+
868941 if (r2 (& ehdr -> e32 .e_ehsize ) != sizeof (Elf32_Ehdr ) ||
869942 r2 (& ehdr -> e32 .e_shentsize ) != sizeof (Elf32_Shdr )) {
870943 fprintf (stderr ,
871944 "unrecognized ET_EXEC/ET_DYN file: %s\n" , fname );
872945 return -1 ;
873946 }
874947
875- compare_extable = compare_extable_32 ;
876- ehdr_shoff = ehdr32_shoff ;
877- ehdr_shentsize = ehdr32_shentsize ;
878- ehdr_shstrndx = ehdr32_shstrndx ;
879- ehdr_shnum = ehdr32_shnum ;
880- shdr_addr = shdr32_addr ;
881- shdr_offset = shdr32_offset ;
882- shdr_link = shdr32_link ;
883- shdr_size = shdr32_size ;
884- shdr_name = shdr32_name ;
885- shdr_type = shdr32_type ;
886- shdr_entsize = shdr32_entsize ;
887- sym_type = sym32_type ;
888- sym_name = sym32_name ;
889- sym_value = sym32_value ;
890- sym_shndx = sym32_shndx ;
891- long_size = 4 ;
892- extable_ent_size = 8 ;
948+ }
893949 break ;
894- case ELFCLASS64 :
950+ case ELFCLASS64 : {
951+ struct elf_funcs efuncs = {
952+ .compare_extable = compare_extable_64 ,
953+ .ehdr_shoff = ehdr64_shoff ,
954+ .ehdr_shentsize = ehdr64_shentsize ,
955+ .ehdr_shstrndx = ehdr64_shstrndx ,
956+ .ehdr_shnum = ehdr64_shnum ,
957+ .shdr_addr = shdr64_addr ,
958+ .shdr_offset = shdr64_offset ,
959+ .shdr_link = shdr64_link ,
960+ .shdr_size = shdr64_size ,
961+ .shdr_name = shdr64_name ,
962+ .shdr_type = shdr64_type ,
963+ .shdr_entsize = shdr64_entsize ,
964+ .sym_type = sym64_type ,
965+ .sym_name = sym64_name ,
966+ .sym_value = sym64_value ,
967+ .sym_shndx = sym64_shndx ,
968+ };
969+
970+ e = efuncs ;
971+ long_size = 8 ;
972+ extable_ent_size = 16 ;
973+
895974 if (r2 (& ehdr -> e64 .e_ehsize ) != sizeof (Elf64_Ehdr ) ||
896975 r2 (& ehdr -> e64 .e_shentsize ) != sizeof (Elf64_Shdr )) {
897976 fprintf (stderr ,
@@ -900,25 +979,7 @@ static int do_file(char const *const fname, void *addr)
900979 return -1 ;
901980 }
902981
903- compare_extable = compare_extable_64 ;
904- ehdr_shoff = ehdr64_shoff ;
905- ehdr_shentsize = ehdr64_shentsize ;
906- ehdr_shstrndx = ehdr64_shstrndx ;
907- ehdr_shnum = ehdr64_shnum ;
908- shdr_addr = shdr64_addr ;
909- shdr_offset = shdr64_offset ;
910- shdr_link = shdr64_link ;
911- shdr_size = shdr64_size ;
912- shdr_name = shdr64_name ;
913- shdr_type = shdr64_type ;
914- shdr_entsize = shdr64_entsize ;
915- sym_type = sym64_type ;
916- sym_name = sym64_name ;
917- sym_value = sym64_value ;
918- sym_shndx = sym64_shndx ;
919- long_size = 8 ;
920- extable_ent_size = 16 ;
921-
982+ }
922983 break ;
923984 default :
924985 fprintf (stderr , "unrecognized ELF class %d %s\n" ,
0 commit comments