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 | EHDR_HALF(shstrndx) | 110 | EHDR_HALF(shstrndx) |
| 111 | EHDR_HALF(shnum) | 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 | * Get the whole file as a programming convenience in order to avoid | 156 | * Get the whole file as a programming convenience in order to avoid |
| 115 | * malloc+lseek+read+free of many pieces. If successful, then mmap | 157 | * malloc+lseek+read+free of many pieces. If successful, then mmap |
| @@ -31,6 +31,13 @@ · 30 unmodified lines | |||
| 31 | #undef ehdr_shentsize | 31 | #undef ehdr_shentsize |
| 32 | #undef ehdr_shstrndx | 32 | #undef ehdr_shstrndx |
| 33 | #undef ehdr_shnum | 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 | #ifdef SORTTABLE_64 | 42 | #ifdef SORTTABLE_64 |
| 36 | # define extable_ent_size 16 | 43 | # define extable_ent_size 16 |
| @@ -47,6 +54,13 @@ · 10 unmodified lines | |||
| 47 | # define ehdr_shentsize ehdr64_shentsize | 54 | # define ehdr_shentsize ehdr64_shentsize |
| 48 | # define ehdr_shstrndx ehdr64_shstrndx | 55 | # define ehdr_shstrndx ehdr64_shstrndx |
| 49 | # define ehdr_shnum ehdr64_shnum | 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 | #else | 64 | #else |
| 51 | # define extable_ent_size 8 | 65 | # define extable_ent_size 8 |
| 52 | # define compare_extable compare_extable_32 | 66 | # define compare_extable compare_extable_32 |
| @@ -62,6 +76,13 @@ · 9 unmodified lines | |||
| 62 | # define ehdr_shentsize ehdr32_shentsize | 76 | # define ehdr_shentsize ehdr32_shentsize |
| 63 | # define ehdr_shstrndx ehdr32_shstrndx | 77 | # define ehdr_shstrndx ehdr32_shstrndx |
| 64 | # define ehdr_shnum ehdr32_shnum | 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 | #endif | 86 | #endif |
| 66 | 87 | ||
| 67 | #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) | 88 | #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) |
| @@ -177,8 +198,8 @@ struct elf_mcount_loc { · 109 unmodified lines | |||
| 177 | static void *sort_mcount_loc(void *arg) | 198 | static void *sort_mcount_loc(void *arg) |
| 178 | { | 199 | { |
| 179 | struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg; | 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) | 201 | uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec) |
| 181 | + _r(&(emloc->init_data_sec)->etype.sh_offset); | 202 | + shdr_offset(emloc->init_data_sec); |
| 182 | uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc; | 203 | uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc; |
| 183 | unsigned char *start_loc = (void *)emloc->ehdr + offset; | 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 | shstrndx = ehdr_shstrndx(ehdr); | 289 | shstrndx = ehdr_shstrndx(ehdr); |
| 269 | if (shstrndx == SHN_XINDEX) | 290 | if (shstrndx == SHN_XINDEX) |
| 270 | shstrndx = r(&shdr_start->etype.sh_link); | 291 | shstrndx = shdr_link(shdr_start); |
| 271 | string_sec = get_index(shdr_start, shentsize, shstrndx); | 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 | shnum = ehdr_shnum(ehdr); | 295 | shnum = ehdr_shnum(ehdr); |
| 275 | if (shnum == SHN_UNDEF) | 296 | if (shnum == SHN_UNDEF) |
| 276 | shnum = _r(&shdr_start->etype.sh_size); | 297 | shnum = shdr_size(shdr_start); |
| 277 | 298 | ||
| 278 | for (i = 0; i < shnum; i++) { | 299 | for (i = 0; i < shnum; i++) { |
| 279 | Elf_Shdr *shdr = get_index(shdr_start, shentsize, i); | 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 | if (!strcmp(secstrings + idx, "__ex_table")) | 303 | if (!strcmp(secstrings + idx, "__ex_table")) |
| 283 | extab_sec = shdr; | 304 | extab_sec = shdr; |
| 284 | if (!strcmp(secstrings + idx, ".symtab")) | 305 | if (!strcmp(secstrings + idx, ".symtab")) |
| @@ -286,9 +307,9 @@ static int do_sort(Elf_Ehdr *ehdr, · 1 unmodified line | |||
| 286 | if (!strcmp(secstrings + idx, ".strtab")) | 307 | if (!strcmp(secstrings + idx, ".strtab")) |
| 287 | strtab_sec = shdr; | 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 | symtab_shndx = (Elf32_Word *)((const char *)ehdr + | 311 | symtab_shndx = (Elf32_Word *)((const char *)ehdr + |
| 291 | _r(&shdr->etype.sh_offset)); | 312 | shdr_offset(shdr)); |
| 292 | 313 | ||
| 293 | #ifdef MCOUNT_SORT_ENABLED | 314 | #ifdef MCOUNT_SORT_ENABLED |
| 294 | /* locate the .init.data section in vmlinux */ | 315 | /* locate the .init.data section in vmlinux */ |
| @@ -304,14 +325,14 @@ static int do_sort(Elf_Ehdr *ehdr, · 9 unmodified lines | |||
| 304 | #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) | 325 | #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) |
| 305 | /* locate the ORC unwind tables */ | 326 | /* locate the ORC unwind tables */ |
| 306 | if (!strcmp(secstrings + idx, ".orc_unwind_ip")) { | 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 | g_orc_ip_table = (int *)((void *)ehdr + | 329 | g_orc_ip_table = (int *)((void *)ehdr + |
| 309 | _r(&shdr->etype.sh_offset)); | 330 | shdr_offset(shdr)); |
| 310 | } | 331 | } |
| 311 | if (!strcmp(secstrings + idx, ".orc_unwind")) { | 332 | if (!strcmp(secstrings + idx, ".orc_unwind")) { |
| 312 | orc_size = _r(&shdr->etype.sh_size); | 333 | orc_size = shdr_size(shdr); |
| 313 | g_orc_table = (struct orc_entry *)((void *)ehdr + | 334 | g_orc_table = (struct orc_entry *)((void *)ehdr + |
| 314 | _r(&shdr->etype.sh_offset)); | 335 | shdr_offset(shdr)); |
| 315 | } | 336 | } |
| 316 | #endif | 337 | #endif |
| 317 | } /* for loop */ | 338 | } /* for loop */ |
| @@ -374,23 +395,22 @@ static int do_sort(Elf_Ehdr *ehdr, · 56 unmodified lines | |||
| 374 | goto out; | 395 | goto out; |
| 375 | } | 396 | } |
| 376 | 397 | ||
| 377 | extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset); | 398 | extab_image = (void *)ehdr + shdr_offset(extab_sec); |
| 378 | strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset); | 399 | strtab = (const char *)ehdr + shdr_offset(strtab_sec); |
| 379 | symtab = (const Elf_Sym *)((const char *)ehdr + | 400 | symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec)); |
| 380 | _r(&symtab_sec->etype.sh_offset)); | ||
| 381 | 401 | ||
| 382 | if (custom_sort) { | 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 | } else { | 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 | qsort(extab_image, num_entries, | 406 | qsort(extab_image, num_entries, |
| 387 | extable_ent_size, compare_extable); | 407 | extable_ent_size, compare_extable); |
| 388 | } | 408 | } |
| 389 | 409 | ||
| 390 | /* find the flag main_extable_sort_needed */ | 410 | /* find the flag main_extable_sort_needed */ |
| 391 | sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset); | 411 | sym_start = (void *)ehdr + shdr_offset(symtab_sec); |
| 392 | sym_end = sym_start + _r(&symtab_sec->etype.sh_size); | 412 | sym_end = sym_start + shdr_size(symtab_sec); |
| 393 | symentsize = _r(&symtab_sec->etype.sh_entsize); | 413 | symentsize = shdr_entsize(symtab_sec); |
| 394 | 414 | ||
| 395 | for (sym = sym_start; (void *)sym + symentsize < sym_end; | 415 | for (sym = sym_start; (void *)sym + symentsize < sym_end; |
| 396 | sym = (void *)sym + symentsize) { | 416 | sym = (void *)sym + symentsize) { |
| @@ -415,9 +435,9 @@ static int do_sort(Elf_Ehdr *ehdr, · 18 unmodified lines | |||
| 415 | symtab_shndx); | 435 | symtab_shndx); |
| 416 | sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index); | 436 | sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index); |
| 417 | sort_needed_loc = (void *)ehdr + | 437 | sort_needed_loc = (void *)ehdr + |
| 418 | _r(&sort_needed_sec->etype.sh_offset) + | 438 | shdr_offset(sort_needed_sec) + |
| 419 | _r(&sort_needed_sym->etype.st_value) - | 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 | /* extable has been sorted, clear the flag */ | 442 | /* extable has been sorted, clear the flag */ |
| 423 | w(0, sort_needed_loc); | 443 | w(0, sort_needed_loc); |