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)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
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"
25 declsec_20_get_classname (const char* p
, const char **rptr
)
31 GString
*res
= g_string_new ("");
32 int len
= mono_metadata_decode_value (p
, &p
);
35 while ((*c
++ != ',') && (cpos
++ < len
));
40 while ((*a
++ != ',') && (apos
++ < len
));
42 if (apos
- cpos
> 1) {
43 g_string_append_printf (res
, "[%.*s]%.*s", apos
- cpos
, c
, cpos
, p
);
45 /* in-assembly type aren't fully qualified (no comma) */
46 g_string_append_printf (res
, "%.*s", cpos
- 1, p
);
54 g_string_free (res
, FALSE
);
59 declsec_20_write_type (GString
*str
, char type
)
62 case MONO_TYPE_BOOLEAN
:
63 g_string_append (str
, "bool");
65 case MONO_TYPE_SZARRAY
:
66 g_string_append (str
, "[]");
68 case MONO_TYPE_SYSTEM_TYPE
:
69 g_string_append (str
, "type");
71 case MONO_TYPE_STRING
:
72 g_string_append (str
, "string");
75 g_warning ("TODO type %d - please fill a bug report on this!", type
);
82 declsec_20_write_value (GString
*str
, char type
, const char *value
)
86 g_string_append_printf (str
, "%d", (unsigned char)*value
);
89 g_string_append_printf (str
, "%d", *value
);
91 case MONO_TYPE_BOOLEAN
:
92 g_string_append_printf (str
, "%s", *value
? "true" : "false");
95 g_string_append_printf (str
, "0x%04X", read16 (value
));
98 g_string_append_printf (str
, "%d", read16 (value
));
101 g_string_append_printf (str
, "%d", (gint16
)read16 (value
));
104 g_string_append_printf (str
, "%d", read32 (value
));
107 g_string_append_printf (str
, "%d", (gint32
)read32 (value
));
111 g_string_append_printf (str
, "%" PRId64
, (gint64
)read64 (value
));
115 readr4 (value
, &val
);
116 const int inf
= mono_isinf (val
);
118 g_string_append_printf (str
, "0xFF800000"); /* negative infinity */
120 g_string_append_printf (str
, "0x7F800000"); /* positive infinity */
121 else if (mono_isnan (val
))
122 g_string_append_printf (str
, "0xFFC00000"); /* NaN */
124 g_string_append_printf (str
, "%.8g", val
);
129 readr8 (value
, &val
);
130 const int inf
= mono_isinf (val
);
132 g_string_append_printf (str
, "0xFFF00000000000000"); /* negative infinity */
134 g_string_append_printf (str
, "0x7FFF0000000000000"); /* positive infinity */
135 else if (mono_isnan (val
))
136 g_string_append_printf (str
, "0xFFF80000000000000"); /* NaN */
138 g_string_append_printf (str
, "%.17g", val
);
141 case MONO_TYPE_STRING
:
142 if (*value
== (char)0xff) {
143 g_string_append (str
, "nullref");
146 int len
= mono_metadata_decode_value (value
, &value
);
147 g_string_append_printf (str
, "'%.*s'", len
, value
);
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
);
162 dump_declsec_entry20 (MonoImage
*m
, const char* p
, const char *indent
)
166 GString
*res
= g_string_new ("");
168 if (*p
++ != MONO_DECLSEC_FORMAT_20
)
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
;
179 char *s
= declsec_20_get_classname (p
, &p
);
180 g_string_append_printf (res
, "%s = {", 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
++) {
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 ");
198 case MONO_DECLSEC_PROPERTY
:
199 g_string_append (res
, "property ");
202 g_warning ("TODO %d - please fill a bug report on this!", type
);
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
);
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
));
221 if (type
== MONO_TYPE_SZARRAY
) {
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
);
231 if (type
== MONO_TYPE_SZARRAY
) {
233 declsec_20_write_type (res
, type
);
236 g_string_append_printf (res
, "[%d]", elem
);
238 declsec_20_write_type (res
, type
);
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 */
248 g_string_append (res
, " ");
252 g_string_append_printf (res
, ")\n%s", indent
);
254 g_string_append (res
, ")");
260 g_string_append_printf (res
, "},\n%s", indent
);
262 g_string_append (res
, "}");
265 p
= param_start
+ param_len
;
267 g_string_append (res
, "}");
270 g_string_free (res
, FALSE
);