diff options
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ChangeLog | 6 | ||||
-rw-r--r-- | libctf/ctf-impl.h | 33 | ||||
-rw-r--r-- | libctf/ctf-util.c | 176 | ||||
-rw-r--r-- | libctf/elf.h | 61 |
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 */ |