From: Jan Palus Date: Thu, 17 Nov 2022 18:49:35 +0000 (+0100) Subject: up to 0.8.1 X-Git-Tag: auto/th/neovim-0.8.1-1 X-Git-Url: http://git.pld-linux.org/gitweb.cgi?a=commitdiff_plain;h=04338cf936046e8b901019d219e786c14fb1ccba;p=packages%2Fneovim.git up to 0.8.1 - fix memory alignment crash on armv7 (https://github.com/neovim/neovim/pull/20489) --- diff --git a/armv7-memalign.patch b/armv7-memalign.patch new file mode 100644 index 0000000..f5935b0 --- /dev/null +++ b/armv7-memalign.patch @@ -0,0 +1,179 @@ +From 0240fd6d0f7e27c459b243578ad51100ff6e2b66 Mon Sep 17 00:00:00 2001 +From: Jan Palus +Date: Wed, 5 Oct 2022 00:18:09 +0200 +Subject: [PATCH 1/2] fix(memory): fix memory alignment for dynamic allocation + +all pointers returned by arena_alloc residing in arena block should be +properly aligned + +to meet neovim's alignment requirements but keeping it simple settle on +ARENA_ALIGN = MAX(sizeof(void *), sizeof(double)). +--- + src/nvim/memory.c | 32 +++++++++++++++++++------------- + src/nvim/memory.h | 2 +- + 2 files changed, 20 insertions(+), 14 deletions(-) + +diff --git a/src/nvim/memory.c b/src/nvim/memory.c +index 61c43d8f995a..93aa9bd6e55e 100644 +--- a/src/nvim/memory.c ++++ b/src/nvim/memory.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + #include "nvim/api/extmark.h" +@@ -576,6 +577,12 @@ void alloc_block(Arena *arena) + blk->prev = prev_blk; + } + ++static size_t arena_align_offset(void *ptr, size_t alignment) ++{ ++ uintptr_t uptr = (uintptr_t)ptr; ++ return ((uptr + (alignment - 1)) & ~(alignment - 1)) - uptr; ++} ++ + /// @param arena if NULL, do a global allocation. caller must then free the value! + /// @param size if zero, will still return a non-null pointer, but not a unique one + void *arena_alloc(Arena *arena, size_t size, bool align) +@@ -583,34 +590,33 @@ void *arena_alloc(Arena *arena, size_t size, bool align) + if (!arena) { + return xmalloc(size); + } +- if (align) { +- arena->pos = (arena->pos + (ARENA_ALIGN - 1)) & ~(ARENA_ALIGN - 1); ++ if (!arena->cur_blk) { ++ alloc_block(arena); + } +- if (arena->pos + size > arena->size || !arena->cur_blk) { +- if (size > (ARENA_BLOCK_SIZE - sizeof(struct consumed_blk)) >> 1) { ++ size_t align_pos = align ? arena_align_offset(arena->cur_blk + arena->pos, ARENA_ALIGN) : 0; ++ if (arena->pos + align_pos + size > arena->size) { ++ if (size + (align ? (ARENA_ALIGN - 1) : 0) > (ARENA_BLOCK_SIZE - sizeof(struct consumed_blk)) ++ >> 1) { + // if allocation is too big, allocate a large block with the requested + // size, but still with block pointer head. We do this even for + // arena->size / 2, as there likely is space left for the next + // small allocation in the current block. +- if (!arena->cur_blk) { +- // to simplify free-list management, arena->cur_blk must +- // always be a normal, ARENA_BLOCK_SIZE sized, block +- alloc_block(arena); +- } + arena_alloc_count++; +- char *alloc = xmalloc(size + sizeof(struct consumed_blk)); ++ char *alloc = xmalloc(size + sizeof(struct consumed_blk) + (align ? (ARENA_ALIGN - 1) : 0)); + struct consumed_blk *cur_blk = (struct consumed_blk *)arena->cur_blk; + struct consumed_blk *fix_blk = (struct consumed_blk *)alloc; + fix_blk->prev = cur_blk->prev; + cur_blk->prev = fix_blk; +- return (alloc + sizeof(struct consumed_blk)); ++ char *mem = (alloc + sizeof(struct consumed_blk)); ++ return mem + (align ? arena_align_offset(mem, ARENA_ALIGN) : 0); + } else { + alloc_block(arena); ++ align_pos = align ? arena_align_offset(arena->cur_blk + arena->pos, ARENA_ALIGN) : 0; + } + } + +- char *mem = arena->cur_blk + arena->pos; +- arena->pos += size; ++ char *mem = arena->cur_blk + arena->pos + align_pos; ++ arena->pos += (size + align_pos); + return mem; + } + +diff --git a/src/nvim/memory.h b/src/nvim/memory.h +index f40719233165..1c2ed2ba3b20 100644 +--- a/src/nvim/memory.h ++++ b/src/nvim/memory.h +@@ -45,7 +45,7 @@ typedef struct consumed_blk { + struct consumed_blk *prev; + } *ArenaMem; + +-#define ARENA_ALIGN sizeof(void *) ++#define ARENA_ALIGN MAX(sizeof(void *), sizeof(double)) + + typedef struct { + char *cur_blk; + +From 8b7247af7dc613a7e4248ba14760f586a8a66a32 Mon Sep 17 00:00:00 2001 +From: bfredl +Date: Mon, 31 Oct 2022 10:07:21 +0100 +Subject: [PATCH 2/2] refactor(memory): simplify new alignment logic + +In particular, we can assume the xmalloc-ed pointer is at least +double-aligned, otherwise nothing work work. +--- + src/nvim/memory.c | 32 +++++++++++++++++--------------- + 1 file changed, 17 insertions(+), 15 deletions(-) + +diff --git a/src/nvim/memory.c b/src/nvim/memory.c +index 93aa9bd6e55e..16033e9c63f5 100644 +--- a/src/nvim/memory.c ++++ b/src/nvim/memory.c +@@ -577,14 +577,13 @@ void alloc_block(Arena *arena) + blk->prev = prev_blk; + } + +-static size_t arena_align_offset(void *ptr, size_t alignment) ++static size_t arena_align_offset(uint64_t off) + { +- uintptr_t uptr = (uintptr_t)ptr; +- return ((uptr + (alignment - 1)) & ~(alignment - 1)) - uptr; ++ return ((off + (ARENA_ALIGN - 1)) & ~(ARENA_ALIGN - 1)); + } + + /// @param arena if NULL, do a global allocation. caller must then free the value! +-/// @param size if zero, will still return a non-null pointer, but not a unique one ++/// @param size if zero, will still return a non-null pointer, but not a usable or unique one + void *arena_alloc(Arena *arena, size_t size, bool align) + { + if (!arena) { +@@ -593,30 +592,33 @@ void *arena_alloc(Arena *arena, size_t size, bool align) + if (!arena->cur_blk) { + alloc_block(arena); + } +- size_t align_pos = align ? arena_align_offset(arena->cur_blk + arena->pos, ARENA_ALIGN) : 0; +- if (arena->pos + align_pos + size > arena->size) { +- if (size + (align ? (ARENA_ALIGN - 1) : 0) > (ARENA_BLOCK_SIZE - sizeof(struct consumed_blk)) +- >> 1) { ++ size_t alloc_pos = align ? arena_align_offset(arena->pos) : arena->pos; ++ if (alloc_pos + size > arena->size) { ++ if (size > (ARENA_BLOCK_SIZE - sizeof(struct consumed_blk)) >> 1) { + // if allocation is too big, allocate a large block with the requested + // size, but still with block pointer head. We do this even for + // arena->size / 2, as there likely is space left for the next + // small allocation in the current block. + arena_alloc_count++; +- char *alloc = xmalloc(size + sizeof(struct consumed_blk) + (align ? (ARENA_ALIGN - 1) : 0)); ++ size_t hdr_size = sizeof(struct consumed_blk); ++ size_t aligned_hdr_size = (align ? arena_align_offset(hdr_size) : hdr_size); ++ char *alloc = xmalloc(size + aligned_hdr_size); ++ ++ // to simplify free-list management, arena->cur_blk must ++ // always be a normal, ARENA_BLOCK_SIZE sized, block + struct consumed_blk *cur_blk = (struct consumed_blk *)arena->cur_blk; + struct consumed_blk *fix_blk = (struct consumed_blk *)alloc; + fix_blk->prev = cur_blk->prev; + cur_blk->prev = fix_blk; +- char *mem = (alloc + sizeof(struct consumed_blk)); +- return mem + (align ? arena_align_offset(mem, ARENA_ALIGN) : 0); ++ return alloc + aligned_hdr_size; + } else { +- alloc_block(arena); +- align_pos = align ? arena_align_offset(arena->cur_blk + arena->pos, ARENA_ALIGN) : 0; ++ alloc_block(arena); // resets arena->pos ++ alloc_pos = align ? arena_align_offset(arena->pos) : arena->pos; + } + } + +- char *mem = arena->cur_blk + arena->pos + align_pos; +- arena->pos += (size + align_pos); ++ char *mem = arena->cur_blk + alloc_pos; ++ arena->pos = alloc_pos + size; + return mem; + } + diff --git a/neovim.spec b/neovim.spec index ba5ee1d..34331a0 100644 --- a/neovim.spec +++ b/neovim.spec @@ -18,17 +18,18 @@ Summary: Vim-fork focused on extensibility and agility Name: neovim -Version: 0.8.0 +Version: 0.8.1 Release: 1 License: Apache v2.0 Group: Applications/Editors/Vim # Source0Download: https://github.com/neovim/neovim/releases Source0: https://github.com/neovim/neovim/archive/v%{version}/%{name}-%{version}.tar.gz -# Source0-md5: 4fccaf03bd8854e902cabf65e85e3346 +# Source0-md5: 61c323fdeb948c31d780dd33f2b764f6 URL: https://neovim.io/ Source2: %{name}.svg Patch0: desktop.patch Patch1: build-type.patch +Patch2: armv7-memalign.patch BuildRequires: cmake >= 3.10 BuildRequires: gcc >= 6:4.4 BuildRequires: gettext-tools @@ -96,6 +97,7 @@ Desktop files for Neovim. %setup -q %patch0 -p1 %patch1 -p1 +%patch2 -p1 %build %cmake -B build \