[gnome-ostree/wip/libgelf] WIP libgelf/debuginfo processing
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree/wip/libgelf] WIP libgelf/debuginfo processing
- Date: Sat, 16 Mar 2013 23:17:45 +0000 (UTC)
commit 53fde17f52004c0525f57437e8ebbcc903ec7aab
Author: Colin Walters <walters verbum org>
Date: Thu Feb 21 15:27:09 2013 -0500
WIP libgelf/debuginfo processing
Makefile-gsystem-introspection.am | 16 ++
Makefile-libgelf.am | 25 +++
Makefile.am | 35 ++---
configure.ac | 10 +-
src/libgelf/gelf-file.c | 330 +++++++++++++++++++++++++++++++++++++
src/libgelf/gelf-file.h | 61 +++++++
src/libgelf/libgelf.h | 32 ++++
7 files changed, 483 insertions(+), 26 deletions(-)
---
diff --git a/Makefile-gsystem-introspection.am b/Makefile-gsystem-introspection.am
new file mode 100644
index 0000000..3f7d763
--- /dev/null
+++ b/Makefile-gsystem-introspection.am
@@ -0,0 +1,16 @@
+INTROSPECTION_GIRS += GSystem-1.0.gir
+
+GSystem-1.0.gir: libgsystem.la Makefile
+GSystem_1_0_gir_NAMESPACE = GSystem
+GSystem_1_0_gir_VERSION = 1.0
+GSystem_1_0_gir_LIBS = libgsystem.la
+GSystem_1_0_gir_CFLAGS = $(libgsystem_cflags)
+GSystem_1_0_gir_SCANNERFLAGS = \
+ --warn-all \
+ --warn-error \
+ --symbol-prefix=gs_ \
+ --identifier-prefix=GS \
+ --c-include="libgsystem.h" \
+ $(NULL)
+GSystem_1_0_gir_INCLUDES = Gio-2.0
+GSystem_1_0_gir_FILES = $(libgsystem_la_SOURCES)
diff --git a/Makefile-libgelf.am b/Makefile-libgelf.am
new file mode 100644
index 0000000..e619a94
--- /dev/null
+++ b/Makefile-libgelf.am
@@ -0,0 +1,25 @@
+privlib_LTLIBRARIES += libgelf.la
+libgelf_la_SOURCES = src/libgelf/libgelf.h \
+ src/libgelf/gelf-file.c \
+ src/libgelf/gelf-file.h \
+ $(NULL)
+libgelf_la_CFLAGS = $(AM_CFLAGS) $(OSTBUILD_DEP_CFLAGS) -I$(top_srcdir)/src/libgelf
+libgelf_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^gelf_" -no-undefined
-export-dynamic
+libgelf_la_LIBADD = $(OSTBUILD_DEP_LIBS) -lelf
+
+INTROSPECTION_GIRS += GElf-1.0.gir
+
+GElf-1.0.gir: libgelf.la Makefile
+GElf_1_0_gir_NAMESPACE = GElf
+GElf_1_0_gir_VERSION = 1.0
+GElf_1_0_gir_LIBS = libgelf.la
+GElf_1_0_gir_CFLAGS = $(OSTBUILD_DEP_CFLAGS) -I$(top_srcdir)/src/libgelf
+GElf_1_0_gir_SCANNERFLAGS = \
+ --warn-all \
+ --warn-error \
+ --symbol-prefix=gelf_ \
+ --identifier-prefix=GElf \
+ --c-include="libgelf.h" \
+ $(NULL)
+GElf_1_0_gir_INCLUDES = Gio-2.0
+GElf_1_0_gir_FILES = $(libgelf_la_SOURCES)
diff --git a/Makefile.am b/Makefile.am
index f19a3f3..2c27782 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,6 +34,15 @@ privlibdir = $(pkglibdir)
privlib_LTLIBRARIES =
INSTALL_DATA_HOOKS =
+include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+
+girdir= $(pkgdatadir)/gir-1.0
+typelibdir= $(pkglibdir)/girepository-1.0
+
+gir_DATA = $(INTROSPECTION_GIRS)
+typelib_DATA = $(gir_DATA:.gir=.typelib)
+
libgsystem_srcpath := src/libgsystem
libgsystem_cflags = $(GIO_UNIX_CFLAGS) -I$(srcdir)/src/libgsystem
libgsystem_libs = $(GIO_UNIX_LIBS)
@@ -42,30 +51,8 @@ privlib_LTLIBRARIES += libgsystem.la
include Makefile-ostbuild.am
include Makefile-tests.am
-
-include $(INTROSPECTION_MAKEFILE)
-INTROSPECTION_GIRS = GSystem-1.0.gir
-
-GSystem-1.0.gir: libgsystem.la Makefile
-GSystem_1_0_gir_NAMESPACE = GSystem
-GSystem_1_0_gir_VERSION = 1.0
-GSystem_1_0_gir_LIBS = libgsystem.la
-GSystem_1_0_gir_CFLAGS = $(libgsystem_cflags)
-GSystem_1_0_gir_SCANNERFLAGS = \
- --warn-all \
- --warn-error \
- --symbol-prefix=gs_ \
- --identifier-prefix=GS \
- --c-include="libgsystem.h" \
- $(NULL)
-GSystem_1_0_gir_INCLUDES = Gio-2.0
-GSystem_1_0_gir_FILES = $(libgsystem_la_SOURCES)
-
-girdir= $(pkgdatadir)/gir-1.0
-typelibdir= $(pkglibdir)/girepository-1.0
-
-gir_DATA = $(INTROSPECTION_GIRS)
-typelib_DATA = $(gir_DATA:.gir=.typelib)
+include Makefile-libgelf.am
+include Makefile-gsystem-introspection.am
install-data-hook: $(INSTALL_DATA_HOOKS)
diff --git a/configure.ac b/configure.ac
index a29ac58..18b37af 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,8 +44,14 @@ AC_ARG_ENABLE(buildsystem,
enable_buildsystem=yes)
AM_CONDITIONAL(BUILDSYSTEM, test x$enable_buildsystem != xno)
-PKG_CHECK_MODULES(GIO_UNIX, [gio-unix-2.0 >= 2.34.0])
-GIO_UNIX_CFLAGS="$GIO_UNIX_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_34
-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_34"
+gio_unix_dep_version=2.34.0
+PKG_CHECK_MODULES(GIO_UNIX, [gio-unix-2.0 >= ${gio_unix_dep_version}])
+PKG_CHECK_MODULES(OSTBUILD_DEP, [gio-unix-2.0 >= ${gio_unix_dep_version}])
+
+AC_CHECK_HEADER([libelf.h],,[AC_MSG_ERROR(libelf.h is required)])
+
+AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, [GLIB_VERSION_2_34], [Define to GLib min version])
+AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, [GLIB_VERSION_2_34], [Define to GLib max version])
AC_CONFIG_FILES([
Makefile
diff --git a/src/libgelf/gelf-file.c b/src/libgelf/gelf-file.c
new file mode 100644
index 0000000..dc80c0d
--- /dev/null
+++ b/src/libgelf/gelf-file.c
@@ -0,0 +1,330 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright © 2013 Colin Walters <walters verbum org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2 of the licence or (at
+ * your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ */
+
+#include "config.h"
+
+#include "gelf-file.h"
+
+/**
+ * SECTION:gelffile
+ * @title: GElfFile
+ * @short_description: Read an ELF object
+ *
+ * This class provides a high-level API for inspecting ELF object
+ * files.
+ */
+
+#include "config.h"
+
+#include "gelf-file.h"
+
+#include "libelf.h"
+#include <gio/gfiledescriptorbased.h>
+
+#include <string.h>
+#include <glib-unix.h>
+
+static void initable_iface_init (GInitableIface *initable_iface);
+
+typedef GObjectClass GElfFileClass;
+
+struct _GElfFile
+{
+ GObject parent;
+
+ GFile *path;
+ GFileInputStream *stream;
+ Elf *elf;
+ Ebl *ebl;
+ guint shnum;
+ guint phnum;
+};
+
+G_DEFINE_TYPE_WITH_CODE (GElfFile, gelf_file, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init));
+
+enum
+{
+ PROP_0,
+ PROP_PATH,
+ N_PROPS
+};
+
+static GParamSpec *gelf_file_pspecs[N_PROPS];
+
+static void
+gelf_file_init (GElfFile *self)
+{
+}
+
+static void
+gelf_file_finalize (GObject *object)
+{
+ GElfFile *self = GELF_FILE (object);
+
+ if (self->elf)
+ elf_end (self->elf);
+ if (self->ebl)
+ ebl_closebackend (self->ebl);
+
+ g_clear_object (&self->path);
+ g_clear_object (&self->stream);
+
+ if (G_OBJECT_CLASS (gelf_file_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (gelf_file_parent_class)->finalize (object);
+}
+
+static void
+gelf_file_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GElfFile *self = GELF_FILE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PATH:
+ self->path = g_value_dup_object (value);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+gelf_file_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GElfFile *self = GELF_FILE (object);
+
+ switch (prop_id)
+ {
+ case PROP_PATH:
+ g_value_set_object (value, self->path);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+gelf_file_class_init (GElfFileClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ gobject_class->finalize = gelf_file_finalize;
+ gobject_class->get_property = gelf_file_get_property;
+ gobject_class->set_property = gelf_file_set_property;
+
+ gelf_file_pspecs[PROP_PATH] = g_param_spec_object ("path", "", "", G_TYPE_FILE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (gobject_class, N_PROPS, gelf_file_pspecs);
+}
+
+G_DEFINE_QUARK (gelf-error-quark, gelf_error)
+
+static void
+set_elf_error (Elf *elf,
+ GError **error)
+{
+ g_set_error_literal (error, GELF_ERROR, GELF_ERROR_INVALID,
+ elf_errmsg (elf_errno ()));
+}
+
+static gboolean
+initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GElfFile *self = GELF_FILE (initable);
+ gboolean ret = FALSE;
+ int fd;
+ Elf_Kind kind;
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return FALSE;
+
+ self->stream = g_file_read (self->path, cancellable, error);
+ if (!self->stream)
+ goto out;
+
+ (void) elf_version (EV_CURRENT);
+
+ g_assert (G_IS_FILE_DESCRIPTOR_BASED (self->stream));
+ fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*) self->stream);
+
+ self->elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+ if (!self->elf)
+ {
+ set_elf_error (self->elf, error);
+ goto out;
+ }
+
+ kind = elf_kind (self->elf);
+ if (kind != ELF_K_ELF)
+ {
+ g_set_error (error, GELF_ERROR, GELF_ERROR_NOT_ELF,
+ "Not an ELF file");
+ goto out;
+ }
+
+ self->ebl = ebl_openbackend (self->elf);
+
+ if (elf_getshdrnum (self->ebl->elf, &self->shnum) < 0)
+ {
+ set_elf_error (self->ebl->elf, error);
+ goto out;
+ }
+
+ if (elf_getphdrnum (self->ebl->elf, &self->phnum) < 0)
+ {
+ set_elf_error (self->ebl->elf, error);
+ goto out;
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+static void
+initable_iface_init (GInitableIface *initable_iface)
+{
+ initable_iface->init = initable_init;
+}
+
+/**
+ * gelf_file_new:
+ * @path: Path to ELF file
+ * @cancellable:
+ * @error:
+ *
+ * Create a new #GElfFile; will throw an error if @path is not ELF.
+ *
+ * Returns: (transfer full): A newly created %GElfFile, or %NULL on error (and @error will be set)
+ */
+GElfFile *
+gelf_file_new (GFile *path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return g_initable_new (GELF_TYPE_FILE,
+ cancellable, error,
+ "path", path,
+ NULL);
+}
+
+/**
+ * gelf_file_maybe_new:
+ * @path: Path to ELF file
+ * @cancellable:
+ * @error:
+ *
+ * Create a new #GElfFile; if @path is not ELF, then %NULL will be
+ * returned, and @error will not be set.
+ *
+ * Returns: (transfer full): A newly created %GElfFile, or %NULL on error (and @error will be set)
+ */
+GElfFile *
+gelf_file_maybe_new (GFile *path,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GError *tmp_error = NULL;
+ GElfFile *ret;
+
+ ret = g_initable_new (GELF_TYPE_FILE,
+ cancellable, &tmp_error,
+ "path", path,
+ NULL);
+ if (tmp_error != NULL)
+ {
+ if (g_error_matches (tmp_error, GELF_ERROR, GELF_ERROR_NOT_ELF))
+ g_clear_error (&tmp_error);
+ else
+ g_propagate_error (error, tmp_error);
+ }
+
+ return ret;
+}
+
+static
+
+/**
+ * gelf_file_get_build_id:
+ * @self:
+ * @out_build_id: (out) (allow-none): Build-Id, or %NULL if none found
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ */
+gboolean
+gelf_file_get_build_id (GElfFile *self,
+ char **out_build_id,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ char *ret_build_id = NULL;
+ Elf_Scn *scn = NULL;
+
+ if (self->shnum > 0)
+ {
+ size_t shstrndx;
+ if (elf_getshdrstrndx (self->ebl->elf, &shstrndx) < 0)
+ {
+ set_elf_error (self->ebl->elf, error);
+ goto out;
+ }
+ while ((scn = elf_nextscn (self->ebl->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ GElf_Off start;
+ Elf_Data *data;
+
+ if (shdr == NULL || shdr->sh_type != SHT_NOTE)
+ continue;
+
+ start = shdr->sh_offset;
+ data = elf_getdata (scn, NULL);
+
+ if (data == NULL)
+ continue;
+
+ }
+ }
+
+ out:
+ if (out_build_id)
+ *out_build_id = ret_build_id;
+ else
+ g_free (ret_build_id);
+ return ret;
+}
+
+/**
+ * gelf_file_get_dt_needed:
+ * @self:
+ *
+ * Returns: (transfer full) (element-type utf8): the list of DT_NEEDED entries
+ */
+GList *
+gelf_file_get_dt_needed (GElfFile *self)
+{
+ return NULL;
+}
diff --git a/src/libgelf/gelf-file.h b/src/libgelf/gelf-file.h
new file mode 100644
index 0000000..e73cbf5
--- /dev/null
+++ b/src/libgelf/gelf-file.h
@@ -0,0 +1,61 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2013 Colin Walters <walters verbum org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GELF_FILE_H__
+#define __GELF_FILE_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GELF_TYPE_FILE (gelf_file_get_type ())
+#define GELF_FILE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GELF_TYPE_FILE, GElfFile))
+#define GELF_IS_FILE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GELF_TYPE_FILE))
+
+typedef struct _GElfFile GElfFile;
+
+GQuark gelf_error_quark (void);
+
+#define GELF_ERROR (gelf_error_quark ())
+
+typedef enum {
+ GELF_ERROR_NOT_ELF = 1,
+ GELF_ERROR_INVALID
+} GElfError;
+
+GType gelf_file_get_type (void) G_GNUC_CONST;
+
+GElfFile * gelf_file_new (GFile *path,
+ GCancellable *cancellable,
+ GError **error);
+
+GElfFile * gelf_file_maybe_new (GFile *path,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean gelf_file_get_build_id (GElfFile *self,
+ char **out_build_id,
+ GError **error);
+
+GList * gelf_file_get_dt_needed (GElfFile *self);
+
+G_END_DECLS
+
+#endif
diff --git a/src/libgelf/libgelf.h b/src/libgelf/libgelf.h
new file mode 100644
index 0000000..5111dba
--- /dev/null
+++ b/src/libgelf/libgelf.h
@@ -0,0 +1,32 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2012 Colin Walters <walters verbum org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LIBGSYSTEM__
+#define __LIBGSYSTEM__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#include <gelf-file.h>
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]