[sysprof] kallsyms: add API to extract kallsyms with strtok_r()
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] kallsyms: add API to extract kallsyms with strtok_r()
- Date: Mon, 29 Jan 2018 06:17:31 +0000 (UTC)
commit 26343e3d2a59a890c52275eb1761d8fb07494f20
Author: Christian Hergert <chergert redhat com>
Date: Sun Jan 28 21:26:17 2018 -0800
kallsyms: add API to extract kallsyms with strtok_r()
This will allow us to simplify some code, and provide an API in both
the lib and daemon to get symbols while sharing code.
lib/meson.build | 2 +
lib/sp-kallsyms.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/sp-kallsyms.h | 41 +++++++++++++++
3 files changed, 191 insertions(+), 0 deletions(-)
---
diff --git a/lib/meson.build b/lib/meson.build
index d02d9f3..5f9f2a5 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -28,12 +28,14 @@ libsysprof_base_headers = [
'sp-address.h',
'sp-clock.h',
'sp-error.h',
+ 'sp-kallsyms.h',
]
libsysprof_base_sources = [
'sp-address.c',
'sp-clock.c',
'sp-error.c',
+ 'sp-kallsyms.c',
]
libsysprof_headers = libsysprof_base_headers
diff --git a/lib/sp-kallsyms.c b/lib/sp-kallsyms.c
new file mode 100644
index 0000000..3e799cb
--- /dev/null
+++ b/lib/sp-kallsyms.c
@@ -0,0 +1,148 @@
+/* sp-kallsyms.c
+ *
+ * Copyright © 2018 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "sp-kallsyms"
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "sp-kallsyms.h"
+
+struct _SpKallsyms
+{
+ gchar *buf;
+ gsize buflen;
+ gchar *endptr;
+ gchar *iter;
+};
+
+void
+sp_kallsyms_free (SpKallsyms *self)
+{
+ if (self != NULL)
+ {
+ g_clear_pointer (&self->buf, g_free);
+ g_slice_free (SpKallsyms, self);
+ }
+}
+
+SpKallsyms *
+sp_kallsyms_new (void)
+{
+ g_autoptr(SpKallsyms) self = NULL;
+
+ self = g_slice_new0 (SpKallsyms);
+
+ if (!g_file_get_contents ("/proc/kallsyms", &self->buf, &self->buflen, NULL))
+ return NULL;
+
+ self->iter = self->buf;
+ self->endptr = self->buf + self->buflen;
+
+ return g_steal_pointer (&self);
+}
+
+gboolean
+sp_kallsyms_next (SpKallsyms *self,
+ const gchar **name,
+ guint64 *address,
+ guint8 *type)
+{
+ guint64 addr;
+ char *tok;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (self->buf != NULL, FALSE);
+ g_return_val_if_fail (self->buflen > 0, FALSE);
+ g_return_val_if_fail (self->iter != NULL, FALSE);
+ g_return_val_if_fail (self->endptr != NULL, FALSE);
+
+try_next:
+
+ if (self->iter >= self->endptr)
+ return FALSE;
+
+ tok = strtok_r (self->iter, " \t\n", &self->iter);
+ if (!tok || *tok == 0)
+ return FALSE;
+
+ if (*tok == '[')
+ {
+ tok = strtok_r (self->iter, " \t\n", &self->iter);
+ if (!tok || *tok == 0)
+ return FALSE;
+ }
+
+ addr = g_ascii_strtoull (tok, NULL, 10);
+ if ((addr == G_MAXUINT64 && errno == ERANGE) ||
+ (addr == 0 && errno == EINVAL))
+ return FALSE;
+
+ *address = addr;
+
+ if (self->iter >= self->endptr)
+ return FALSE;
+
+ tok = strtok_r (self->iter, " \t\n", &self->iter);
+ if (!tok || *tok == 0)
+ return FALSE;
+
+ switch (*tok)
+ {
+ case 'A':
+ case 'B':
+ case 'D':
+ case 'R':
+ case 'T':
+ case 'V':
+ case 'W':
+ case 'a':
+ case 'b':
+ case 'd':
+ case 'r':
+ case 't':
+ case 'w':
+ *type = *tok;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (self->iter >= self->endptr)
+ return FALSE;
+
+ tok = strtok_r (self->iter, " \t\n", &self->iter);
+ if (!tok || *tok == 0)
+ return FALSE;
+
+ if (self->iter >= self->endptr)
+ return FALSE;
+
+ if (g_strcmp0 (tok, "(null)") == 0)
+ goto try_next;
+
+ *name = tok;
+
+ return TRUE;
+}
diff --git a/lib/sp-kallsyms.h b/lib/sp-kallsyms.h
new file mode 100644
index 0000000..76b7a62
--- /dev/null
+++ b/lib/sp-kallsyms.h
@@ -0,0 +1,41 @@
+/* sp-kallsyms.h
+ *
+ * Copyright © 2018 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SP_KALLSYMS_H
+#define SP_KALLSYMS_H
+
+#include <gio/gio.h>
+
+#include "sp-kallsyms.h"
+
+G_BEGIN_DECLS
+
+typedef struct _SpKallsyms SpKallsyms;
+
+SpKallsyms *sp_kallsyms_new (void);
+gboolean sp_kallsyms_next (SpKallsyms *self,
+ const gchar **name,
+ guint64 *address,
+ guint8 *type);
+void sp_kallsyms_free (SpKallsyms *self);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (SpKallsyms, sp_kallsyms_free)
+
+G_END_DECLS
+
+#endif /* SP_KALLSYMS_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]