libelf: Add gelf_fsize main check

Message ID 20251208104445.2785906-1-mark@klomp.org
State Committed
Headers
Series libelf: Add gelf_fsize main check |

Commit Message

Mark Wielaard Dec. 8, 2025, 10:44 a.m. UTC
  This test itself isn't super interesting, it just checks that all
Elf_Types are handled by gelf_fsize and that the 32 vs 64 variant
sizes make sense. The interesting part is that it uses the internal
interface (__libelf_type_sizes) to do it. So you don't have to
contruct a whole Elf handle.

It mimics the support for "main checks" in libdw. It adds a way to
compile an individual source file with an optional main function that
can directly access the internal/static functions.

To add new main check tests you have to add an #ifdef MAIN_CHECK with
a main function that calls the test functions to the source file. And
add two make file rules after .SECONDEXPANSION. One starting with
<source_basename>_checks$(EXEEXT) and one starting with
nodist_<source_basename>_check_SOURCES.

	* libelf/gelf_fsize.c: Add MAIN_CHECK part.
	* libelf/Makefile.am: Add gelf_fsize main check rules.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libelf/Makefile.am  | 13 +++++++++++++
 libelf/gelf_fsize.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)
  

Comments

Mark Wielaard Dec. 15, 2025, 10:10 p.m. UTC | #1
Hi,

On Mon, Dec 08, 2025 at 11:44:45AM +0100, Mark Wielaard wrote:
> This test itself isn't super interesting, it just checks that all
> Elf_Types are handled by gelf_fsize and that the 32 vs 64 variant
> sizes make sense. The interesting part is that it uses the internal
> interface (__libelf_type_sizes) to do it. So you don't have to
> contruct a whole Elf handle.
> 
> It mimics the support for "main checks" in libdw. It adds a way to
> compile an individual source file with an optional main function that
> can directly access the internal/static functions.
> 
> To add new main check tests you have to add an #ifdef MAIN_CHECK with
> a main function that calls the test functions to the source file. And
> add two make file rules after .SECONDEXPANSION. One starting with
> <source_basename>_checks$(EXEEXT) and one starting with
> nodist_<source_basename>_check_SOURCES.
> 
> 	* libelf/gelf_fsize.c: Add MAIN_CHECK part.
> 	* libelf/Makefile.am: Add gelf_fsize main check rules.

Pushed after Aaron said on irc it looked OK.

Cheers,

Mark
  

Patch

diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 05484c12c0a0..cc539c8dab3c 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -1,6 +1,7 @@ 
 ## Process this file with automake to create Makefile.in
 ##
 ## Copyright (C) 1996-2010, 2015 Red Hat, Inc.
+## Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org>
 ## This file is part of elfutils.
 ##
 ## This file is free software; you can redistribute it and/or modify
@@ -145,3 +146,15 @@  libelf.manifest: $(libelf_a_OBJECTS)
 
 MOSTLYCLEANFILES = $(am_libelf_a_OBJECTS) $(am_libelf_pic_a_OBJECTS) libelf.so.$(VERSION)
 CLEANFILES = libelf.so $(EXTRA_libelf_a_DEPENDENCIES)
+
+# Internal checks
+check_PROGRAMS = gelf_fsize_check
+TESTS = $(check_PROGRAMS)
+
+CHECK_DEF_FLAGS = $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) \
+       $(DEFAULT_INCLUDES) -Wl,-rpath,../libelf -DMAIN_CHECK=1
+
+.SECONDEXPANSION:
+gelf_fsize_check$(EXEEXT): $$(filter-out $$(subst _check,,$$@).o,$(libelf_a_OBJECTS)) $$(subst _check,,$$@).c
+	$(AM_V_CC)$(CC) $(CHECK_DEF_FLAGS) -o $@ $^ $(filter-out libelf_pic.a,$(libelf_so_LIBS)) $(libelf_so_LDLIBS)
+nodist_gelf_fsize_check_SOURCES = gelf_fsize_check.c
diff --git a/libelf/gelf_fsize.c b/libelf/gelf_fsize.c
index 63bcbae51a1d..6f99d83979aa 100644
--- a/libelf/gelf_fsize.c
+++ b/libelf/gelf_fsize.c
@@ -1,5 +1,6 @@ 
 /* Return the size of an object file type.
    Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   Copyright (C) 2025 Mark J. Wielaard <mark@klomp.org>
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 1998.
 
@@ -102,3 +103,48 @@  gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version)
   return count * __libelf_type_sizes[elf->class - 1][type];
 }
 INTDEF(gelf_fsize)
+
+
+#ifdef MAIN_CHECK
+#include <inttypes.h>
+#include <stdio.h>
+
+void
+test_fsize (Elf_Type type)
+{
+  printf ("Testing 0x%" PRIx32 ": ", type);
+
+  int fsize32 = __libelf_type_sizes[ELFCLASS32 - 1][type];
+  if (fsize32 <= 0)
+    {
+      printf ("Unhandled type %" PRIx32 " for ELFCLASS32\n", type);
+      exit (-1);
+    }
+  printf (" %d, ", fsize32);
+
+  int fsize64 = __libelf_type_sizes[ELFCLASS64 - 1][type];
+  if (fsize64 <= 0)
+    {
+      printf ("Unhandled type %" PRIx32 " for ELFCLASS64\n", type);
+      exit (-1);
+    }
+  printf ("%d\n", fsize64);
+
+  /* In theory fsize for 32 bit could of course be larger than fsize
+     for 64 bit.  But if so, better adjust this testcase and
+     explain.  */
+  if (fsize32 > fsize64)
+    {
+      printf ("fsize32 %d > fsize64 %d\n", fsize32, fsize64);
+      exit(-1);
+    }
+}
+
+int
+main (void)
+{
+  for (Elf_Type type = 0; type < ELF_T_NUM; type++)
+    test_fsize (type);
+  return 0;
+}
+#endif