public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Nick Alcock <nick.alcock@oracle.com>
To: binutils@sourceware.org
Subject: [PATCH 04/19] libctf: low-level list manipulation and helper utilities
Date: Tue, 30 Apr 2019 22:57:00 -0000	[thread overview]
Message-ID: <20190430225706.159422-5-nick.alcock@oracle.com> (raw)
In-Reply-To: <20190430225706.159422-1-nick.alcock@oracle.com>

These utilities are a bit of a ragbag of small things needed by more
than one TU: list manipulation, ELF32->64 translators, routines to look
up strings in string tables, dynamically-allocated string appenders, and
routines to set the specialized errno values previously committed in
<ctf-api.h>.

Notes for reviewers:

The distinction betweern this file and ctf-subr.c is lost in the mists
of time: perhaps it was originally that ctf-subr.c contained nothing but
wrappers.  I am quite amenable to combining the two, and also to
splitting the errno-setting stuff out into ctf-error.c with the error
fetchers.

libctf/
	* ctf-util.c: New file.
	* ctf-impl.h: Add definitions.
---
 libctf/ctf-impl.h |  32 +++++++++
 libctf/ctf-util.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 208 insertions(+)
 create mode 100644 libctf/ctf-util.c

diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index 108c89d2c5..d4d71fbfdc 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 <gelf.h>
 
 #ifdef	__cplusplus
 extern "C"
@@ -52,6 +59,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 ctf_file_t *ctf_set_open_errno (int *, int);
+extern long ctf_set_errno (ctf_file_t *, int);
+
 extern void *ctf_data_alloc (size_t);
 extern void ctf_data_free (void *, size_t);
 extern void ctf_data_protect (void *, size_t);
@@ -59,9 +85,15 @@ extern void ctf_data_protect (void *, size_t);
 extern void *ctf_alloc (size_t);
 extern void ctf_free (void *, size_t);
 
+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 Elf64_Sym *ctf_sym_to_gelf (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 0000000000..a3a8d05dd3
--- /dev/null
+++ b/libctf/ctf-util.c
@@ -0,0 +1,176 @@
+/* Miscellaneous utilities.
+   Copyright (C) 2005-2018 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 2, 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 *new)
+{
+  ctf_list_t *p = lp->l_prev;	/* p = tail list element.  */
+  ctf_list_t *q = new;		/* 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 *new)
+{
+  ctf_list_t *p = new;		/* 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 GElf (Elf64) and return a pointer to it.  */
+
+Elf64_Sym *
+ctf_sym_to_gelf (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. */
+
+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.  */
+
+ctf_file_t *
+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;
+}
-- 
2.21.0.237.gd0cfaa883d

  parent reply	other threads:[~2019-04-30 22:57 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-30 22:57 [PATCH 00/19] libctf, and CTF support for objdump and readelf Nick Alcock
2019-04-30 22:57 ` [PATCH 10/19] libctf: ELF file opening Nick Alcock
2019-04-30 22:57 ` [PATCH 06/19] libctf: hashing Nick Alcock
2019-05-02 16:16   ` Nick Clifton
2019-05-03 19:33     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 09/19] libctf: opening Nick Alcock
2019-04-30 22:57 ` [PATCH 15/19] libctf: mmappable archives Nick Alcock
2019-04-30 22:57 ` [PATCH 01/19] include: new header ctf.h: file format description Nick Alcock
2019-05-01 16:57   ` Nick Clifton
2019-05-01 21:29     ` Jim Wilson
2019-05-03 11:15       ` Nick Alcock
2019-04-30 22:57 ` [PATCH 13/19] libctf: type copying Nick Alcock
2019-04-30 22:57 ` [PATCH 05/19] libctf: error handling Nick Alcock
2019-05-02 16:10   ` Nick Clifton
2019-05-03 19:31     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 02/19] include: new header ctf-api.h Nick Alcock
2019-05-02 15:07   ` Nick Clifton
2019-05-03 11:23     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 08/19] libctf: creation functions Nick Alcock
2019-04-30 22:57 ` CTF format overview Nick Alcock
2019-04-30 22:57 ` [PATCH 19/19] binutils: CTF support for objdump and readelf Nick Alcock
2019-04-30 22:57 ` Nick Alcock [this message]
2019-05-02 16:04   ` [PATCH 04/19] libctf: low-level list manipulation and helper utilities Nick Clifton
2019-05-03 19:25     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 11/19] libctf: core type lookup Nick Alcock
2019-04-30 22:57 ` [PATCH 12/19] libctf: lookups by name and symbol Nick Alcock
2019-04-30 22:57 ` [PATCH 03/19] libctf: lowest-level memory allocation and debug-dumping wrappers Nick Alcock
2019-05-02 15:29   ` Nick Clifton
2019-05-03 19:12     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 14/19] libctf: library version enforcement Nick Alcock
2019-04-30 22:58 ` [PATCH 18/19] libctf: build system Nick Alcock
2019-05-01  0:13 ` [PATCH 17/19] libctf: debug dumping Nick Alcock
2019-05-01  0:19 ` [PATCH 16/19] libctf: labels Nick Alcock
2019-05-01  1:57 ` [PATCH 07/19] libctf: implementation definitions related to file creation Nick Alcock
2019-05-01 16:02 ` [PATCH 00/19] libctf, and CTF support for objdump and readelf Nick Clifton
2019-05-01 16:16   ` Jose E. Marchesi
2019-05-03 10:47     ` Nick Alcock
2019-05-02 15:22 ` Joseph Myers
2019-05-03 12:33   ` Nick Clifton
2019-05-06 16:40     ` Nick Alcock
2019-05-08 14:34     ` Michael Matz
2019-05-08 16:01       ` Nick Clifton
2019-05-08 16:20         ` Nick Alcock
2019-05-03 14:23   ` Nick Alcock
     [not found]     ` <alpine.DEB.2.21.1905072117440.19308@digraph.polyomino.org.uk>
2019-05-08 11:39       ` Nick Alcock
2019-05-24  8:57     ` Pedro Alves
2019-05-24 16:05       ` Nick Alcock
2019-05-24 16:19         ` Pedro Alves
2019-05-24 20:09           ` Nick Alcock
2019-05-03 16:19 ` Florian Weimer
2019-05-03 19:45   ` Nick Alcock
2019-05-06 12:07     ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190430225706.159422-5-nick.alcock@oracle.com \
    --to=nick.alcock@oracle.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).