In order to remove the double #include of sorttable.h for 64 and 32 bit to create duplicate functions, add helper functions for Elf_Shdr. This will create a function pointer for each helper that will get assigned to the appropriate function to handle either the 64bit or 32bit version. This also moves the _r()/r() wrappers for the Elf_Shdr references that handle endian and size differences between the different architectures, into the helper function and out of the open code which is more error prone.
Unified · Split
| @@ -110,6 +110,48 @@ EHDR_HALF(shentsize) · 109 unmodified lines | ||
| 110 | 110 | EHDR_HALF(shstrndx) |
| 111 | 111 | EHDR_HALF(shnum) |
| 112 | 112 | |
| 113 | +#define SHDR_WORD(fn_name) \ | |
| 114 | +static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \ | |
| 115 | +{ \ | |
| 116 | + return r(&shdr->e64.sh_##fn_name); \ | |
| 117 | +} \ | |
| 118 | + \ | |
| 119 | +static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \ | |
| 120 | +{ \ | |
| 121 | + return r(&shdr->e32.sh_##fn_name); \ | |
| 122 | +} | |
| 123 | + | |
| 124 | +#define SHDR_ADDR(fn_name) \ | |
| 125 | +static uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \ | |
| 126 | +{ \ | |
| 127 | + return r8(&shdr->e64.sh_##fn_name); \ | |
| 128 | +} \ | |
| 129 | + \ | |
| 130 | +static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \ | |
| 131 | +{ \ | |
| 132 | + return r(&shdr->e32.sh_##fn_name); \ | |
| 133 | +} | |
| 134 | + | |
| 135 | +#define SHDR_WORD(fn_name) \ | |
| 136 | +static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \ | |
| 137 | +{ \ | |
| 138 | + return r(&shdr->e64.sh_##fn_name); \ | |
| 139 | +} \ | |
| 140 | + \ | |
| 141 | +static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \ | |
| 142 | +{ \ | |
| 143 | + return r(&shdr->e32.sh_##fn_name); \ | |
| 144 | +} | |
| 145 | + | |
| 146 | +SHDR_ADDR(addr) | |
| 147 | +SHDR_ADDR(offset) | |
| 148 | +SHDR_ADDR(size) | |
| 149 | +SHDR_ADDR(entsize) | |
| 150 | + | |
| 151 | +SHDR_WORD(link) | |
| 152 | +SHDR_WORD(name) | |
| 153 | +SHDR_WORD(type) | |
| 154 | + | |
| 113 | 155 | /* |
| 114 | 156 | * Get the whole file as a programming convenience in order to avoid |
| 115 | 157 | * malloc+lseek+read+free of many pieces. If successful, then mmap |
| @@ -31,6 +31,13 @@ · 30 unmodified lines | ||
| 31 | 31 | #undef ehdr_shentsize |
| 32 | 32 | #undef ehdr_shstrndx |
| 33 | 33 | #undef ehdr_shnum |
| 34 | +#undef shdr_addr | |
| 35 | +#undef shdr_offset | |
| 36 | +#undef shdr_link | |
| 37 | +#undef shdr_size | |
| 38 | +#undef shdr_name | |
| 39 | +#undef shdr_type | |
| 40 | +#undef shdr_entsize | |
| 34 | 41 | |
| 35 | 42 | #ifdef SORTTABLE_64 |
| 36 | 43 | # define extable_ent_size 16 |
| @@ -47,6 +54,13 @@ · 10 unmodified lines | ||
| 47 | 54 | # define ehdr_shentsize ehdr64_shentsize |
| 48 | 55 | # define ehdr_shstrndx ehdr64_shstrndx |
| 49 | 56 | # define ehdr_shnum ehdr64_shnum |
| 57 | +# define shdr_addr shdr64_addr | |
| 58 | +# define shdr_offset shdr64_offset | |
| 59 | +# define shdr_link shdr64_link | |
| 60 | +# define shdr_size shdr64_size | |
| 61 | +# define shdr_name shdr64_name | |
| 62 | +# define shdr_type shdr64_type | |
| 63 | +# define shdr_entsize shdr64_entsize | |
| 50 | 64 | #else |
| 51 | 65 | # define extable_ent_size 8 |
| 52 | 66 | # define compare_extable compare_extable_32 |
| @@ -62,6 +76,13 @@ · 9 unmodified lines | ||
| 62 | 76 | # define ehdr_shentsize ehdr32_shentsize |
| 63 | 77 | # define ehdr_shstrndx ehdr32_shstrndx |
| 64 | 78 | # define ehdr_shnum ehdr32_shnum |
| 79 | +# define shdr_addr shdr32_addr | |
| 80 | +# define shdr_offset shdr32_offset | |
| 81 | +# define shdr_link shdr32_link | |
| 82 | +# define shdr_size shdr32_size | |
| 83 | +# define shdr_name shdr32_name | |
| 84 | +# define shdr_type shdr32_type | |
| 85 | +# define shdr_entsize shdr32_entsize | |
| 65 | 86 | #endif |
| 66 | 87 | |
| 67 | 88 | #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) |
| @@ -177,8 +198,8 @@ struct elf_mcount_loc { · 109 unmodified lines | ||
| 177 | 198 | static void *sort_mcount_loc(void *arg) |
| 178 | 199 | { |
| 179 | 200 | struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg; |
| 180 | − uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr) | |
| 181 | − + _r(&(emloc->init_data_sec)->etype.sh_offset); | |
| 201 | + uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec) | |
| 202 | + + shdr_offset(emloc->init_data_sec); | |
| 182 | 203 | uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc; |
| 183 | 204 | unsigned char *start_loc = (void *)emloc->ehdr + offset; |
| 184 | 205 | |
| @@ -267,18 +288,18 @@ static int do_sort(Elf_Ehdr *ehdr, · 82 unmodified lines | ||
| 267 | 288 | |
| 268 | 289 | shstrndx = ehdr_shstrndx(ehdr); |
| 269 | 290 | if (shstrndx == SHN_XINDEX) |
| 270 | − shstrndx = r(&shdr_start->etype.sh_link); | |
| 291 | + shstrndx = shdr_link(shdr_start); | |
| 271 | 292 | string_sec = get_index(shdr_start, shentsize, shstrndx); |
| 272 | − secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset); | |
| 293 | + secstrings = (const char *)ehdr + shdr_offset(string_sec); | |
| 273 | 294 | |
| 274 | 295 | shnum = ehdr_shnum(ehdr); |
| 275 | 296 | if (shnum == SHN_UNDEF) |
| 276 | − shnum = _r(&shdr_start->etype.sh_size); | |
| 297 | + shnum = shdr_size(shdr_start); | |
| 277 | 298 | |
| 278 | 299 | for (i = 0; i < shnum; i++) { |
| 279 | 300 | Elf_Shdr *shdr = get_index(shdr_start, shentsize, i); |
| 280 | 301 | |
| 281 | − idx = r(&shdr->etype.sh_name); | |
| 302 | + idx = shdr_name(shdr); | |
| 282 | 303 | if (!strcmp(secstrings + idx, "__ex_table")) |
| 283 | 304 | extab_sec = shdr; |
| 284 | 305 | if (!strcmp(secstrings + idx, ".symtab")) |
| @@ -286,9 +307,9 @@ static int do_sort(Elf_Ehdr *ehdr, · 1 unmodified line | ||
| 286 | 307 | if (!strcmp(secstrings + idx, ".strtab")) |
| 287 | 308 | strtab_sec = shdr; |
| 288 | 309 | |
| 289 | − if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX) | |
| 310 | + if (shdr_type(shdr) == SHT_SYMTAB_SHNDX) | |
| 290 | 311 | symtab_shndx = (Elf32_Word *)((const char *)ehdr + |
| 291 | − _r(&shdr->etype.sh_offset)); | |
| 312 | + shdr_offset(shdr)); | |
| 292 | 313 | |
| 293 | 314 | #ifdef MCOUNT_SORT_ENABLED |
| 294 | 315 | /* locate the .init.data section in vmlinux */ |
| @@ -304,14 +325,14 @@ static int do_sort(Elf_Ehdr *ehdr, · 9 unmodified lines | ||
| 304 | 325 | #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) |
| 305 | 326 | /* locate the ORC unwind tables */ |
| 306 | 327 | if (!strcmp(secstrings + idx, ".orc_unwind_ip")) { |
| 307 | − orc_ip_size = _r(&shdr->etype.sh_size); | |
| 328 | + orc_ip_size = shdr_size(shdr); | |
| 308 | 329 | g_orc_ip_table = (int *)((void *)ehdr + |
| 309 | − _r(&shdr->etype.sh_offset)); | |
| 330 | + shdr_offset(shdr)); | |
| 310 | 331 | } |
| 311 | 332 | if (!strcmp(secstrings + idx, ".orc_unwind")) { |
| 312 | − orc_size = _r(&shdr->etype.sh_size); | |
| 333 | + orc_size = shdr_size(shdr); | |
| 313 | 334 | g_orc_table = (struct orc_entry *)((void *)ehdr + |
| 314 | − _r(&shdr->etype.sh_offset)); | |
| 335 | + shdr_offset(shdr)); | |
| 315 | 336 | } |
| 316 | 337 | #endif |
| 317 | 338 | } /* for loop */ |
| @@ -374,23 +395,22 @@ static int do_sort(Elf_Ehdr *ehdr, · 56 unmodified lines | ||
| 374 | 395 | goto out; |
| 375 | 396 | } |
| 376 | 397 | |
| 377 | − extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset); | |
| 378 | − strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset); | |
| 379 | − symtab = (const Elf_Sym *)((const char *)ehdr + | |
| 380 | − _r(&symtab_sec->etype.sh_offset)); | |
| 398 | + extab_image = (void *)ehdr + shdr_offset(extab_sec); | |
| 399 | + strtab = (const char *)ehdr + shdr_offset(strtab_sec); | |
| 400 | + symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec)); | |
| 381 | 401 | |
| 382 | 402 | if (custom_sort) { |
| 383 | − custom_sort(extab_image, _r(&extab_sec->etype.sh_size)); | |
| 403 | + custom_sort(extab_image, shdr_size(extab_sec)); | |
| 384 | 404 | } else { |
| 385 | − int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size; | |
| 405 | + int num_entries = shdr_size(extab_sec) / extable_ent_size; | |
| 386 | 406 | qsort(extab_image, num_entries, |
| 387 | 407 | extable_ent_size, compare_extable); |
| 388 | 408 | } |
| 389 | 409 | |
| 390 | 410 | /* find the flag main_extable_sort_needed */ |
| 391 | − sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset); | |
| 392 | − sym_end = sym_start + _r(&symtab_sec->etype.sh_size); | |
| 393 | − symentsize = _r(&symtab_sec->etype.sh_entsize); | |
| 411 | + sym_start = (void *)ehdr + shdr_offset(symtab_sec); | |
| 412 | + sym_end = sym_start + shdr_size(symtab_sec); | |
| 413 | + symentsize = shdr_entsize(symtab_sec); | |
| 394 | 414 | |
| 395 | 415 | for (sym = sym_start; (void *)sym + symentsize < sym_end; |
| 396 | 416 | sym = (void *)sym + symentsize) { |
| @@ -415,9 +435,9 @@ static int do_sort(Elf_Ehdr *ehdr, · 18 unmodified lines | ||
| 415 | 435 | symtab_shndx); |
| 416 | 436 | sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index); |
| 417 | 437 | sort_needed_loc = (void *)ehdr + |
| 418 | − _r(&sort_needed_sec->etype.sh_offset) + | |
| 438 | + shdr_offset(sort_needed_sec) + | |
| 419 | 439 | _r(&sort_needed_sym->etype.st_value) - |
| 420 | − _r(&sort_needed_sec->etype.sh_addr); | |
| 440 | + shdr_addr(sort_needed_sec); | |
| 421 | 441 | |
| 422 | 442 | /* extable has been sorted, clear the flag */ |
| 423 | 443 | w(0, sort_needed_loc); |