From 8bcea4710bd328ef74dc852d9fdffb3c47ed8abe Mon Sep 17 00:00:00 2001 From: Matias Larsson Date: Thu, 24 Nov 2022 18:22:55 +0100 Subject: Fix libpinyin crash on ARMv7 Fix the alignment trap in get_unigram_frequency(). Fix also other places where this same trap could happen (depending on compiler and surrounding code). The trap happened when the ARM GCC generated a SIMD instruction (specifically VLDR) to load 32 bits in a single instruction, and when the memory address was not aligned to 32 bits. VLDR traps if the address is not aligned. GCC generated the instruction because of the cast to uint32 from the address. The fix is to allocate a uint32 variable in stack and use memcpy to copy the data to that variable. This way we ensure that appropriate instructions are generated. **Links** About the issue with GCC: https://trust-in-soft.com/blog/2020/04/06/gcc-always-assumes-aligned-pointer-accesses/ How Linux does it: https://elixir.bootlin.com/linux/v5.10.155/source/include/linux/unaligned/memmove.h#L13 ARM documentation: https://documentation-service.arm.com/static/5f8dc043f86e16515cdbbc92?token= See 'A3.2.1 Unaligned data access' --- src/storage/chewing_large_table.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/storage/chewing_large_table.cpp') diff --git a/src/storage/chewing_large_table.cpp b/src/storage/chewing_large_table.cpp index e856caf..bd76e9b 100644 --- a/src/storage/chewing_large_table.cpp +++ b/src/storage/chewing_large_table.cpp @@ -804,7 +804,7 @@ bool ChewingBitmapIndexLevel::store(MemoryChunk * new_chunk, bool ChewingLengthIndexLevel::load(MemoryChunk * chunk, table_offset_t offset, table_offset_t end) { char * begin = (char *) chunk->begin(); - guint32 nindex = *((guint32 *)(begin + offset)); /* number of index */ + guint32 nindex = chunk->get_content(offset); /* number of index */ table_offset_t * index = (table_offset_t *) (begin + offset + sizeof(guint32)); -- cgit