#include <ctype.h>
#include <elf.h>
#include <bfd.h>
+#include "hashtab.h"
#ifdef __cplusplus
extern "C"
- {
+{
#endif
/* Compiler attributes. */
#define _libctf_unused_ __attribute__ ((__unused__))
#define _libctf_malloc_ __attribute__((__malloc__))
+#else
+
+#define _libctf_printflike_(string_index,first_to_check)
+#define _libctf_unlikely_(x) (x)
+#define _libctf_unused_
+#define _libctf_malloc_
+#define __extension__
+
#endif
+#define ctf_assert(fp, expr) \
+ _libctf_unlikely_ (ctf_assert_internal (fp, __FILE__, __LINE__, \
+ #expr, !!(expr)))
+
/* libctf in-memory state. */
typedef struct ctf_fixed_hash ctf_hash_t; /* Private to ctf-hash.c. */
typedef struct ctf_dynhash ctf_dynhash_t; /* Private to ctf-hash.c. */
+typedef struct ctf_dynset ctf_dynset_t; /* Private to ctf-hash.c. */
typedef struct ctf_strs
{
ctf_list_t dtu_members; /* struct, union, or enum */
ctf_arinfo_t dtu_arr; /* array */
ctf_encoding_t dtu_enc; /* integer or float */
- ctf_id_t *dtu_argv; /* function */
+ uint32_t *dtu_argv; /* function */
ctf_slice_t dtu_slice; /* slice */
} dtd_u;
} ctf_dtdef_t;
ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any). */
} ctf_bundle_t;
+typedef struct ctf_err_warning
+{
+ ctf_list_t cew_list; /* List forward/back pointers. */
+ int cew_is_warning; /* 1 if warning, 0 if error. */
+ char *cew_text; /* Error/warning text. */
+} ctf_err_warning_t;
+
/* Atoms associate strings with a list of the CTF items that reference that
string, so that ctf_update() can instantiate all the strings using the
ctf_str_atoms and then reassociate them with the real string later.
uint32_t *caf_ref; /* A single ref to this string. */
} ctf_str_atom_ref_t;
-/* The structure used as the key in a ctf_link_type_mapping, which lets the
- linker machinery determine which type IDs on the input side of a link map to
- which types on the output side. (The value is a ctf_id_t: another
- index, not a type.) */
+/* The structure used as the key in a ctf_link_type_mapping. The value is a
+ type index, not a type ID. */
-typedef struct ctf_link_type_mapping_key
+typedef struct ctf_link_type_key
{
- ctf_file_t *cltm_fp;
- ctf_id_t cltm_idx;
-} ctf_link_type_mapping_key_t;
+ ctf_file_t *cltk_fp;
+ ctf_id_t cltk_idx;
+} ctf_link_type_key_t;
+
/* The ctf_file is the structure used to represent a CTF container to library
clients, who see it only as an opaque pointer. Modifications can therefore
const char *ctf_cuname; /* Compilation unit name (if any). */
char *ctf_dyncuname; /* Dynamically allocated name of CU. */
struct ctf_file *ctf_parent; /* Parent CTF container (if any). */
+ int ctf_parent_unreffed; /* Parent set by ctf_import_unref? */
const char *ctf_parlabel; /* Label in parent container (if any). */
const char *ctf_parname; /* Basename of parent (if any). */
char *ctf_dynparname; /* Dynamically allocated name of parent. */
unsigned long ctf_snapshots; /* ctf_snapshot() plus ctf_update() count. */
unsigned long ctf_snapshot_lu; /* ctf_snapshot() call count at last update. */
ctf_archive_t *ctf_archive; /* Archive this ctf_file_t came from. */
+ ctf_list_t ctf_errs_warnings; /* CTF errors and warnings. */
ctf_dynhash_t *ctf_link_inputs; /* Inputs to this link. */
ctf_dynhash_t *ctf_link_outputs; /* Additional outputs from this link. */
ctf_dynhash_t *ctf_link_type_mapping; /* Map input types to output types. */
struct ctf_archive_internal
{
int ctfi_is_archive;
+ int ctfi_unmap_on_close;
ctf_file_t *ctfi_file;
struct ctf_archive *ctfi_archive;
ctf_sect_t ctfi_symsect;
ctf_sect_t ctfi_strsect;
int ctfi_free_symsect;
+ int ctfi_free_strsect;
void *ctfi_data;
bfd *ctfi_abfd; /* Optional source of section data. */
void (*ctfi_bfd_close) (struct ctf_archive_internal *);
};
+/* Iterator state for the *_next() functions. */
+
+/* A single hash key/value pair. */
+typedef struct ctf_next_hkv
+{
+ void *hkv_key;
+ void *hkv_value;
+} ctf_next_hkv_t;
+
+struct ctf_next
+{
+ void (*ctn_iter_fun) (void);
+ ctf_id_t ctn_type;
+ ssize_t ctn_size;
+ ssize_t ctn_increment;
+ uint32_t ctn_n;
+ /* We can save space on this side of things by noting that a container is
+ either dynamic or not, as a whole, and a given iterator can only iterate
+ over one kind of thing at once: so we can overlap the DTD and non-DTD
+ members, and the structure, variable and enum members, etc. */
+ union
+ {
+ const ctf_member_t *ctn_mp;
+ const ctf_lmember_t *ctn_lmp;
+ const ctf_dmdef_t *ctn_dmd;
+ const ctf_enum_t *ctn_en;
+ const ctf_dvdef_t *ctn_dvd;
+ ctf_next_hkv_t *ctn_sorted_hkv;
+ void **ctn_hash_slot;
+ } u;
+ /* This union is of various sorts of container we can iterate over:
+ currently dictionaries and archives, dynhashes, and dynsets. */
+ union
+ {
+ const ctf_file_t *ctn_fp;
+ const ctf_archive_t *ctn_arc;
+ const ctf_dynhash_t *ctn_h;
+ const ctf_dynset_t *ctn_s;
+ } cu;
+};
+
/* Return x rounded up to an alignment boundary.
eg, P2ROUNDUP(0x1234, 0x100) == 0x1300 (0x13*align)
eg, P2ROUNDUP(0x5600, 0x100) == 0x5600 (0x56*align) */
#define LCTF_VBYTES(fp, kind, size, vlen) \
((fp)->ctf_fileops->ctfo_get_vbytes(kind, size, vlen))
-static inline ssize_t ctf_get_ctt_size (const ctf_file_t *fp,
- const ctf_type_t *tp,
- ssize_t *sizep,
- ssize_t *incrementp)
-{
- return (fp->ctf_fileops->ctfo_get_ctt_size (fp, tp, sizep, incrementp));
-}
-
#define LCTF_CHILD 0x0001 /* CTF container is a child */
#define LCTF_RDWR 0x0002 /* CTF container is writable */
#define LCTF_DIRTY 0x0004 /* CTF container has been modified */
extern ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *, ctf_names_t *, const char *);
extern void ctf_set_ctl_hashes (ctf_file_t *);
+extern ctf_file_t *ctf_get_dict (ctf_file_t *fp, ctf_id_t type);
+
typedef unsigned int (*ctf_hash_fun) (const void *ptr);
extern unsigned int ctf_hash_integer (const void *ptr);
extern unsigned int ctf_hash_string (const void *ptr);
-extern unsigned int ctf_hash_type_mapping_key (const void *ptr);
+extern unsigned int ctf_hash_type_key (const void *ptr);
typedef int (*ctf_hash_eq_fun) (const void *, const void *);
extern int ctf_hash_eq_integer (const void *, const void *);
extern int ctf_hash_eq_string (const void *, const void *);
-extern int ctf_hash_eq_type_mapping_key (const void *, const void *);
+extern int ctf_hash_eq_type_key (const void *, const void *);
+
+extern int ctf_dynset_eq_string (const void *, const void *);
typedef void (*ctf_hash_free_fun) (void *);
typedef void (*ctf_hash_iter_f) (void *key, void *value, void *arg);
typedef int (*ctf_hash_iter_remove_f) (void *key, void *value, void *arg);
+typedef int (*ctf_hash_iter_find_f) (void *key, void *value, void *arg);
+typedef int (*ctf_hash_sort_f) (const ctf_next_hkv_t *, const ctf_next_hkv_t *,
+ void *arg);
extern ctf_hash_t *ctf_hash_create (unsigned long, ctf_hash_fun, ctf_hash_eq_fun);
extern int ctf_hash_insert_type (ctf_hash_t *, ctf_file_t *, uint32_t, uint32_t);
ctf_hash_free_fun, ctf_hash_free_fun);
extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *);
extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *);
+extern size_t ctf_dynhash_elements (ctf_dynhash_t *);
extern void ctf_dynhash_empty (ctf_dynhash_t *);
extern void *ctf_dynhash_lookup (ctf_dynhash_t *, const void *);
+extern int ctf_dynhash_lookup_kv (ctf_dynhash_t *, const void *key,
+ const void **orig_key, void **value);
extern void ctf_dynhash_destroy (ctf_dynhash_t *);
extern void ctf_dynhash_iter (ctf_dynhash_t *, ctf_hash_iter_f, void *);
extern void ctf_dynhash_iter_remove (ctf_dynhash_t *, ctf_hash_iter_remove_f,
void *);
+extern void *ctf_dynhash_iter_find (ctf_dynhash_t *, ctf_hash_iter_find_f,
+ void *);
+extern int ctf_dynhash_next (ctf_dynhash_t *, ctf_next_t **,
+ void **key, void **value);
+extern int ctf_dynhash_next_sorted (ctf_dynhash_t *, ctf_next_t **,
+ void **key, void **value, ctf_hash_sort_f,
+ void *);
+
+extern ctf_dynset_t *ctf_dynset_create (htab_hash, htab_eq, ctf_hash_free_fun);
+extern int ctf_dynset_insert (ctf_dynset_t *, void *);
+extern void ctf_dynset_remove (ctf_dynset_t *, const void *);
+extern void ctf_dynset_destroy (ctf_dynset_t *);
+extern void *ctf_dynset_lookup (ctf_dynset_t *, const void *);
+extern int ctf_dynset_exists (ctf_dynset_t *, const void *key,
+ const void **orig_key);
+extern int ctf_dynset_next (ctf_dynset_t *, ctf_next_t **, void **key);
+extern void *ctf_dynset_lookup_any (ctf_dynset_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_str_purge_refs (ctf_file_t *);
extern ctf_strs_writable_t ctf_str_write_strtab (ctf_file_t *);
-extern struct ctf_archive_internal *ctf_new_archive_internal
- (int is_archive, struct ctf_archive *arc,
- ctf_file_t *fp, const ctf_sect_t *symsect,
- const ctf_sect_t *strsect, int *errp);
+extern struct ctf_archive_internal *
+ctf_new_archive_internal (int is_archive, int unmap_on_close,
+ struct ctf_archive *, ctf_file_t *,
+ const ctf_sect_t *symsect,
+ const ctf_sect_t *strsect, int *errp);
extern struct ctf_archive *ctf_arc_open_internal (const char *, int *);
extern void ctf_arc_close_internal (struct ctf_archive *);
extern void *ctf_set_open_errno (int *, int);
extern ctf_file_t *ctf_bufopen_internal (const ctf_sect_t *, const ctf_sect_t *,
const ctf_sect_t *, ctf_dynhash_t *,
int, int *);
+extern int ctf_import_unref (ctf_file_t *fp, ctf_file_t *pfp);
extern int ctf_serialize (ctf_file_t *);
_libctf_malloc_
extern void *ctf_realloc (ctf_file_t *, void *, size_t);
extern char *ctf_str_append (char *, const char *);
extern char *ctf_str_append_noerr (char *, const char *);
-extern const char *ctf_strerror (int);
extern ctf_id_t ctf_type_resolve_unsliced (ctf_file_t *, ctf_id_t);
extern int ctf_type_kind_unsliced (ctf_file_t *, ctf_id_t);
extern void ctf_dprintf (const char *, ...);
extern void libctf_init_debug (void);
+_libctf_printflike_ (3, 4)
+extern void ctf_err_warn (ctf_file_t *, int is_warning, const char *, ...);
+extern void ctf_assert_fail_internal (ctf_file_t *, const char *,
+ size_t, const char *);
+
extern Elf64_Sym *ctf_sym_to_elf64 (const Elf32_Sym *src, Elf64_Sym *dst);
extern const char *ctf_lookup_symbol_name (ctf_file_t *fp, unsigned long symidx);
extern int _libctf_version; /* library client version */
extern int _libctf_debug; /* debugging messages enabled */
+#include "ctf-inlines.h"
+
#ifdef __cplusplus
}
#endif