2 * declsec.h: Support for the new declarative security attribute
3 * metadata format (2.0)
6 * Sebastien Pouliot <sebastien@ximian.com>
8 * Copyright (C) 2005 Novell, Inc (http://www.novell.com)
14 #include "mono/metadata/blob.h"
15 #include "mono/metadata/metadata.h"
16 #include "mono/metadata/mono-endian.h"
17 #include "mono/utils/mono-compiler.h"
22 declsec_20_get_classname (const char* p, const char **rptr)
28 GString *res = g_string_new ("");
29 int len = mono_metadata_decode_value (p, &p);
32 while ((*c++ != ',') && (cpos++ < len));
37 while ((*a++ != ',') && (apos++ < len));
39 if (apos - cpos > 1) {
40 g_string_sprintfa (res, "[%.*s]%.*s", apos - cpos, c, cpos, p);
42 /* in-assembly type aren't fully qualified (no comma) */
43 g_string_sprintfa (res, "%.*s", cpos - 1, p);
51 g_string_free (res, FALSE);
56 declsec_20_write_type (GString *str, char type)
59 case MONO_TYPE_SZARRAY:
60 g_string_append (str, "[]");
62 case MONO_TYPE_SYSTEM_TYPE:
63 g_string_append (str, "type");
66 g_warning ("TODO type %d - please fill a bug report on this!", type);
73 declsec_20_write_value (GString *str, char type, const char *value)
77 g_string_sprintfa (str, "%d", (unsigned char)*value);
80 g_string_sprintfa (str, "%d", *value);
82 case MONO_TYPE_BOOLEAN:
83 g_string_sprintfa (str, "%s", *value ? "true" : "false");
86 g_string_sprintfa (str, "0x%04X", read16 (value));
89 g_string_sprintfa (str, "%d", read16 (value));
92 g_string_sprintfa (str, "%d", (gint16)read16 (value));
95 g_string_sprintfa (str, "%d", read32 (value));
98 g_string_sprintfa (str, "%d", (gint32)read32 (value));
101 g_string_sprintfa (str, "%lld", (long long)read64 (value));
104 g_string_sprintfa (str, "%lld", (long long)read64 (value));
109 readr4 (value, &val);
112 g_string_sprintfa (str, "0xFF800000"); /* negative infinity */
114 g_string_sprintfa (str, "0x7F800000"); /* positive infinity */
115 else if (isnan (val))
116 g_string_sprintfa (str, "0xFFC00000"); /* NaN */
118 g_string_sprintfa (str, "%.8g", val);
124 readr8 (value, &val);
127 g_string_sprintfa (str, "0xFFF00000000000000"); /* negative infinity */
129 g_string_sprintfa (str, "0x7FFF0000000000000"); /* positive infinity */
130 else if (isnan (val))
131 g_string_sprintfa (str, "0xFFF80000000000000"); /* NaN */
133 g_string_sprintfa (str, "%.17g", val);
136 case MONO_TYPE_STRING:
137 if (*value == (char)0xff) {
138 g_string_append (str, "nullref");
141 int len = mono_metadata_decode_value (value, &value);
142 g_string_sprintfa (str, "'%.*s'", len, value);
145 case MONO_TYPE_SYSTEM_TYPE: {
146 char *cname = declsec_20_get_classname (value, NULL);
147 int len = mono_metadata_decode_value (value, &value);
148 g_string_append (str, cname);
157 dump_declsec_entry20 (MonoImage *m, const char* p, const char *indent)
161 GString *res = g_string_new ("");
163 if (*p++ != MONO_DECLSEC_FORMAT_20)
166 g_string_append (res, "{");
168 /* number of encoded permission attributes */
169 num = mono_metadata_decode_value (p, &p);
171 for (i = 0; i < num; i++) {
172 int len, j, pos = 0, param_len;
174 char *s = declsec_20_get_classname (p, &p);
175 g_string_sprintfa (res, "%s = {", s);
178 /* optional parameters length */
179 param_len = mono_metadata_decode_value (p, &p);
180 param_start = (char *) p;
182 /* number of parameters */
183 pos = mono_metadata_decode_value (p, &p);
184 for (j = 0; j < pos; j++) {
189 case MONO_DECLSEC_FIELD:
190 /* not sure if/how we can get this in a declarative security attribute... */
191 g_string_append (res, "field ");
193 case MONO_DECLSEC_PROPERTY:
194 g_string_append (res, "property ");
197 g_warning ("TODO %d - please fill a bug report on this!", type);
203 if (type == MONO_DECLSEC_ENUM) {
204 s = declsec_20_get_classname (p, &p);
205 len = mono_metadata_decode_value (p, &p);
206 g_string_sprintfa (res, "enum %s '%.*s' = ", s, len, p);
209 /* TODO: we must detect the size of the enum element (from the type ? length ?)
210 * note: ildasm v2 has some problem decoding them too and doesn't
211 * seems to rely on the type (as the other assembly isn't loaded) */
212 g_string_sprintfa (res, "int32(%d)", read32 (p));
216 if (type == MONO_TYPE_SZARRAY) {
218 declsec_20_write_type (res, arraytype);
220 declsec_20_write_type (res, type);
222 len = mono_metadata_decode_value (p, &p);
223 g_string_sprintfa (res, " '%.*s' = ", len, p);
226 if (type == MONO_TYPE_SZARRAY) {
228 declsec_20_write_type (res, type);
231 g_string_sprintfa (res, "[%d]", elem);
233 declsec_20_write_type (res, type);
236 g_string_append (res, "(");
238 /* write value - or each element in the array */
239 for (k = 0; k < elem; k++) {
240 p = declsec_20_write_value (res, type, p);
241 /* separate array elements */
243 g_string_append (res, " ");
247 g_string_sprintfa (res, ")\n%s", indent);
249 g_string_append (res, ")");
255 g_string_sprintfa (res, "},\n%s", indent);
257 g_string_append (res, "}");
260 p = param_start + param_len;
262 g_string_append (res, "}");
265 g_string_free (res, FALSE);