type.h revision 2bea8615d97097a334449ee95112c8a59277103e
1/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
4 * Copyright (C) 1997-2009 Juan Cespedes
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 */
21
22#ifndef TYPE_H
23#define TYPE_H
24
25#include <stddef.h>
26#include "forward.h"
27#include "vect.h"
28
29enum arg_type {
30	ARGTYPE_UNKNOWN = -1,
31	ARGTYPE_VOID,
32	ARGTYPE_INT,
33	ARGTYPE_UINT,
34	ARGTYPE_LONG,
35	ARGTYPE_ULONG,
36	ARGTYPE_OCTAL,
37	ARGTYPE_CHAR,
38	ARGTYPE_SHORT,
39	ARGTYPE_USHORT,
40	ARGTYPE_FLOAT,		/* float value, may require index */
41	ARGTYPE_DOUBLE,		/* double value, may require index */
42	ARGTYPE_FORMAT,		/* printf-like format */
43	ARGTYPE_STRING_N,	/* String of known maxlen */
44	ARGTYPE_ARRAY,		/* Series of values in memory */
45	ARGTYPE_ENUM,		/* Enumeration */
46	ARGTYPE_STRUCT,		/* Structure of values */
47	ARGTYPE_POINTER,	/* Pointer to some other type */
48	ARGTYPE_COUNT		/* number of ARGTYPE_* values */
49};
50
51struct arg_type_info {
52	enum arg_type type;
53	union {
54		struct vect entries;
55
56		/* ARGTYPE_ENUM */
57		struct {
58			size_t entries;
59			char **keys;
60			int *values;
61		} enum_info;
62
63		/* ARGTYPE_ARRAY */
64		struct {
65			struct arg_type_info *elt_type;
66			struct expr_node *length;
67			int own_info:1;
68			int own_length:1;
69		} array_info;
70
71		/* ARGTYPE_STRING_N */
72		struct {
73			struct expr_node *length;
74			int own_length:1;
75		} string_n_info;
76
77		/* ARGTYPE_POINTER */
78		struct {
79			struct arg_type_info *info;
80			int own_info:1;
81		} ptr_info;
82
83		/* ARGTYPE_FLOAT */
84		struct {
85			size_t float_index;
86		} float_info;
87
88		/* ARGTYPE_DOUBLE */
89		struct {
90			size_t float_index;
91		} double_info;
92	} u;
93};
94
95/* Return a type info for simple type TYPE (which shall not be array,
96 * struct, enum or pointer.  Each call with the same TYPE yields the
97 * same arg_type_info pointer.  */
98struct arg_type_info *type_get_simple(enum arg_type type);
99
100/* Initialize INFO so it becomes ARGTYPE_ENUM.  Returns 0 on success
101 * or negative value on failure.  */
102void type_init_enum(struct arg_type_info *info);
103
104/* Push another member of the enumeration, named KEY, with given
105 * VALUE.  If OWN_KEY, KEY is owned and released after the type is
106 * destroyed.  KEY is typed as const char *, but note that if
107 * OWN_KEY, this value will be freed.  */
108int type_enum_add(struct arg_type_info *info,
109		  const char *key, int own_key, int value);
110
111/* Return number of enum elements of type INFO.  */
112size_t type_enum_size(struct arg_type_info *info);
113
114/* Look up enum key with given VALUE in INFO.  */
115const char *type_enum_get(struct arg_type_info *info, int value);
116
117/* Initialize INFO so it becomes ARGTYPE_STRUCT.  The created
118 * structure contains no fields.  Use type_struct_add to populate the
119 * structure.  */
120void type_init_struct(struct arg_type_info *info);
121
122/* Add a new field of type FIELD_INFO to a structure INFO.  If OWN,
123 * the field type is owned and destroyed together with INFO.  */
124int type_struct_add(struct arg_type_info *info,
125		    struct arg_type_info *field_info, int own);
126
127/* Get IDX-th field of structure type INFO.  */
128struct arg_type_info *type_struct_get(struct arg_type_info *info, size_t idx);
129
130/* Return number of fields of structure type INFO.  */
131size_t type_struct_size(struct arg_type_info *info);
132
133/* Initialize INFO so it becomes ARGTYPE_ARRAY.  The element type is
134 * passed in ELEMENT_INFO, and array length in LENGTH_EXPR.  If,
135 * respectively, OWN_INFO and OWN_LENGTH are true, the pointee and
136 * length are owned and destroyed together with INFO.  */
137void type_init_array(struct arg_type_info *info,
138		     struct arg_type_info *element_info, int own_info,
139		     struct expr_node *length, int own_length);
140
141/* Initialize INFO so it becomes ARGTYPE_STRING_N.  Length is passed
142 * in LENGTH_EXPR.  If OWN_LENGTH is true, the length is owned and
143 * destroyed together with INFO.  */
144void type_init_string(struct arg_type_info *info,
145		      struct expr_node *length, int own_length);
146
147/* Initialize INFO so it becomes ARGTYPE_POINTER.  The pointee type is
148 * passed in POINTEE_INFO.  If OWN_INFO, the pointee type is owned and
149 * destroyed together with INFO.  */
150void type_init_pointer(struct arg_type_info *info,
151		       struct arg_type_info *pointee_info, int own_info);
152
153/* Release any memory associated with INFO.  Doesn't free INFO
154 * itself.  */
155void type_destroy(struct arg_type_info *info);
156
157/* Compute a size of given type.  Return (size_t)-1 for error.  */
158size_t type_sizeof(struct Process *proc, struct arg_type_info *type);
159
160/* Compute an alignment necessary for elements of this type.  Return
161 * (size_t)-1 for error.  */
162size_t type_alignof(struct Process *proc, struct arg_type_info *type);
163
164/* Align value SZ to ALIGNMENT and return the result.  */
165size_t align(size_t sz, size_t alignment);
166
167/* Return ELT-th element of compound type TYPE.  This is useful for
168 * arrays and structures.  */
169struct arg_type_info *type_element(struct arg_type_info *type, size_t elt);
170
171/* Compute an offset of EMT-th element of type TYPE.  This works for
172 * arrays and structures.  Return (size_t)-1 for error.  */
173size_t type_offsetof(struct Process *proc,
174		     struct arg_type_info *type, size_t elt);
175
176struct arg_type_info *lookup_prototype(enum arg_type at);
177
178#endif /* TYPE_H */
179