[v2,14/16] Add function sys_get_page_size to replace platform dependent sysconf (_SC_PAGESIZE)

Message ID 20221217165213.152-15-luoyonggang@gmail.com
State Under Review
Headers
Series Patches for building with mingw/gcc msvc/clang-cl |

Commit Message

Yonggang Luo Dec. 17, 2022, 4:52 p.m. UTC
  Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
 lib/Makefile.am                |  2 +-
 lib/crc32_file.c               |  2 +-
 lib/system.c                   | 48 ++++++++++++++++++++++++++++++++++
 lib/system.h                   |  3 +++
 libdw/dwarf_begin_elf.c        |  2 +-
 libdwelf/dwelf_strtab.c        |  2 +-
 libdwfl/linux-kernel-modules.c |  2 +-
 libdwfl/linux-proc-maps.c      |  2 +-
 libelf/elf32_updatefile.c      |  2 +-
 src/ar.c                       |  2 +-
 src/ranlib.c                   |  2 +-
 src/strings.c                  |  2 +-
 12 files changed, 61 insertions(+), 10 deletions(-)
 create mode 100644 lib/system.c
  

Comments

Mark Wielaard March 2, 2023, 4:33 p.m. UTC | #1
Hi,

On Sun, 2022-12-18 at 00:52 +0800, Yonggang Luo via Elfutils-devel
wrote:
> Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
> ---
>  lib/Makefile.am                |  2 +-
>  lib/crc32_file.c               |  2 +-
>  lib/system.c                   | 48 ++++++++++++++++++++++++++++++++++
>  lib/system.h                   |  3 +++
>  libdw/dwarf_begin_elf.c        |  2 +-
>  libdwelf/dwelf_strtab.c        |  2 +-
>  libdwfl/linux-kernel-modules.c |  2 +-
>  libdwfl/linux-proc-maps.c      |  2 +-
>  libelf/elf32_updatefile.c      |  2 +-
>  src/ar.c                       |  2 +-
>  src/ranlib.c                   |  2 +-
>  src/strings.c                  |  2 +-
>  12 files changed, 61 insertions(+), 10 deletions(-)
>  create mode 100644 lib/system.c
> 
> diff --git a/lib/Makefile.am b/lib/Makefile.am
> index 42ddf5ae..7a50085b 100644
> --- a/lib/Makefile.am
> +++ b/lib/Makefile.am
> @@ -35,7 +35,7 @@ noinst_LIBRARIES = libeu.a
>  
>  libeu_a_SOURCES = xasprintf.c xstrdup.c xstrndup.c xmalloc.c next_prime.c \
>  		  crc32.c crc32_file.c \
> -		  color.c error.c printversion.c
> +		  color.c error.c printversion.c system.c
>  
>  noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
>  		 eu-config.h color.h printversion.h bpf.h \
> diff --git a/lib/crc32_file.c b/lib/crc32_file.c
> index 66833702..45e1cc52 100644
> --- a/lib/crc32_file.c
> +++ b/lib/crc32_file.c
> @@ -52,7 +52,7 @@ crc32_file (int fd, uint32_t *resp)
>        void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
>        if (mapped == MAP_FAILED && errno == ENOMEM)
>  	{
> -	  const size_t pagesize = sysconf (_SC_PAGESIZE);
> +	  const size_t pagesize = sys_get_page_size();
>  	  mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize;
>  	  while (mapsize >= pagesize
>  		 && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE,
> diff --git a/lib/system.c b/lib/system.c
> new file mode 100644
> index 00000000..bd3831f5
> --- /dev/null
> +++ b/lib/system.c
> @@ -0,0 +1,48 @@
> +/* Definitions for system functions.
> +   Copyright (C) 2006-2011 Red Hat, Inc.
> +   Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
> +   Copyright (C) 2022 Yonggang Luo <luoyonggang@gmail.com>
> +   This file is part of elfutils.
> +
> +   This file is free software; you can redistribute it and/or modify
> +   it under the terms of either
> +
> +     * the GNU Lesser General Public License as published by the Free
> +       Software Foundation; either version 3 of the License, or (at
> +       your option) any later version
> +
> +   or
> +
> +     * the GNU General Public License as published by the Free
> +       Software Foundation; either version 2 of the License, or (at
> +       your option) any later version
> +
> +   or both in parallel, as here.
> +
> +   elfutils is distributed in the hope that it will be useful, but
> +   WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   General Public License for more details.
> +
> +   You should have received copies of the GNU General Public License and
> +   the GNU Lesser General Public License along with this program.  If
> +   not, see <http://www.gnu.org/licenses/>.  */
> +
> +#include <errno.h>
> +
> +#include "system.h"
> +#if defined(_WIN32)
> +#include <windows.h>
> +#endif
> +
> +size_t
> +sys_get_page_size(void)
> +{
> +#ifdef _WIN32
> +  SYSTEM_INFO info;
> +  GetSystemInfo(&info);
> +  return info.dwPageSize;
> +#else
> +  return sysconf (_SC_PAGESIZE);
> +#endif
> +}

I am not against abstracting this, but can we use some configure check
to see how to get the pagesize? I don't really like these #ifdef
_WIN32.

Does your environment provide the getpagesize() function that comes
from SVr4, 4.4BSD, SUSv2 and was part of older POSIX?

Cheers,

Mark
  

Patch

diff --git a/lib/Makefile.am b/lib/Makefile.am
index 42ddf5ae..7a50085b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -35,7 +35,7 @@  noinst_LIBRARIES = libeu.a
 
 libeu_a_SOURCES = xasprintf.c xstrdup.c xstrndup.c xmalloc.c next_prime.c \
 		  crc32.c crc32_file.c \
-		  color.c error.c printversion.c
+		  color.c error.c printversion.c system.c
 
 noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
 		 eu-config.h color.h printversion.h bpf.h \
diff --git a/lib/crc32_file.c b/lib/crc32_file.c
index 66833702..45e1cc52 100644
--- a/lib/crc32_file.c
+++ b/lib/crc32_file.c
@@ -52,7 +52,7 @@  crc32_file (int fd, uint32_t *resp)
       void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
       if (mapped == MAP_FAILED && errno == ENOMEM)
 	{
-	  const size_t pagesize = sysconf (_SC_PAGESIZE);
+	  const size_t pagesize = sys_get_page_size();
 	  mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize;
 	  while (mapsize >= pagesize
 		 && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE,
diff --git a/lib/system.c b/lib/system.c
new file mode 100644
index 00000000..bd3831f5
--- /dev/null
+++ b/lib/system.c
@@ -0,0 +1,48 @@ 
+/* Definitions for system functions.
+   Copyright (C) 2006-2011 Red Hat, Inc.
+   Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org>
+   Copyright (C) 2022 Yonggang Luo <luoyonggang@gmail.com>
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+
+#include "system.h"
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+size_t
+sys_get_page_size(void)
+{
+#ifdef _WIN32
+  SYSTEM_INFO info;
+  GetSystemInfo(&info);
+  return info.dwPageSize;
+#else
+  return sysconf (_SC_PAGESIZE);
+#endif
+}
diff --git a/lib/system.h b/lib/system.h
index 7f9f2a91..c84c416c 100644
--- a/lib/system.h
+++ b/lib/system.h
@@ -200,6 +200,9 @@  pread_retry (int fd, void *buf, size_t len, off_t off)
   return recvd;
 }
 
+size_t
+sys_get_page_size(void);
+
 /* The demangler from libstdc++.  */
 extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
 			     size_t *length, int *status);
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 8fcef335..0f13e2f5 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -502,7 +502,7 @@  dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
 
 
   /* Default memory allocation size.  */
-  size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
+  size_t mem_default_size = sys_get_page_size() - 4 * sizeof (void *);
   assert (sizeof (struct Dwarf) < mem_default_size);
 
   /* Allocate the data structure.  */
diff --git a/libdwelf/dwelf_strtab.c b/libdwelf/dwelf_strtab.c
index c95f9467..293b2d93 100644
--- a/libdwelf/dwelf_strtab.c
+++ b/libdwelf/dwelf_strtab.c
@@ -86,7 +86,7 @@  dwelf_strtab_init (bool nullstr)
 {
   if (ps == 0)
     {
-      ps = sysconf (_SC_PAGESIZE);
+      ps = sys_get_page_size();
       assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD);
     }
 
diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c
index 58c0c417..65a58616 100644
--- a/libdwfl/linux-kernel-modules.c
+++ b/libdwfl/linux-kernel-modules.c
@@ -550,7 +550,7 @@  intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes)
 	    *notes = *end;
 	}
 
-      Dwarf_Addr round_kernel = sysconf (_SC_PAGESIZE);
+      Dwarf_Addr round_kernel = sys_get_page_size();
       *start &= -(Dwarf_Addr) round_kernel;
       *end += round_kernel - 1;
       *end &= -(Dwarf_Addr) round_kernel;
diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c
index 719cba68..40b8050b 100644
--- a/libdwfl/linux-proc-maps.c
+++ b/libdwfl/linux-proc-maps.c
@@ -422,7 +422,7 @@  dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
       if (fd < 0)
 	goto detach;
 
-      *elfp = elf_from_remote_memory (base, sysconf (_SC_PAGESIZE), NULL,
+      *elfp = elf_from_remote_memory (base, sys_get_page_size(), NULL,
 				      &read_proc_memory, &fd);
 
       close (fd);
diff --git a/libelf/elf32_updatefile.c b/libelf/elf32_updatefile.c
index 8229fd26..af4518b8 100644
--- a/libelf/elf32_updatefile.c
+++ b/libelf/elf32_updatefile.c
@@ -474,7 +474,7 @@  __elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
 
   /* Make sure the content hits the disk.  */
   char *msync_start = ((char *) elf->map_address
-		       + (elf->start_offset & ~(sysconf (_SC_PAGESIZE) - 1)));
+		       + (elf->start_offset & ~(sys_get_page_size() - 1)));
   char *msync_end = ((char *) elf->map_address
 		     + elf->start_offset + ehdr->e_shoff
 		     + ehdr->e_shentsize * shnum);
diff --git a/src/ar.c b/src/ar.c
index 3bcb18fe..d01f8482 100644
--- a/src/ar.c
+++ b/src/ar.c
@@ -428,7 +428,7 @@  copy_content (Elf *elf, int newfd, off_t off, size_t n)
   assert (off + n <= len);
 
   /* Tell the kernel we will read all the pages sequentially.  */
-  size_t ps = sysconf (_SC_PAGESIZE);
+  size_t ps = sys_get_page_size();
   if (n > 2 * ps)
     posix_madvise (rawfile + (off & ~(ps - 1)), n, POSIX_MADV_SEQUENTIAL);
 
diff --git a/src/ranlib.c b/src/ranlib.c
index 7838d69e..645b40ae 100644
--- a/src/ranlib.c
+++ b/src/ranlib.c
@@ -122,7 +122,7 @@  copy_content (Elf *elf, int newfd, off_t off, size_t n)
   assert (off + n <= len);
 
   /* Tell the kernel we will read all the pages sequentially.  */
-  size_t ps = sysconf (_SC_PAGESIZE);
+  size_t ps = sys_get_page_size();
   if (n > 2 * ps)
     posix_madvise (rawfile + (off & ~(ps - 1)), n, POSIX_MADV_SEQUENTIAL);
 
diff --git a/src/strings.c b/src/strings.c
index 55b047be..3341760d 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -163,7 +163,7 @@  main (int argc, char *argv[])
   elf_version (EV_CURRENT);
 
   /* Determine the page size.  We will likely need it a couple of times.  */
-  ps = sysconf (_SC_PAGESIZE);
+  ps = sys_get_page_size();
 
   struct stat st;
   int result = 0;