Messages in this thread Patch in this message | | | Date | Sat, 14 Nov 2020 13:53:10 +0100 | From | Vasily Gorbik <> | Subject | [PATCH] scripts/sorttable: Fix ORC unwind table sorting on big endian |
| |
Currently when x86_64 kernel is cross compiled on big endian hardware ORC unwind table is not sorted correctly. Due to missing byte swaps and treating size as 4-byte value ORC sections sizes end up as 0 and the problem is silently ignored.
Make ORC unwind table sorting endianness aware.
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> --- This goes on top of the patch series: http://lkml.kernel.org/r/cover.thread-1e2854.your-ad-here.call-01605220128-ext-6070@work.hours
scripts/sorttable.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/scripts/sorttable.h b/scripts/sorttable.h index a2baa2fefb13..99f3fa1767d1 100644 --- a/scripts/sorttable.h +++ b/scripts/sorttable.h @@ -59,6 +59,8 @@ # define uint_t uint64_t # define _r r8 # define _w w8 +# define _r4 r +# define _w4 w #else # define extable_ent_size 8 # define compare_extable compare_extable_32 @@ -80,6 +82,8 @@ # define uint_t uint32_t # define _r r # define _w w +# define _r4 r +# define _w4 w #endif #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) @@ -98,7 +102,7 @@ pthread_t orc_sort_thread; static inline unsigned long orc_ip(const int *ip) { - return (unsigned long)ip + *ip; + return (unsigned long)ip + (int)_r4((uint32_t *)ip); } static int orc_sort_cmp(const void *_a, const void *_b) @@ -158,7 +162,7 @@ static void *sort_orctable(void *arg) /* initialize indices array, convert ip_table to absolute address */ for (i = 0; i < num_entries; i++) { idxs[i] = i; - tmp_orc_ip_table[i] = g_orc_ip_table[i] + i * sizeof(int); + tmp_orc_ip_table[i] = (int)_r4((uint32_t *)&g_orc_ip_table[i]) + i * sizeof(int); } memcpy(tmp_orc_table, g_orc_table, orc_size); @@ -169,7 +173,7 @@ static void *sort_orctable(void *arg) continue; /* convert back to relative address */ - g_orc_ip_table[i] = tmp_orc_ip_table[idxs[i]] - i * sizeof(int); + _w4(tmp_orc_ip_table[idxs[i]] - i * sizeof(int), (uint32_t *)&g_orc_ip_table[i]); g_orc_table[i] = tmp_orc_table[idxs[i]]; } @@ -256,14 +260,12 @@ static int do_sort(Elf_Ehdr *ehdr, #if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED) /* locate the ORC unwind tables */ if (!strcmp(secstrings + idx, ".orc_unwind_ip")) { - orc_ip_size = s->sh_size; - g_orc_ip_table = (int *)((void *)ehdr + - s->sh_offset); + orc_ip_size = _r(&s->sh_size); + g_orc_ip_table = (int *)((void *)ehdr + _r(&s->sh_offset)); } if (!strcmp(secstrings + idx, ".orc_unwind")) { - orc_size = s->sh_size; - g_orc_table = (struct orc_entry *)((void *)ehdr + - s->sh_offset); + orc_size = _r(&s->sh_size); + g_orc_table = (struct orc_entry *)((void *)ehdr + _r(&s->sh_offset)); } #endif } /* for loop */ -- 2.25.4
| |