Skip to content
Snippets Groups Projects
Commit 6f2d1498 authored by Ludovico de Nittis's avatar Ludovico de Nittis
Browse files

inspect-library: Refactor several functions into a separate file


Move the shared functions between `inspect-library` and
`inspect-library-supplement` into a common separate file.
This helps to avoid duplicating code between the two helpers.

Signed-off-by: default avatarLudovico de Nittis <ludovico.denittis@collabora.com>
parent 5fbba53b
No related branches found
No related tags found
1 merge request!540Avoid libelf dependency in critical-path code
Pipeline #42330 passed
......@@ -49,27 +49,7 @@
#include <libelf.h>
#include <gelf.h>
static void print_json_string_content (const char *s);
static void oom (void) __attribute__((__noreturn__));
static void
oom (void)
{
fprintf (stderr, "Out of memory");
exit (EX_OSERR);
}
#define asprintf_or_die(...) \
do { \
if (asprintf (__VA_ARGS__) < 0) \
oom (); \
} while (0)
#define argz_add_or_die(...) \
do { \
if (argz_add (__VA_ARGS__) != 0) \
oom (); \
} while (0)
#include <inspect-library-utils.h>
static inline void *
malloc_or_die (size_t size)
......@@ -82,30 +62,6 @@ malloc_or_die (size_t size)
return p;
}
static inline void *
steal_pointer (void *pp)
{
typedef void *__attribute__((may_alias)) voidp_alias;
voidp_alias *pointer_to_pointer = pp;
void *ret = *pointer_to_pointer;
*pointer_to_pointer = NULL;
return ret;
}
static inline int
steal_fd (int *fdp)
{
int fd = *fdp;
*fdp = -1;
return fd;
}
static void
clear_with_free (void *pp)
{
free (steal_pointer (pp));
}
static void
clear_with_freev (void *pp)
{
......@@ -118,15 +74,6 @@ clear_with_freev (void *pp)
free (str_array);
}
static void
clear_with_fclose (void *pp)
{
FILE *fh = steal_pointer (pp);
if (fh != NULL)
fclose (fh);
}
static void
close_fd (void *pp)
{
......@@ -145,9 +92,7 @@ close_elf (void *pp)
elf_end (elf);
}
#define autofclose __attribute__((__cleanup__(clear_with_fclose)))
#define autofreev __attribute__((__cleanup__(clear_with_freev)))
#define autofree __attribute__((__cleanup__(clear_with_free)))
#define autofd __attribute__((__cleanup__(close_fd)))
#define autoelf __attribute__((__cleanup__(close_elf)))
......@@ -191,78 +136,6 @@ usage (int code)
exit (code);
}
/*
* Print a bytestring to stdout, escaping backslashes and control
* characters in octal. The result can be parsed with g_strcompress().
*/
static void
print_strescape (const char *bytestring)
{
const unsigned char *p;
for (p = (const unsigned char *) bytestring; *p != '\0'; p++)
{
if (*p < ' ' || *p >= 0x7f || *p == '\\')
printf ("\\%03o", *p);
else
putc (*p, stdout);
}
}
/*
* Print an element as either a line based or, if @name_line_based
* is %NULL, as an entry in a JSON array.
*/
static void
print_array_entry (const char *entry,
const char *name_line_based,
bool *first)
{
assert (entry != NULL);
assert (first != NULL);
if (*first)
*first = false;
else if (name_line_based == NULL)
printf (",");
if (name_line_based == NULL)
{
printf ("\n \"");
print_json_string_content (entry);
printf ("\"");
}
else
{
fprintf (stdout, "%s=", name_line_based);
print_strescape (entry);
putc ('\n', stdout);
}
}
/*
* Print an array in stdout as either a formatted JSON entry or
* a line based
*/
static void
print_argz (const char *name,
const char *argz_values,
size_t argz_n,
bool line_based)
{
const char *entry = 0;
bool first = true;
if (!line_based)
printf (",\n \"%s\": [", name);
while ((entry = argz_next (argz_values, argz_n, entry)))
print_array_entry (entry, line_based ? name : NULL, &first);
if (!line_based)
printf ("\n ]");
}
static int
bsearch_strcmp_cb (const void *n, const void *ip)
{
......@@ -692,17 +565,3 @@ main (int argc,
return 0;
}
static void
print_json_string_content (const char *s)
{
const unsigned char *p;
for (p = (const unsigned char *) s; *p != '\0'; p++)
{
if (*p == '"' || *p == '\\' || *p <= 0x1F || *p >= 0x80)
printf ("\\u%04x", *p);
else
printf ("%c", *p);
}
}
/*
* Copyright © 2019-2023 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <argz.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <link.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <assert.h>
#include <unistd.h>
#include "inspect-library-utils.h"
void *
steal_pointer (void *pp)
{
typedef void *__attribute__((may_alias)) voidp_alias;
voidp_alias *pointer_to_pointer = pp;
void *ret = *pointer_to_pointer;
*pointer_to_pointer = NULL;
return ret;
}
int
steal_fd (int *fdp)
{
int fd = *fdp;
*fdp = -1;
return fd;
}
void
clear_with_free (void *pp)
{
free (steal_pointer (pp));
}
void
clear_with_fclose (void *pp)
{
FILE *fh = steal_pointer (pp);
if (fh != NULL)
fclose (fh);
}
/*
* Print a bytestring to stdout, escaping backslashes and control
* characters in octal. The result can be parsed with g_strcompress().
*/
void
print_strescape (const char *bytestring)
{
const unsigned char *p;
for (p = (const unsigned char *) bytestring; *p != '\0'; p++)
{
if (*p < ' ' || *p >= 0x7f || *p == '\\')
printf ("\\%03o", *p);
else
putc (*p, stdout);
}
}
void
print_json_string_content (const char *s)
{
const unsigned char *p;
for (p = (const unsigned char *) s; *p != '\0'; p++)
{
if (*p == '"' || *p == '\\' || *p <= 0x1F || *p >= 0x80)
printf ("\\u%04x", *p);
else
printf ("%c", *p);
}
}
/*
* Print an element as either a line based or, if @name_line_based
* is %NULL, as an entry in a JSON array.
*/
void
print_array_entry (const char *entry,
const char *name_line_based,
bool *first)
{
assert (entry != NULL);
assert (first != NULL);
if (*first)
*first = false;
else if (name_line_based == NULL)
printf (",");
if (name_line_based == NULL)
{
printf ("\n \"");
print_json_string_content (entry);
printf ("\"");
}
else
{
fprintf (stdout, "%s=", name_line_based);
print_strescape (entry);
putc ('\n', stdout);
}
}
/*
* Print an array in stdout as either a formatted JSON entry or
* a line based
*/
void
print_argz (const char *name,
const char *argz_values,
size_t argz_n,
bool line_based)
{
const char *entry = 0;
bool first = true;
if (!line_based)
printf (",\n \"%s\": [", name);
while ((entry = argz_next (argz_values, argz_n, entry)))
print_array_entry (entry, line_based ? name : NULL, &first);
if (!line_based)
printf ("\n ]");
}
/*
* Copyright © 2019-2023 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <argz.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <link.h>
static inline void oom (void) __attribute__((__noreturn__));
static inline void
oom (void)
{
fprintf (stderr, "Out of memory");
exit (EX_OSERR);
}
#define asprintf_or_die(...) \
do { \
if (asprintf (__VA_ARGS__) < 0) \
oom (); \
} while (0)
#define argz_add_or_die(...) \
do { \
if (argz_add (__VA_ARGS__) != 0) \
oom (); \
} while (0)
void *steal_pointer (void *pp);
int steal_fd (int *fdp);
void clear_with_free (void *pp);
void clear_with_fclose (void *pp);
#define autofclose __attribute__((__cleanup__(clear_with_fclose)))
#define autofree __attribute__((__cleanup__(clear_with_free)))
void print_strescape (const char *bytestring);
void print_json_string_content (const char *s);
void print_array_entry (const char *entry,
const char *name_line_based,
bool *first);
void print_argz (const char *name,
const char *argz_values,
size_t argz_n,
bool line_based);
......@@ -44,50 +44,15 @@
#include <sysexits.h>
#include <assert.h>
#include <inspect-library-utils.h>
#define BASE "Base"
static void print_json_string_content (const char *s);
static bool has_symbol (void *handle, const char *symbol);
static bool has_versioned_symbol (void *handle,
const char *symbol,
const char * version);
static void oom (void) __attribute__((__noreturn__));
static void
oom (void)
{
fprintf (stderr, "Out of memory");
exit (EX_OSERR);
}
#define asprintf_or_die(...) \
do { \
if (asprintf (__VA_ARGS__) < 0) \
oom (); \
} while (0)
#define argz_add_or_die(...) \
do { \
if (argz_add (__VA_ARGS__) != 0) \
oom (); \
} while (0)
static inline void *
steal_pointer (void *pp)
{
typedef void *__attribute__((may_alias)) voidp_alias;
voidp_alias *pointer_to_pointer = pp;
void *ret = *pointer_to_pointer;
*pointer_to_pointer = NULL;
return ret;
}
static void
clear_with_free (void *pp)
{
free (steal_pointer (pp));
}
static void
clear_with_dlclose (void *pp)
{
......@@ -97,18 +62,7 @@ clear_with_dlclose (void *pp)
dlclose (handle);
}
static void
clear_with_fclose (void *pp)
{
FILE *fh = steal_pointer (pp);
if (fh != NULL)
fclose (fh);
}
#define autodlclose __attribute__((__cleanup__(clear_with_dlclose)))
#define autofclose __attribute__((__cleanup__(clear_with_fclose)))
#define autofree __attribute__((__cleanup__(clear_with_free)))
enum
{
......@@ -184,80 +138,6 @@ find_tag_value (const ElfW(Dyn) *dyn,
return (size_t) -1;
}
/*
* Print a bytestring to stdout, escaping backslashes and control
* characters in octal. The result can be parsed with g_strcompress().
*/
static void
print_strescape (const char *bytestring)
{
const unsigned char *p;
for (p = (const unsigned char *) bytestring; *p != '\0'; p++)
{
if (*p < ' ' || *p >= 0x7f || *p == '\\')
printf ("\\%03o", *p);
else
putc (*p, stdout);
}
}
/*
* Print an element as either a line based or, if @name_line_based
* is %NULL, as an entry in a JSON array.
*/
static void
print_array_entry (const char *entry,
const char *name_line_based,
bool *first)
{
assert (entry != NULL);
assert (first != NULL);
if (*first)
*first = false;
else if (name_line_based == NULL)
printf (",");
if (name_line_based == NULL)
{
printf ("\n \"");
print_json_string_content (entry);
printf ("\"");
}
else
{
fprintf (stdout, "%s=", name_line_based);
print_strescape (entry);
putc ('\n', stdout);
}
}
/*
* Print an array in stdout as either a formatted JSON entry or
* a line based
*/
static void
print_argz (const char *name,
const char *argz_values,
size_t argz_n,
bool line_based)
{
const char *entry = 0;
bool first = true;
if (!line_based)
printf (",\n \"%s\": [", name);
while ((entry = argz_next (argz_values, argz_n, entry)))
print_array_entry (entry, line_based ? name : NULL, &first);
if (!line_based)
printf ("\n ]");
}
int
main (int argc,
char **argv)
......@@ -561,20 +441,6 @@ main (int argc,
return 0;
}
static void
print_json_string_content (const char *s)
{
const unsigned char *p;
for (p = (const unsigned char *) s; *p != '\0'; p++)
{
if (*p == '"' || *p == '\\' || *p <= 0x1F || *p >= 0x80)
printf ("\\u%04x", *p);
else
printf ("%c", *p);
}
}
static bool
has_symbol (void *handle,
const char *symbol)
......
......@@ -47,7 +47,7 @@ executable(
executable(
multiarch + '-inspect-library',
sources : 'inspect-library.c',
sources : ['inspect-library.c', 'inspect-library-utils.c'],
dependencies : [libdl],
include_directories : project_include_dirs,
install : true,
......@@ -58,7 +58,7 @@ executable(
executable(
multiarch + '-inspect-library-libelf',
sources : 'inspect-library-libelf.c',
sources : ['inspect-library-libelf.c', 'inspect-library-utils.c'],
dependencies : [libdl, libelf],
include_directories : project_include_dirs,
install : true,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment