]> git.pld-linux.org Git - packages/neovim.git/commitdiff
up to 0.8.1 auto/th/neovim-0.8.1-1
authorJan Palus <atler@pld-linux.org>
Thu, 17 Nov 2022 18:49:35 +0000 (19:49 +0100)
committerJan Palus <atler@pld-linux.org>
Thu, 17 Nov 2022 18:49:35 +0000 (19:49 +0100)
- fix memory alignment crash on armv7
  (https://github.com/neovim/neovim/pull/20489)

armv7-memalign.patch [new file with mode: 0644]
neovim.spec

diff --git a/armv7-memalign.patch b/armv7-memalign.patch
new file mode 100644 (file)
index 0000000..f5935b0
--- /dev/null
@@ -0,0 +1,179 @@
+From 0240fd6d0f7e27c459b243578ad51100ff6e2b66 Mon Sep 17 00:00:00 2001
+From: Jan Palus <jpalus@fastmail.com>
+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 <assert.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
++#include <stdint.h>
+ #include <string.h>
+ #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 <bjorn.linse@gmail.com>
+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;
+ }
index ba5ee1d9c0a70a527b2c118355558e1f492203f8..34331a0b219ac249a9fdc0481a59375dd530f5c0 100644 (file)
 
 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 \
This page took 0.184259 seconds and 4 git commands to generate.