Remove some #if __cplusplus wrt inlining. (#18891)
[mono-project.git] / mono / dis / declsec.c
blobc2aa2a6ea3e21723eef9dc7829fc4808c202726d
1 /*
2 * declsec.h: Support for the new declarative security attribute
3 * metadata format (2.0)
5 * Author:
6 * Sebastien Pouliot <sebastien@ximian.com>
8 * Copyright (C) 2005 Novell, Inc (http://www.novell.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #include <glib.h>
13 #include <math.h>
15 #include "mono/metadata/blob.h"
16 #include "mono/metadata/metadata.h"
17 #include "mono/metadata/mono-endian.h"
18 #include "mono/utils/mono-compiler.h"
19 #include "mono/utils/mono-math.h"
21 #include "declsec.h"
22 #include "util.h"
24 static char*
25 declsec_20_get_classname (const char* p, const char **rptr)
27 int apos, cpos = 0;
28 char *c;
29 char *a;
30 char *result;
31 GString *res = g_string_new ("");
32 int len = mono_metadata_decode_value (p, &p);
34 c = (char *) p;
35 while ((*c++ != ',') && (cpos++ < len));
36 c++;
38 apos = cpos;
39 a = c;
40 while ((*a++ != ',') && (apos++ < len));
42 if (apos - cpos > 1) {
43 g_string_append_printf (res, "[%.*s]%.*s", apos - cpos, c, cpos, p);
44 } else {
45 /* in-assembly type aren't fully qualified (no comma) */
46 g_string_append_printf (res, "%.*s", cpos - 1, p);
49 p += len;
50 if (rptr)
51 *rptr = p;
53 result = res->str;
54 g_string_free (res, FALSE);
55 return result;
58 static gboolean
59 declsec_20_write_type (GString *str, char type)
61 switch (type) {
62 case MONO_TYPE_BOOLEAN:
63 g_string_append (str, "bool");
64 break;
65 case MONO_TYPE_SZARRAY:
66 g_string_append (str, "[]");
67 break;
68 case MONO_TYPE_SYSTEM_TYPE:
69 g_string_append (str, "type");
70 break;
71 case MONO_TYPE_STRING:
72 g_string_append (str, "string");
73 break;
74 default:
75 g_warning ("TODO type %d - please fill a bug report on this!", type);
76 return FALSE;
78 return TRUE;
81 static const char*
82 declsec_20_write_value (GString *str, char type, const char *value)
84 switch (type) {
85 case MONO_TYPE_U1:
86 g_string_append_printf (str, "%d", (unsigned char)*value);
87 return value + 1;
88 case MONO_TYPE_I1:
89 g_string_append_printf (str, "%d", *value);
90 return value + 1;
91 case MONO_TYPE_BOOLEAN:
92 g_string_append_printf (str, "%s", *value ? "true" : "false");
93 return value + 1;
94 case MONO_TYPE_CHAR:
95 g_string_append_printf (str, "0x%04X", read16 (value));
96 return value + 2;
97 case MONO_TYPE_U2:
98 g_string_append_printf (str, "%d", read16 (value));
99 return value + 2;
100 case MONO_TYPE_I2:
101 g_string_append_printf (str, "%d", (gint16)read16 (value));
102 return value + 2;
103 case MONO_TYPE_U4:
104 g_string_append_printf (str, "%d", read32 (value));
105 return value + 4;
106 case MONO_TYPE_I4:
107 g_string_append_printf (str, "%d", (gint32)read32 (value));
108 return value + 4;
109 case MONO_TYPE_U8:
110 case MONO_TYPE_I8:
111 g_string_append_printf (str, "%" PRId64, (gint64)read64 (value));
112 return value + 8;
113 case MONO_TYPE_R4: {
114 float val;
115 readr4 (value, &val);
116 const int inf = mono_isinf (val);
117 if (inf == -1)
118 g_string_append_printf (str, "0xFF800000"); /* negative infinity */
119 else if (inf == 1)
120 g_string_append_printf (str, "0x7F800000"); /* positive infinity */
121 else if (mono_isnan (val))
122 g_string_append_printf (str, "0xFFC00000"); /* NaN */
123 else
124 g_string_append_printf (str, "%.8g", val);
125 return value + 4;
127 case MONO_TYPE_R8: {
128 double val;
129 readr8 (value, &val);
130 const int inf = mono_isinf (val);
131 if (inf == -1)
132 g_string_append_printf (str, "0xFFF00000000000000"); /* negative infinity */
133 else if (inf == 1)
134 g_string_append_printf (str, "0x7FFF0000000000000"); /* positive infinity */
135 else if (mono_isnan (val))
136 g_string_append_printf (str, "0xFFF80000000000000"); /* NaN */
137 else
138 g_string_append_printf (str, "%.17g", val);
139 return value + 8;
141 case MONO_TYPE_STRING:
142 if (*value == (char)0xff) {
143 g_string_append (str, "nullref");
144 return value + 1;
145 } else {
146 int len = mono_metadata_decode_value (value, &value);
147 g_string_append_printf (str, "'%.*s'", len, value);
148 return value + len;
150 case MONO_TYPE_SYSTEM_TYPE: {
151 char *cname = declsec_20_get_classname (value, NULL);
152 int len = mono_metadata_decode_value (value, &value);
153 g_string_append (str, cname);
154 g_free (cname);
155 return value + len;
158 return 0;
161 char*
162 dump_declsec_entry20 (MonoImage *m, const char* p, const char *indent)
164 int i, num;
165 char *result;
166 GString *res = g_string_new ("");
168 if (*p++ != MONO_DECLSEC_FORMAT_20)
169 return NULL;
171 g_string_append (res, "{");
173 /* number of encoded permission attributes */
174 num = mono_metadata_decode_value (p, &p);
176 for (i = 0; i < num; i++) {
177 int len, j, pos = 0, param_len;
178 char *param_start;
179 char *s = declsec_20_get_classname (p, &p);
180 g_string_append_printf (res, "%s = {", s);
181 g_free (s);
183 /* optional parameters length */
184 param_len = mono_metadata_decode_value (p, &p);
185 param_start = (char *) p;
187 /* number of parameters */
188 pos = mono_metadata_decode_value (p, &p);
189 for (j = 0; j < pos; j++) {
190 int k, elem;
191 int type = *p++;
193 switch (type) {
194 case MONO_DECLSEC_FIELD:
195 /* not sure if/how we can get this in a declarative security attribute... */
196 g_string_append (res, "field ");
197 break;
198 case MONO_DECLSEC_PROPERTY:
199 g_string_append (res, "property ");
200 break;
201 default:
202 g_warning ("TODO %d - please fill a bug report on this!", type);
203 break;
206 type = *p++;
208 if (type == MONO_DECLSEC_ENUM) {
209 s = declsec_20_get_classname (p, &p);
210 len = mono_metadata_decode_value (p, &p);
211 g_string_append_printf (res, "enum %s '%.*s' = ", s, len, p);
212 g_free (s);
213 p += len;
214 /* TODO: we must detect the size of the enum element (from the type ? length ?)
215 * note: ildasm v2 has some problem decoding them too and doesn't
216 * seems to rely on the type (as the other assembly isn't loaded) */
217 g_string_append_printf (res, "int32(%d)", read32 (p));
218 p += 4;
219 } else {
220 int arraytype = 0;
221 if (type == MONO_TYPE_SZARRAY) {
222 arraytype = *p++;
223 declsec_20_write_type (res, arraytype);
225 declsec_20_write_type (res, type);
227 len = mono_metadata_decode_value (p, &p);
228 g_string_append_printf (res, " '%.*s' = ", len, p);
229 p += len;
231 if (type == MONO_TYPE_SZARRAY) {
232 type = arraytype;
233 declsec_20_write_type (res, type);
234 elem = read32 (p);
235 p += 4;
236 g_string_append_printf (res, "[%d]", elem);
237 } else {
238 declsec_20_write_type (res, type);
239 elem = 1;
241 g_string_append (res, "(");
243 /* write value - or each element in the array */
244 for (k = 0; k < elem; k++) {
245 p = declsec_20_write_value (res, type, p);
246 /* separate array elements */
247 if (k < elem - 1)
248 g_string_append (res, " ");
251 if (j < pos - 1)
252 g_string_append_printf (res, ")\n%s", indent);
253 else
254 g_string_append (res, ")");
259 if (i < num - 1)
260 g_string_append_printf (res, "},\n%s", indent);
261 else
262 g_string_append (res, "}");
264 if (param_len > 0)
265 p = param_start + param_len;
267 g_string_append (res, "}");
269 result = res->str;
270 g_string_free (res, FALSE);
271 return result;