1 /** 2 * \file 3 */ 4 5 #ifndef __MONO_METADATA_H__ 6 #define __MONO_METADATA_H__ 7 8 #include <mono/utils/mono-publib.h> 9 10 #include <mono/metadata/blob.h> 11 #include <mono/metadata/row-indexes.h> 12 #include <mono/metadata/image.h> 13 14 MONO_BEGIN_DECLS 15 16 #define MONO_TYPE_ISSTRUCT(t) mono_type_is_struct (t) 17 #define MONO_TYPE_IS_VOID(t) mono_type_is_void (t) 18 #define MONO_TYPE_IS_POINTER(t) mono_type_is_pointer (t) 19 #define MONO_TYPE_IS_REFERENCE(t) mono_type_is_reference (t) 20 21 #define MONO_CLASS_IS_INTERFACE(c) ((mono_class_get_flags (c) & TYPE_ATTRIBUTE_INTERFACE) || (c->byval_arg.type == MONO_TYPE_VAR) || (c->byval_arg.type == MONO_TYPE_MVAR)) 22 23 #define MONO_CLASS_IS_IMPORT(c) ((mono_class_get_flags (c) & TYPE_ATTRIBUTE_IMPORT)) 24 25 typedef struct _MonoClass MonoClass; 26 typedef struct _MonoDomain MonoDomain; 27 typedef struct _MonoMethod MonoMethod; 28 29 typedef enum { 30 MONO_EXCEPTION_CLAUSE_NONE, 31 MONO_EXCEPTION_CLAUSE_FILTER, 32 MONO_EXCEPTION_CLAUSE_FINALLY, 33 MONO_EXCEPTION_CLAUSE_FAULT = 4 34 } MonoExceptionEnum; 35 36 typedef enum { 37 MONO_CALL_DEFAULT, 38 MONO_CALL_C, 39 MONO_CALL_STDCALL, 40 MONO_CALL_THISCALL, 41 MONO_CALL_FASTCALL, 42 MONO_CALL_VARARG 43 } MonoCallConvention; 44 45 /* ECMA lamespec: the old spec had more info... */ 46 typedef enum { 47 MONO_NATIVE_BOOLEAN = 0x02, /* 4 bytes, 0 is false, != 0 is true */ 48 MONO_NATIVE_I1 = 0x03, 49 MONO_NATIVE_U1 = 0x04, 50 MONO_NATIVE_I2 = 0x05, 51 MONO_NATIVE_U2 = 0x06, 52 MONO_NATIVE_I4 = 0x07, 53 MONO_NATIVE_U4 = 0x08, 54 MONO_NATIVE_I8 = 0x09, 55 MONO_NATIVE_U8 = 0x0a, 56 MONO_NATIVE_R4 = 0x0b, 57 MONO_NATIVE_R8 = 0x0c, 58 MONO_NATIVE_CURRENCY = 0x0f, 59 MONO_NATIVE_BSTR = 0x13, /* prefixed length, Unicode */ 60 MONO_NATIVE_LPSTR = 0x14, /* ANSI, null terminated */ 61 MONO_NATIVE_LPWSTR = 0x15, /* UNICODE, null terminated */ 62 MONO_NATIVE_LPTSTR = 0x16, /* plattform dep., null terminated */ 63 MONO_NATIVE_BYVALTSTR = 0x17, 64 MONO_NATIVE_IUNKNOWN = 0x19, 65 MONO_NATIVE_IDISPATCH = 0x1a, 66 MONO_NATIVE_STRUCT = 0x1b, 67 MONO_NATIVE_INTERFACE = 0x1c, 68 MONO_NATIVE_SAFEARRAY = 0x1d, 69 MONO_NATIVE_BYVALARRAY = 0x1e, 70 MONO_NATIVE_INT = 0x1f, 71 MONO_NATIVE_UINT = 0x20, 72 MONO_NATIVE_VBBYREFSTR = 0x22, 73 MONO_NATIVE_ANSIBSTR = 0x23, /* prefixed length, ANSI */ 74 MONO_NATIVE_TBSTR = 0x24, /* prefixed length, plattform dep. */ 75 MONO_NATIVE_VARIANTBOOL = 0x25, 76 MONO_NATIVE_FUNC = 0x26, 77 MONO_NATIVE_ASANY = 0x28, 78 MONO_NATIVE_LPARRAY = 0x2a, 79 MONO_NATIVE_LPSTRUCT = 0x2b, 80 MONO_NATIVE_CUSTOM = 0x2c, 81 MONO_NATIVE_ERROR = 0x2d, 82 // TODO: MONO_NATIVE_IINSPECTABLE = 0x2e 83 // TODO: MONO_NATIVE_HSTRING = 0x2f 84 MONO_NATIVE_UTF8STR = 0x30, 85 MONO_NATIVE_MAX = 0x50 /* no info */ 86 } MonoMarshalNative; 87 88 /* Used only in context of SafeArray */ 89 typedef enum { 90 MONO_VARIANT_EMPTY = 0x00, 91 MONO_VARIANT_NULL = 0x01, 92 MONO_VARIANT_I2 = 0x02, 93 MONO_VARIANT_I4 = 0x03, 94 MONO_VARIANT_R4 = 0x04, 95 MONO_VARIANT_R8 = 0x05, 96 MONO_VARIANT_CY = 0x06, 97 MONO_VARIANT_DATE = 0x07, 98 MONO_VARIANT_BSTR = 0x08, 99 MONO_VARIANT_DISPATCH = 0x09, 100 MONO_VARIANT_ERROR = 0x0a, 101 MONO_VARIANT_BOOL = 0x0b, 102 MONO_VARIANT_VARIANT = 0x0c, 103 MONO_VARIANT_UNKNOWN = 0x0d, 104 MONO_VARIANT_DECIMAL = 0x0e, 105 MONO_VARIANT_I1 = 0x10, 106 MONO_VARIANT_UI1 = 0x11, 107 MONO_VARIANT_UI2 = 0x12, 108 MONO_VARIANT_UI4 = 0x13, 109 MONO_VARIANT_I8 = 0x14, 110 MONO_VARIANT_UI8 = 0x15, 111 MONO_VARIANT_INT = 0x16, 112 MONO_VARIANT_UINT = 0x17, 113 MONO_VARIANT_VOID = 0x18, 114 MONO_VARIANT_HRESULT = 0x19, 115 MONO_VARIANT_PTR = 0x1a, 116 MONO_VARIANT_SAFEARRAY = 0x1b, 117 MONO_VARIANT_CARRAY = 0x1c, 118 MONO_VARIANT_USERDEFINED = 0x1d, 119 MONO_VARIANT_LPSTR = 0x1e, 120 MONO_VARIANT_LPWSTR = 0x1f, 121 MONO_VARIANT_RECORD = 0x24, 122 MONO_VARIANT_FILETIME = 0x40, 123 MONO_VARIANT_BLOB = 0x41, 124 MONO_VARIANT_STREAM = 0x42, 125 MONO_VARIANT_STORAGE = 0x43, 126 MONO_VARIANT_STREAMED_OBJECT = 0x44, 127 MONO_VARIANT_STORED_OBJECT = 0x45, 128 MONO_VARIANT_BLOB_OBJECT = 0x46, 129 MONO_VARIANT_CF = 0x47, 130 MONO_VARIANT_CLSID = 0x48, 131 MONO_VARIANT_VECTOR = 0x1000, 132 MONO_VARIANT_ARRAY = 0x2000, 133 MONO_VARIANT_BYREF = 0x4000 134 } MonoMarshalVariant; 135 136 typedef enum { 137 MONO_MARSHAL_CONV_NONE, 138 MONO_MARSHAL_CONV_BOOL_VARIANTBOOL, 139 MONO_MARSHAL_CONV_BOOL_I4, 140 MONO_MARSHAL_CONV_STR_BSTR, 141 MONO_MARSHAL_CONV_STR_LPSTR, 142 MONO_MARSHAL_CONV_LPSTR_STR, 143 MONO_MARSHAL_CONV_LPTSTR_STR, 144 MONO_MARSHAL_CONV_STR_LPWSTR, 145 MONO_MARSHAL_CONV_LPWSTR_STR, 146 MONO_MARSHAL_CONV_STR_LPTSTR, 147 MONO_MARSHAL_CONV_STR_ANSIBSTR, 148 MONO_MARSHAL_CONV_STR_TBSTR, 149 MONO_MARSHAL_CONV_STR_BYVALSTR, 150 MONO_MARSHAL_CONV_STR_BYVALWSTR, 151 MONO_MARSHAL_CONV_SB_LPSTR, 152 MONO_MARSHAL_CONV_SB_LPTSTR, 153 MONO_MARSHAL_CONV_SB_LPWSTR, 154 MONO_MARSHAL_CONV_LPSTR_SB, 155 MONO_MARSHAL_CONV_LPTSTR_SB, 156 MONO_MARSHAL_CONV_LPWSTR_SB, 157 MONO_MARSHAL_CONV_ARRAY_BYVALARRAY, 158 MONO_MARSHAL_CONV_ARRAY_BYVALCHARARRAY, 159 MONO_MARSHAL_CONV_ARRAY_SAVEARRAY, 160 MONO_MARSHAL_CONV_ARRAY_LPARRAY, 161 MONO_MARSHAL_FREE_LPARRAY, 162 MONO_MARSHAL_CONV_OBJECT_INTERFACE, 163 MONO_MARSHAL_CONV_OBJECT_IDISPATCH, 164 MONO_MARSHAL_CONV_OBJECT_IUNKNOWN, 165 MONO_MARSHAL_CONV_OBJECT_STRUCT, 166 MONO_MARSHAL_CONV_DEL_FTN, 167 MONO_MARSHAL_CONV_FTN_DEL, 168 MONO_MARSHAL_FREE_ARRAY, 169 MONO_MARSHAL_CONV_BSTR_STR, 170 MONO_MARSHAL_CONV_SAFEHANDLE, 171 MONO_MARSHAL_CONV_HANDLEREF, 172 MONO_MARSHAL_CONV_STR_UTF8STR, 173 MONO_MARSHAL_CONV_SB_UTF8STR, 174 MONO_MARSHAL_CONV_UTF8STR_STR, 175 MONO_MARSHAL_CONV_UTF8STR_SB, 176 MONO_MARSHAL_CONV_FIXED_BUFFER 177 } MonoMarshalConv; 178 179 #define MONO_MARSHAL_CONV_INVALID ((MonoMarshalConv)-1) 180 181 typedef struct { 182 MonoMarshalNative native; 183 union { 184 struct { 185 MonoMarshalNative elem_type; 186 int32_t num_elem; /* -1 if not set */ 187 int16_t param_num; /* -1 if not set */ 188 int16_t elem_mult; /* -1 if not set */ 189 } array_data; 190 struct { 191 char *custom_name; 192 char *cookie; 193 MonoImage *image; 194 } custom_data; 195 struct { 196 MonoMarshalVariant elem_type; 197 int32_t num_elem; 198 } safearray_data; 199 } data; 200 } MonoMarshalSpec; 201 202 MONO_API void mono_metadata_init (void); 203 204 MONO_API void mono_metadata_decode_row (const MonoTableInfo *t, 205 int idx, 206 uint32_t *res, 207 int res_size); 208 209 MONO_API uint32_t mono_metadata_decode_row_col (const MonoTableInfo *t, 210 int idx, 211 unsigned int col); 212 213 /* 214 * This macro is used to extract the size of the table encoded in 215 * the size_bitfield of MonoTableInfo. 216 */ 217 #define mono_metadata_table_size(bitfield,table) ((((bitfield) >> ((table)*2)) & 0x3) + 1) 218 #define mono_metadata_table_count(bitfield) ((bitfield) >> 24) 219 220 MONO_API int mono_metadata_compute_size (MonoImage *meta, 221 int tableindex, 222 uint32_t *result_bitfield); 223 224 /* 225 * 226 */ 227 MONO_API const char *mono_metadata_locate (MonoImage *meta, int table, int idx); 228 MONO_API const char *mono_metadata_locate_token (MonoImage *meta, uint32_t token); 229 230 MONO_API const char *mono_metadata_string_heap (MonoImage *meta, uint32_t table_index); 231 MONO_API const char *mono_metadata_blob_heap (MonoImage *meta, uint32_t table_index); 232 MONO_API const char *mono_metadata_user_string (MonoImage *meta, uint32_t table_index); 233 MONO_API const char *mono_metadata_guid_heap (MonoImage *meta, uint32_t table_index); 234 235 MONO_API uint32_t mono_metadata_typedef_from_field (MonoImage *meta, uint32_t table_index); 236 MONO_API uint32_t mono_metadata_typedef_from_method (MonoImage *meta, uint32_t table_index); 237 MONO_API uint32_t mono_metadata_nested_in_typedef (MonoImage *meta, uint32_t table_index); 238 MONO_API uint32_t mono_metadata_nesting_typedef (MonoImage *meta, uint32_t table_index, uint32_t start_index); 239 240 MONO_API MonoClass** mono_metadata_interfaces_from_typedef (MonoImage *meta, uint32_t table_index, unsigned int *count); 241 242 MONO_API uint32_t mono_metadata_events_from_typedef (MonoImage *meta, uint32_t table_index, unsigned int *end_idx); 243 MONO_API uint32_t mono_metadata_methods_from_event (MonoImage *meta, uint32_t table_index, unsigned int *end); 244 MONO_API uint32_t mono_metadata_properties_from_typedef (MonoImage *meta, uint32_t table_index, unsigned int *end); 245 MONO_API uint32_t mono_metadata_methods_from_property (MonoImage *meta, uint32_t table_index, unsigned int *end); 246 MONO_API uint32_t mono_metadata_packing_from_typedef (MonoImage *meta, uint32_t table_index, uint32_t *packing, uint32_t *size); 247 MONO_API const char* mono_metadata_get_marshal_info (MonoImage *meta, uint32_t idx, mono_bool is_field); 248 MONO_API uint32_t mono_metadata_custom_attrs_from_index (MonoImage *meta, uint32_t cattr_index); 249 250 MONO_API MonoMarshalSpec *mono_metadata_parse_marshal_spec (MonoImage *image, const char *ptr); 251 252 MONO_API void mono_metadata_free_marshal_spec (MonoMarshalSpec *spec); 253 254 MONO_API uint32_t mono_metadata_implmap_from_method (MonoImage *meta, uint32_t method_idx); 255 256 MONO_API void mono_metadata_field_info (MonoImage *meta, 257 uint32_t table_index, 258 uint32_t *offset, 259 uint32_t *rva, 260 MonoMarshalSpec **marshal_spec); 261 262 MONO_API uint32_t mono_metadata_get_constant_index (MonoImage *meta, uint32_t token, uint32_t hint); 263 264 /* 265 * Functions to extract information from the Blobs 266 */ 267 MONO_API uint32_t mono_metadata_decode_value (const char *ptr, 268 const char **rptr); 269 MONO_API int32_t mono_metadata_decode_signed_value (const char *ptr, const char **rptr); 270 271 MONO_API uint32_t mono_metadata_decode_blob_size (const char *ptr, 272 const char **rptr); 273 274 MONO_API void mono_metadata_encode_value (uint32_t value, char *bug, char **endbuf); 275 276 #define MONO_OFFSET_IN_CLAUSE(clause,offset) \ 277 ((clause)->try_offset <= (offset) && (offset) < ((clause)->try_offset + (clause)->try_len)) 278 #define MONO_OFFSET_IN_HANDLER(clause,offset) \ 279 ((clause)->handler_offset <= (offset) && (offset) < ((clause)->handler_offset + (clause)->handler_len)) 280 #define MONO_OFFSET_IN_FILTER(clause,offset) \ 281 ((clause)->flags == MONO_EXCEPTION_CLAUSE_FILTER && (clause)->data.filter_offset <= (offset) && (offset) < ((clause)->handler_offset)) 282 283 typedef struct { 284 uint32_t flags; 285 uint32_t try_offset; 286 uint32_t try_len; 287 uint32_t handler_offset; 288 uint32_t handler_len; 289 union { 290 uint32_t filter_offset; 291 MonoClass *catch_class; 292 } data; 293 } MonoExceptionClause; 294 295 typedef struct _MonoType MonoType; 296 typedef struct _MonoGenericInst MonoGenericInst; 297 typedef struct _MonoGenericClass MonoGenericClass; 298 typedef struct _MonoGenericContext MonoGenericContext; 299 typedef struct _MonoGenericContainer MonoGenericContainer; 300 typedef struct _MonoGenericParam MonoGenericParam; 301 typedef struct _MonoArrayType MonoArrayType; 302 typedef struct _MonoMethodSignature MonoMethodSignature; 303 304 /* FIXME: Keeping this name alive for now, since it is part of the exposed API, even though no entrypoint uses it. */ 305 typedef struct invalid_name MonoGenericMethod; 306 307 typedef struct { 308 unsigned int required : 1; 309 unsigned int token : 31; 310 } MonoCustomMod; 311 312 struct _MonoArrayType { 313 MonoClass *eklass; 314 // Number of dimensions of the array 315 uint8_t rank; 316 317 // Arrays recording known upper and lower index bounds for each dimension 318 uint8_t numsizes; 319 uint8_t numlobounds; 320 int *sizes; 321 int *lobounds; 322 }; 323 324 typedef struct _MonoMethodHeader MonoMethodHeader; 325 326 typedef enum { 327 MONO_PARSE_TYPE, 328 MONO_PARSE_MOD_TYPE, 329 MONO_PARSE_LOCAL, 330 MONO_PARSE_PARAM, 331 MONO_PARSE_RET, 332 MONO_PARSE_FIELD 333 } MonoParseTypeMode; 334 335 MONO_API mono_bool 336 mono_type_is_byref (MonoType *type); 337 338 MONO_API int 339 mono_type_get_type (MonoType *type); 340 341 /* For MONO_TYPE_FNPTR */ 342 MONO_API MonoMethodSignature* 343 mono_type_get_signature (MonoType *type); 344 345 /* For MONO_TYPE_CLASS, VALUETYPE */ 346 MONO_API MonoClass* 347 mono_type_get_class (MonoType *type); 348 349 MONO_API MonoArrayType* 350 mono_type_get_array_type (MonoType *type); 351 352 /* For MONO_TYPE_PTR */ 353 MONO_API MonoType* 354 mono_type_get_ptr_type (MonoType *type); 355 356 MONO_API MonoClass* 357 mono_type_get_modifiers (MonoType *type, mono_bool *is_required, void **iter); 358 359 MONO_API mono_bool mono_type_is_struct (MonoType *type); 360 MONO_API mono_bool mono_type_is_void (MonoType *type); 361 MONO_API mono_bool mono_type_is_pointer (MonoType *type); 362 MONO_API mono_bool mono_type_is_reference (MonoType *type); 363 mono_bool mono_type_is_generic_parameter (MonoType *type); 364 365 MONO_API MonoType* 366 mono_signature_get_return_type (MonoMethodSignature *sig); 367 368 MONO_API MonoType* 369 mono_signature_get_params (MonoMethodSignature *sig, void **iter); 370 371 MONO_API uint32_t 372 mono_signature_get_param_count (MonoMethodSignature *sig); 373 374 MONO_API uint32_t 375 mono_signature_get_call_conv (MonoMethodSignature *sig); 376 377 MONO_API int 378 mono_signature_vararg_start (MonoMethodSignature *sig); 379 380 MONO_API mono_bool 381 mono_signature_is_instance (MonoMethodSignature *sig); 382 383 MONO_API mono_bool 384 mono_signature_explicit_this (MonoMethodSignature *sig); 385 386 MONO_API mono_bool 387 mono_signature_param_is_out (MonoMethodSignature *sig, int param_num); 388 389 MONO_API uint32_t mono_metadata_parse_typedef_or_ref (MonoImage *m, 390 const char *ptr, 391 const char **rptr); 392 MONO_API int mono_metadata_parse_custom_mod (MonoImage *m, 393 MonoCustomMod *dest, 394 const char *ptr, 395 const char **rptr); 396 MONO_RT_EXTERNAL_ONLY 397 MONO_API MonoArrayType *mono_metadata_parse_array (MonoImage *m, 398 const char *ptr, 399 const char **rptr); 400 MONO_API void mono_metadata_free_array (MonoArrayType *array); 401 MONO_RT_EXTERNAL_ONLY 402 MONO_API MonoType *mono_metadata_parse_type (MonoImage *m, 403 MonoParseTypeMode mode, 404 short opt_attrs, 405 const char *ptr, 406 const char **rptr); 407 MONO_RT_EXTERNAL_ONLY 408 MONO_API MonoType *mono_metadata_parse_param (MonoImage *m, 409 const char *ptr, 410 const char **rptr); 411 MONO_RT_EXTERNAL_ONLY 412 MONO_API MonoType *mono_metadata_parse_field_type (MonoImage *m, 413 short field_flags, 414 const char *ptr, 415 const char **rptr); 416 MONO_API MonoType *mono_type_create_from_typespec (MonoImage *image, 417 uint32_t type_spec); 418 MONO_API void mono_metadata_free_type (MonoType *type); 419 MONO_API int mono_type_size (MonoType *type, 420 int *alignment); 421 MONO_API int mono_type_stack_size (MonoType *type, 422 int *alignment); 423 424 MONO_API mono_bool mono_type_generic_inst_is_valuetype (MonoType *type); 425 MONO_API mono_bool mono_metadata_generic_class_is_valuetype (MonoGenericClass *gclass); 426 427 MONO_API unsigned int mono_metadata_type_hash (MonoType *t1); 428 MONO_API mono_bool mono_metadata_type_equal (MonoType *t1, MonoType *t2); 429 430 MONO_API MonoMethodSignature *mono_metadata_signature_alloc (MonoImage *image, uint32_t nparams); 431 432 MONO_API MonoMethodSignature *mono_metadata_signature_dup (MonoMethodSignature *sig); 433 434 MONO_RT_EXTERNAL_ONLY 435 MONO_API MonoMethodSignature *mono_metadata_parse_signature (MonoImage *image, 436 uint32_t token); 437 438 MONO_API MonoMethodSignature *mono_metadata_parse_method_signature (MonoImage *m, 439 int def, 440 const char *ptr, 441 const char **rptr); 442 MONO_API void mono_metadata_free_method_signature (MonoMethodSignature *method); 443 444 MONO_API mono_bool mono_metadata_signature_equal (MonoMethodSignature *sig1, 445 MonoMethodSignature *sig2); 446 447 MONO_API unsigned int mono_signature_hash (MonoMethodSignature *sig); 448 449 MONO_RT_EXTERNAL_ONLY 450 MONO_API MonoMethodHeader *mono_metadata_parse_mh (MonoImage *m, const char *ptr); 451 MONO_API void mono_metadata_free_mh (MonoMethodHeader *mh); 452 453 /* MonoMethodHeader acccessors */ 454 MONO_API const unsigned char* 455 mono_method_header_get_code (MonoMethodHeader *header, uint32_t* code_size, uint32_t* max_stack); 456 457 MONO_API MonoType** 458 mono_method_header_get_locals (MonoMethodHeader *header, uint32_t* num_locals, mono_bool *init_locals); 459 460 MONO_API int 461 mono_method_header_get_num_clauses (MonoMethodHeader *header); 462 463 MONO_API int 464 mono_method_header_get_clauses (MonoMethodHeader *header, MonoMethod *method, void **iter, MonoExceptionClause *clause); 465 466 MONO_API uint32_t 467 mono_type_to_unmanaged (MonoType *type, MonoMarshalSpec *mspec, 468 mono_bool as_field, mono_bool unicode, MonoMarshalConv *conv); 469 470 /* 471 * Makes a token based on a table and an index 472 */ 473 #define mono_metadata_make_token(table,idx) (((table) << 24)| (idx)) 474 475 /* 476 * Returns the table index that this token encodes. 477 */ 478 #define mono_metadata_token_table(token) ((token) >> 24) 479 480 /* 481 * Returns the index that a token refers to 482 */ 483 #define mono_metadata_token_index(token) ((token & 0xffffff)) 484 485 486 #define mono_metadata_token_code(token) ((token & 0xff000000)) 487 488 MONO_API uint32_t mono_metadata_token_from_dor (uint32_t dor_index); 489 490 MONO_API char *mono_guid_to_string (const uint8_t *guid); 491 492 MONO_API char *mono_guid_to_string_minimal (const uint8_t *guid); 493 494 MONO_API uint32_t mono_metadata_declsec_from_index (MonoImage *meta, uint32_t idx); 495 496 MONO_API uint32_t mono_metadata_translate_token_index (MonoImage *image, int table, uint32_t idx); 497 498 MONO_API void mono_metadata_decode_table_row (MonoImage *image, int table, 499 int idx, 500 uint32_t *res, 501 int res_size); 502 503 MONO_API uint32_t mono_metadata_decode_table_row_col (MonoImage *image, int table, 504 int idx, 505 unsigned int col); 506 507 MONO_END_DECLS 508 509 #endif /* __MONO_METADATA_H__ */ 510