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 <[email protected]>
---
 libelf/Makefile.am  | 13 +++++++++++++
 libelf/gelf_fsize.c | 46 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

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 <[email protected]>
 ## 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 <[email protected]>
    This file is part of elfutils.
    Written by Ulrich Drepper <[email protected]>, 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
-- 
2.51.1

Reply via email to