[runtime] MonoError-ize mono_marshal_xdomain_copy_value
[mono-project.git] / mono / dis / declsec.c
blobeb0f168850aefc9a73ace127cef519640ae8c284
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"
20 #include "declsec.h"
21 #include "util.h"
23 static char*
24 declsec_20_get_classname (const char* p, const char **rptr)
26 int apos, cpos = 0;
27 char *c;
28 char *a;
29 char *result;
30 GString *res = g_string_new ("");
31 int len = mono_metadata_decode_value (p, &p);
33 c = (char *) p;
34 while ((*c++ != ',') && (cpos++ < len));
35 c++;
37 apos = cpos;
38 a = c;
39 while ((*a++ != ',') && (apos++ < len));
41 if (apos - cpos > 1) {
42 g_string_append_printf (res, "[%.*s]%.*s", apos - cpos, c, cpos, p);
43 } else {
44 /* in-assembly type aren't fully qualified (no comma) */
45 g_string_append_printf (res, "%.*s", cpos - 1, p);
48 p += len;
49 if (rptr)
50 *rptr = p;
52 result = res->str;
53 g_string_free (res, FALSE);
54 return result;
57 static gboolean
58 declsec_20_write_type (GString *str, char type)
60 switch (type) {
61 case MONO_TYPE_BOOLEAN:
62 g_string_append (str, "bool");
63 break;
64 case MONO_TYPE_SZARRAY:
65 g_string_append (str, "[]");
66 break;
67 case MONO_TYPE_SYSTEM_TYPE:
68 g_string_append (str, "type");
69 break;
70 case MONO_TYPE_STRING:
71 g_string_append (str, "string");
72 break;
73 default:
74 g_warning ("TODO type %d - please fill a bug report on this!", type);
75 return FALSE;
77 return TRUE;
80 static const char*
81 declsec_20_write_value (GString *str, char type, const char *value)
83 switch (type) {
84 case MONO_TYPE_U1:
85 g_string_append_printf (str, "%d", (unsigned char)*value);
86 return value + 1;
87 case MONO_TYPE_I1:
88 g_string_append_printf (str, "%d", *value);
89 return value + 1;
90 case MONO_TYPE_BOOLEAN:
91 g_string_append_printf (str, "%s", *value ? "true" : "false");
92 return value + 1;
93 case MONO_TYPE_CHAR:
94 g_string_append_printf (str, "0x%04X", read16 (value));
95 return value + 2;
96 case MONO_TYPE_U2:
97 g_string_append_printf (str, "%d", read16 (value));
98 return value + 2;
99 case MONO_TYPE_I2:
100 g_string_append_printf (str, "%d", (gint16)read16 (value));
101 return value + 2;
102 case MONO_TYPE_U4:
103 g_string_append_printf (str, "%d", read32 (value));
104 return value + 4;
105 case MONO_TYPE_I4:
106 g_string_append_printf (str, "%d", (gint32)read32 (value));
107 return value + 4;
108 case MONO_TYPE_U8:
109 g_string_append_printf (str, "%lld", (long long)read64 (value));
110 return value + 8;
111 case MONO_TYPE_I8:
112 g_string_append_printf (str, "%lld", (long long)read64 (value));
113 return value + 8;
114 case MONO_TYPE_R4: {
115 float val;
116 int inf;
117 readr4 (value, &val);
118 inf = dis_isinf (val);
119 if (inf == -1)
120 g_string_append_printf (str, "0xFF800000"); /* negative infinity */
121 else if (inf == 1)
122 g_string_append_printf (str, "0x7F800000"); /* positive infinity */
123 else if (dis_isnan (val))
124 g_string_append_printf (str, "0xFFC00000"); /* NaN */
125 else
126 g_string_append_printf (str, "%.8g", val);
127 return value + 4;
129 case MONO_TYPE_R8: {
130 double val;
131 int inf;
132 readr8 (value, &val);
133 inf = dis_isinf (val);
134 if (inf == -1)
135 g_string_append_printf (str, "0xFFF00000000000000"); /* negative infinity */
136 else if (inf == 1)
137 g_string_append_printf (str, "0x7FFF0000000000000"); /* positive infinity */
138 else if (isnan (val))
139 g_string_append_printf (str, "0xFFF80000000000000"); /* NaN */
140 else
141 g_string_append_printf (str, "%.17g", val);
142 return value + 8;
144 case MONO_TYPE_STRING:
145 if (*value == (char)0xff) {
146 g_string_append (str, "nullref");
147 return value + 1;
148 } else {
149 int len = mono_metadata_decode_value (value, &value);
150 g_string_append_printf (str, "'%.*s'", len, value);
151 return value + len;
153 case MONO_TYPE_SYSTEM_TYPE: {
154 char *cname = declsec_20_get_classname (value, NULL);
155 int len = mono_metadata_decode_value (value, &value);
156 g_string_append (str, cname);
157 g_free (cname);
158 return value + len;
161 return 0;
164 char*
165 dump_declsec_entry20 (MonoImage *m, const char* p, const char *indent)
167 int i, num;
168 char *result;
169 GString *res = g_string_new ("");
171 if (*p++ != MONO_DECLSEC_FORMAT_20)
172 return NULL;
174 g_string_append (res, "{");
176 /* number of encoded permission attributes */
177 num = mono_metadata_decode_value (p, &p);
179 for (i = 0; i < num; i++) {
180 int len, j, pos = 0, param_len;
181 char *param_start;
182 char *s = declsec_20_get_classname (p, &p);
183 g_string_append_printf (res, "%s = {", s);
184 g_free (s);
186 /* optional parameters length */
187 param_len = mono_metadata_decode_value (p, &p);
188 param_start = (char *) p;
190 /* number of parameters */
191 pos = mono_metadata_decode_value (p, &p);
192 for (j = 0; j < pos; j++) {
193 int k, elem;
194 int type = *p++;
196 switch (type) {
197 case MONO_DECLSEC_FIELD:
198 /* not sure if/how we can get this in a declarative security attribute... */
199 g_string_append (res, "field ");
200 break;
201 case MONO_DECLSEC_PROPERTY:
202 g_string_append (res, "property ");
203 break;
204 default:
205 g_warning ("TODO %d - please fill a bug report on this!", type);
206 break;
209 type = *p++;
211 if (type == MONO_DECLSEC_ENUM) {
212 s = declsec_20_get_classname (p, &p);
213 len = mono_metadata_decode_value (p, &p);
214 g_string_append_printf (res, "enum %s '%.*s' = ", s, len, p);
215 g_free (s);
216 p += len;
217 /* TODO: we must detect the size of the enum element (from the type ? length ?)
218 * note: ildasm v2 has some problem decoding them too and doesn't
219 * seems to rely on the type (as the other assembly isn't loaded) */
220 g_string_append_printf (res, "int32(%d)", read32 (p));
221 p += 4;
222 } else {
223 int arraytype = 0;
224 if (type == MONO_TYPE_SZARRAY) {
225 arraytype = *p++;
226 declsec_20_write_type (res, arraytype);
228 declsec_20_write_type (res, type);
230 len = mono_metadata_decode_value (p, &p);
231 g_string_append_printf (res, " '%.*s' = ", len, p);
232 p += len;
234 if (type == MONO_TYPE_SZARRAY) {
235 type = arraytype;
236 declsec_20_write_type (res, type);
237 elem = read32 (p);
238 p += 4;
239 g_string_append_printf (res, "[%d]", elem);
240 } else {
241 declsec_20_write_type (res, type);
242 elem = 1;
244 g_string_append (res, "(");
246 /* write value - or each element in the array */
247 for (k = 0; k < elem; k++) {
248 p = declsec_20_write_value (res, type, p);
249 /* separate array elements */
250 if (k < elem - 1)
251 g_string_append (res, " ");
254 if (j < pos - 1)
255 g_string_append_printf (res, ")\n%s", indent);
256 else
257 g_string_append (res, ")");
262 if (i < num - 1)
263 g_string_append_printf (res, "},\n%s", indent);
264 else
265 g_string_append (res, "}");
267 if (param_len > 0)
268 p = param_start + param_len;
270 g_string_append (res, "}");
272 result = res->str;
273 g_string_free (res, FALSE);
274 return result;