diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2013-12-19 15:08:03 +0100 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2013-12-19 15:08:32 +0100 |
| commit | e23c34bb41da65f354fb7eee04300c56ee48f60c (patch) | |
| tree | 549fbe449d55273b81ef104a9755109bf4ae7817 /scripts/sortextable.h | |
| parent | b481c2cb3534c85dca625973b33eba15f9af3e4c (diff) | |
| parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) | |
Merge branch 'master' into for-next
Sync with Linus' tree to be able to apply fixes on top of newer things
in tree (efi-stub).
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'scripts/sortextable.h')
| -rw-r--r-- | scripts/sortextable.h | 26 |
1 files changed, 23 insertions, 3 deletions
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) Elf_Shdr *symtab_sec = NULL; Elf_Shdr *extab_sec = NULL; Elf_Sym *sym; + const Elf_Sym *symtab; + Elf32_Word *symtab_shndx_start = NULL; Elf_Sym *sort_needed_sym; Elf_Shdr *sort_needed_sec; Elf_Rel *relocs = NULL; @@ -109,11 +111,22 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) int extab_index = 0; int i; int idx; + unsigned int num_sections; + unsigned int secindex_strings; shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); - shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); + + num_sections = r2(&ehdr->e_shnum); + if (num_sections == SHN_UNDEF) + num_sections = _r(&shdr[0].sh_size); + + secindex_strings = r2(&ehdr->e_shstrndx); + if (secindex_strings == SHN_XINDEX) + secindex_strings = r(&shdr[0].sh_link); + + shstrtab_sec = shdr + secindex_strings; secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset); - for (i = 0; i < r2(&ehdr->e_shnum); i++) { + for (i = 0; i < num_sections; i++) { idx = r(&shdr[i].sh_name); if (strcmp(secstrtab + idx, "__ex_table") == 0) { extab_sec = shdr + i; @@ -129,6 +142,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) symtab_sec = shdr + i; if (strcmp(secstrtab + idx, ".strtab") == 0) strtab_sec = shdr + i; + if (r(&shdr[i].sh_type) == SHT_SYMTAB_SHNDX) + symtab_shndx_start = (Elf32_Word *)( + (const char *)ehdr + _r(&shdr[i].sh_offset)); } if (strtab_sec == NULL) { 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) fprintf(stderr, "no .symtab in file: %s\n", fname); fail_file(); } + symtab = (const Elf_Sym *)((const char *)ehdr + + _r(&symtab_sec->sh_offset)); if (extab_sec == NULL) { fprintf(stderr, "no __ex_table in file: %s\n", fname); fail_file(); @@ -176,7 +194,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) fname); fail_file(); } - sort_needed_sec = &shdr[r2(&sort_needed_sym->st_shndx)]; + sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx), + sort_needed_sym - symtab, + symtab_shndx_start)]; sort_done_location = (void *)ehdr + _r(&sort_needed_sec->sh_offset) + _r(&sort_needed_sym->st_value) - |
