aboutsummaryrefslogtreecommitdiff
path: root/libctf
diff options
context:
space:
mode:
Diffstat (limited to 'libctf')
-rw-r--r--libctf/ChangeLog6
-rw-r--r--libctf/ctf-impl.h33
-rw-r--r--libctf/ctf-util.c176
-rw-r--r--libctf/elf.h61
4 files changed, 276 insertions, 0 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 6a37212..7648c26 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,11 @@
2019-05-28 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-util.c: New file.
+ * elf.h: Likewise.
+ * ctf-impl.h: Include it, and add declarations.
+
+2019-05-28 Nick Alcock <nick.alcock@oracle.com>
+
* ctf-impl.h: New file.
* ctf-subr.c: New file.
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index 4356a2a..268b2f3 100644
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -24,6 +24,13 @@
#include <sys/errno.h>
#include <ctf-api.h>
#include <sys/types.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <limits.h>
+#include <ctype.h>
+#include <elf.h>
#ifdef __cplusplus
extern "C"
@@ -51,6 +58,25 @@ extern "C"
#endif
+typedef struct ctf_list
+{
+ struct ctf_list *l_prev; /* Previous pointer or tail pointer. */
+ struct ctf_list *l_next; /* Next pointer or head pointer. */
+} ctf_list_t;
+
+#define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
+#define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
+
+extern void ctf_list_append (ctf_list_t *, void *);
+extern void ctf_list_prepend (ctf_list_t *, void *);
+extern void ctf_list_delete (ctf_list_t *, void *);
+
+extern const char *ctf_strraw (ctf_file_t *, uint32_t);
+extern const char *ctf_strptr (ctf_file_t *, uint32_t);
+
+extern void *ctf_set_open_errno (int *, int);
+extern long ctf_set_errno (ctf_file_t *, int);
+
_libctf_malloc_
extern void *ctf_data_alloc (size_t);
extern void ctf_data_free (void *, size_t);
@@ -65,10 +91,17 @@ _libctf_malloc_
extern void *ctf_alloc (size_t);
extern void ctf_free (void *);
+_libctf_malloc_
+extern char *ctf_strdup (const char *);
+extern char *ctf_str_append (char *, const char *);
+extern const char *ctf_strerror (int);
+
_libctf_printflike_ (1, 2)
extern void ctf_dprintf (const char *, ...);
extern void libctf_init_debug (void);
+extern Elf64_Sym *ctf_sym_to_elf64 (const Elf32_Sym *src, Elf64_Sym *dst);
+
extern int _libctf_debug; /* debugging messages enabled */
#ifdef __cplusplus
diff --git a/libctf/ctf-util.c b/libctf/ctf-util.c
new file mode 100644
index 0000000..4460046
--- /dev/null
+++ b/libctf/ctf-util.c
@@ -0,0 +1,176 @@
+/* Miscellaneous utilities.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of libctf.
+
+ libctf 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, 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; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#include <ctf-impl.h>
+#include <string.h>
+
+/* Simple doubly-linked list append routine. This implementation assumes that
+ each list element contains an embedded ctf_list_t as the first member.
+ An additional ctf_list_t is used to store the head (l_next) and tail
+ (l_prev) pointers. The current head and tail list elements have their
+ previous and next pointers set to NULL, respectively. */
+
+void
+ctf_list_append (ctf_list_t *lp, void *newp)
+{
+ ctf_list_t *p = lp->l_prev; /* p = tail list element. */
+ ctf_list_t *q = newp; /* q = new list element. */
+
+ lp->l_prev = q;
+ q->l_prev = p;
+ q->l_next = NULL;
+
+ if (p != NULL)
+ p->l_next = q;
+ else
+ lp->l_next = q;
+}
+
+/* Prepend the specified existing element to the given ctf_list_t. The
+ existing pointer should be pointing at a struct with embedded ctf_list_t. */
+
+void
+ctf_list_prepend (ctf_list_t * lp, void *newp)
+{
+ ctf_list_t *p = newp; /* p = new list element. */
+ ctf_list_t *q = lp->l_next; /* q = head list element. */
+
+ lp->l_next = p;
+ p->l_prev = NULL;
+ p->l_next = q;
+
+ if (q != NULL)
+ q->l_prev = p;
+ else
+ lp->l_prev = p;
+}
+
+/* Delete the specified existing element from the given ctf_list_t. The
+ existing pointer should be pointing at a struct with embedded ctf_list_t. */
+
+void
+ctf_list_delete (ctf_list_t *lp, void *existing)
+{
+ ctf_list_t *p = existing;
+
+ if (p->l_prev != NULL)
+ p->l_prev->l_next = p->l_next;
+ else
+ lp->l_next = p->l_next;
+
+ if (p->l_next != NULL)
+ p->l_next->l_prev = p->l_prev;
+ else
+ lp->l_prev = p->l_prev;
+}
+
+/* Convert a 32-bit ELF symbol into Elf64 and return a pointer to it. */
+
+Elf64_Sym *
+ctf_sym_to_elf64 (const Elf32_Sym *src, Elf64_Sym *dst)
+{
+ dst->st_name = src->st_name;
+ dst->st_value = src->st_value;
+ dst->st_size = src->st_size;
+ dst->st_info = src->st_info;
+ dst->st_other = src->st_other;
+ dst->st_shndx = src->st_shndx;
+
+ return dst;
+}
+
+/* Convert an encoded CTF string name into a pointer to a C string by looking
+ up the appropriate string table buffer and then adding the offset. */
+
+const char *
+ctf_strraw (ctf_file_t *fp, uint32_t name)
+{
+ ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID (name)];
+
+ if (ctsp->cts_strs != NULL && CTF_NAME_OFFSET (name) < ctsp->cts_len)
+ return (ctsp->cts_strs + CTF_NAME_OFFSET (name));
+
+ /* String table not loaded or corrupt offset. */
+ return NULL;
+}
+
+const char *
+ctf_strptr (ctf_file_t *fp, uint32_t name)
+{
+ const char *s = ctf_strraw (fp, name);
+ return (s != NULL ? s : "(?)");
+}
+
+/* Same as strdup(3C), but use ctf_alloc() to do the memory allocation. */
+
+_libctf_malloc_ char *
+ctf_strdup (const char *s1)
+{
+ char *s2 = ctf_alloc (strlen (s1) + 1);
+
+ if (s2 != NULL)
+ (void) strcpy (s2, s1);
+
+ return s2;
+}
+
+/* A string appender working on dynamic strings. */
+
+char *
+ctf_str_append (char *s, const char *append)
+{
+ size_t s_len = 0;
+
+ if (append == NULL)
+ return s;
+
+ if (s != NULL)
+ s_len = strlen (s);
+
+ size_t append_len = strlen (append);
+
+ if ((s = realloc (s, s_len + append_len + 1)) == NULL)
+ return NULL;
+
+ memcpy (s + s_len, append, append_len);
+ s[s_len + append_len] = '\0';
+
+ return s;
+}
+
+/* Store the specified error code into errp if it is non-NULL, and then
+ return NULL for the benefit of the caller. */
+
+void *
+ctf_set_open_errno (int *errp, int error)
+{
+ if (errp != NULL)
+ *errp = error;
+ return NULL;
+}
+
+/* Store the specified error code into the CTF container, and then return
+ CTF_ERR for the benefit of the caller. */
+
+long
+ctf_set_errno (ctf_file_t * fp, int err)
+{
+ fp->ctf_errno = err;
+ return CTF_ERR;
+}
diff --git a/libctf/elf.h b/libctf/elf.h
new file mode 100644
index 0000000..fee1630
--- /dev/null
+++ b/libctf/elf.h
@@ -0,0 +1,61 @@
+/* This file defines standard ELF types, structures, and macros.
+ Copyright (C) 1995-2019 Free Software Foundation, Inc.
+
+ This file is part of libctf.
+
+ libctf 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, 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; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _CTF_ELF_H
+#define _CTF_ELF_H
+
+#include "config.h"
+#include "ansidecl.h"
+#include <stdint.h>
+#include "elf/common.h"
+#include "elf/external.h"
+
+typedef uint32_t Elf32_Word;
+typedef uint32_t Elf64_Word;
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Xword;
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+#define SHN_EXTABS 0xFFF1 /* Associated symbol is absolute */
+
+/* Symbol table entry. */
+
+typedef struct
+{
+ Elf32_Word st_name; /* Symbol name (string tbl index) */
+ Elf32_Addr st_value; /* Symbol value */
+ Elf32_Word st_size; /* Symbol size */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf32_Section st_shndx; /* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+ Elf64_Word st_name; /* Symbol name (string tbl index) */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf64_Section st_shndx; /* Section index */
+ Elf64_Addr st_value; /* Symbol value */
+ Elf64_Xword st_size; /* Symbol size */
+} Elf64_Sym;
+
+#endif /* _CTF_ELF_H */