1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: typelib validation, auxiliary functions
3 * related to the binary typelib format
5 * Copyright (C) 2005 Matthias Clasen
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
29 #include "gitypelib-internal.h"
30 #include "glib-compat.h"
34 GSList *context_stack;
37 #define ALIGN_VALUE(this, boundary) \
38 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
41 push_context (ValidateContext *ctx, const char *name)
43 ctx->context_stack = g_slist_prepend (ctx->context_stack, (char*)name);
47 pop_context (ValidateContext *ctx)
49 g_assert (ctx->context_stack != NULL);
50 ctx->context_stack = g_slist_delete_link (ctx->context_stack,
55 validate_interface_blob (ValidateContext *ctx,
60 get_dir_entry_checked (GITypelib *typelib,
64 Header *header = (Header *)typelib->data;
67 if (index == 0 || index > header->n_entries)
71 G_TYPELIB_ERROR_INVALID_BLOB,
72 "Invalid directory index %d", index);
76 offset = header->directory + (index - 1) * header->entry_blob_size;
78 if (typelib->len < offset + sizeof (DirEntry))
82 G_TYPELIB_ERROR_INVALID,
83 "The buffer is too short");
87 return (DirEntry *)&typelib->data[offset];
92 get_blob (GITypelib *typelib,
96 if (typelib->len < offset + sizeof (CommonBlob))
100 G_TYPELIB_ERROR_INVALID,
101 "The buffer is too short");
104 return (CommonBlob *)&typelib->data[offset];
107 static InterfaceTypeBlob *
108 get_type_blob (GITypelib *typelib,
109 SimpleTypeBlob *simple,
112 if (simple->offset == 0)
116 G_TYPELIB_ERROR_INVALID,
117 "Expected blob for type");
121 if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0)
125 G_TYPELIB_ERROR_INVALID,
126 "Expected non-basic type but got %d",
131 return (InterfaceTypeBlob*) get_blob (typelib, simple->offset, error);
135 g_typelib_get_dir_entry (GITypelib *typelib,
138 Header *header = (Header *)typelib->data;
140 return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size];
144 get_section_by_id (GITypelib *typelib,
145 SectionType section_type)
147 Header *header = (Header *)typelib->data;
150 if (header->sections == 0)
153 for (section = (Section*)&typelib->data[header->sections];
154 section->id != GI_SECTION_END;
157 if (section->id == section_type)
164 g_typelib_get_dir_entry_by_name (GITypelib *typelib,
169 const char *entry_name;
172 dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX);
173 n_entries = ((Header *)typelib->data)->n_local_entries;
175 if (dirindex == NULL)
177 for (i = 1; i <= n_entries; i++)
179 entry = g_typelib_get_dir_entry (typelib, i);
180 entry_name = g_typelib_get_string (typelib, entry->name);
181 if (strcmp (name, entry_name) == 0)
188 guint8 *hash = (guint8*) &typelib->data[dirindex->offset];
191 index = _gi_typelib_hash_search (hash, name, n_entries);
192 entry = g_typelib_get_dir_entry (typelib, index + 1);
193 entry_name = g_typelib_get_string (typelib, entry->name);
194 if (strcmp (name, entry_name) == 0)
201 g_typelib_get_dir_entry_by_gtype (GITypelib *typelib,
205 Header *header = (Header *)typelib->data;
206 guint n_entries = header->n_local_entries;
207 const char *gtype_name = g_type_name (gtype);
210 const char *c_prefix;
212 /* There is a corner case regarding GdkRectangle. GdkRectangle is a
213 boxed type, but it is just an alias to boxed struct
214 CairoRectangleInt. Scanner automatically converts all references
215 to GdkRectangle to CairoRectangleInt, so GdkRectangle does not
216 appear in the typelibs at all, although user code might query it.
217 So if we get such query, we also change it to lookup of
219 https://bugzilla.gnome.org/show_bug.cgi?id=655423 */
220 if (!fastpass && !strcmp (gtype_name, "GdkRectangle"))
221 gtype_name = "CairoRectangleInt";
223 /* Inside each typelib, we include the "C prefix" which acts as
224 * a namespace mechanism. For GtkTreeView, the C prefix is Gtk.
225 * Given the assumption that GTypes for a library also use the
226 * C prefix, we know we can skip examining a typelib if our
227 * target type does not have this typelib's C prefix.
229 * However, not every class library necessarily conforms to this,
230 * e.g. Clutter has Cogl inside it. So, we split this into two
231 * passes. First we try a lookup, skipping things which don't
232 * have the prefix. If that fails then we try a global lookup,
233 * ignoring the prefix.
235 * See http://bugzilla.gnome.org/show_bug.cgi?id=564016
237 c_prefix = g_typelib_get_string (typelib, header->c_prefix);
238 if (fastpass && c_prefix != NULL)
240 if (g_ascii_strncasecmp (c_prefix, gtype_name, strlen (c_prefix)) != 0)
244 for (i = 1; i <= n_entries; i++)
246 RegisteredTypeBlob *blob;
249 entry = g_typelib_get_dir_entry (typelib, i);
250 if (!BLOB_IS_REGISTERED_TYPE (entry))
253 blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]);
254 if (!blob->gtype_name)
257 type = g_typelib_get_string (typelib, blob->gtype_name);
258 if (strcmp (type, gtype_name) == 0)
265 g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib,
268 Header *header = (Header *)typelib->data;
269 guint n_entries = header->n_local_entries;
270 const char *domain_string = g_quark_to_string (error_domain);
274 for (i = 1; i <= n_entries; i++)
277 const char *enum_domain_string;
279 entry = g_typelib_get_dir_entry (typelib, i);
280 if (entry->blob_type != BLOB_TYPE_ENUM)
283 blob = (EnumBlob *)(&typelib->data[entry->offset]);
284 if (!blob->error_domain)
287 enum_domain_string = g_typelib_get_string (typelib, blob->error_domain);
288 if (strcmp (domain_string, enum_domain_string) == 0)
295 g_typelib_check_sanity (void)
297 /* Check that struct layout is as we expect */
299 gboolean size_check_ok = TRUE;
301 #define CHECK_SIZE(s,n) \
302 if (sizeof(s) != n) \
304 g_printerr ("sizeof("#s") is expected to be %d but is %"G_GSIZE_FORMAT".\n", \
306 size_check_ok = FALSE; \
309 /* When changing the size of a typelib structure, you are required to update
310 * the hardcoded size here. Do NOT change these to use sizeof(); these
311 * should match whatever is defined in the text specification and serve as
312 * a sanity check on structure modifications.
314 * Everything else in the code however should be using sizeof().
317 CHECK_SIZE (Header, 112);
318 CHECK_SIZE (DirEntry, 12);
319 CHECK_SIZE (SimpleTypeBlob, 4);
320 CHECK_SIZE (ArgBlob, 16);
321 CHECK_SIZE (SignatureBlob, 8);
322 CHECK_SIZE (CommonBlob, 8);
323 CHECK_SIZE (FunctionBlob, 20);
324 CHECK_SIZE (CallbackBlob, 12);
325 CHECK_SIZE (InterfaceTypeBlob, 4);
326 CHECK_SIZE (ArrayTypeBlob, 8);
327 CHECK_SIZE (ParamTypeBlob, 4);
328 CHECK_SIZE (ErrorTypeBlob, 4);
329 CHECK_SIZE (ValueBlob, 12);
330 CHECK_SIZE (FieldBlob, 16);
331 CHECK_SIZE (RegisteredTypeBlob, 16);
332 CHECK_SIZE (StructBlob, 32);
333 CHECK_SIZE (EnumBlob, 24);
334 CHECK_SIZE (PropertyBlob, 16);
335 CHECK_SIZE (SignalBlob, 16);
336 CHECK_SIZE (VFuncBlob, 20);
337 CHECK_SIZE (ObjectBlob, 60);
338 CHECK_SIZE (InterfaceBlob, 40);
339 CHECK_SIZE (ConstantBlob, 24);
340 CHECK_SIZE (AttributeBlob, 12);
341 CHECK_SIZE (UnionBlob, 40);
344 g_assert (size_check_ok);
349 is_aligned (guint32 offset)
351 return offset == ALIGN_VALUE (offset, 4);
354 #define MAX_NAME_LEN 200
357 get_string (GITypelib *typelib, guint32 offset, GError **error)
359 if (typelib->len < offset)
363 G_TYPELIB_ERROR_INVALID,
364 "Buffer is too short while looking up name");
368 return (const char*)&typelib->data[offset];
372 get_string_nofail (GITypelib *typelib, guint32 offset)
374 const char *ret = get_string (typelib, offset, NULL);
380 validate_name (GITypelib *typelib,
382 const guchar *data, guint32 offset,
387 name = get_string (typelib, offset, error);
391 if (!memchr (name, '\0', MAX_NAME_LEN))
395 G_TYPELIB_ERROR_INVALID,
396 "The %s is too long: %s",
401 if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name))
405 G_TYPELIB_ERROR_INVALID,
406 "The %s contains invalid characters: '%s'",
414 /* Fast path sanity check, operates on a memory blob */
416 validate_header_basic (const guint8 *memory,
420 Header *header = (Header *)memory;
422 if (len < sizeof (Header))
426 G_TYPELIB_ERROR_INVALID,
427 "The specified typelib length %" G_GSIZE_FORMAT " is too short",
432 if (strncmp (header->magic, G_IR_MAGIC, 16) != 0)
436 G_TYPELIB_ERROR_INVALID_HEADER,
437 "Invalid magic header");
442 if (header->major_version != 4)
446 G_TYPELIB_ERROR_INVALID_HEADER,
447 "Typelib version mismatch; expected 4, found %d",
448 header->major_version);
453 if (header->n_entries < header->n_local_entries)
457 G_TYPELIB_ERROR_INVALID_HEADER,
458 "Inconsistent entry counts");
462 if (header->size != len)
466 G_TYPELIB_ERROR_INVALID_HEADER,
467 "Typelib size %" G_GSIZE_FORMAT " does not match %" G_GSIZE_FORMAT,
468 (gsize) header->size, len);
472 /* This is a sanity check for a specific typelib; it
473 * prevents us from loading an incompatible typelib.
475 * The hardcoded checks in g_typelib_check_sanity to
476 * protect against inadvertent or buggy changes to the typelib format
480 if (header->entry_blob_size != sizeof (DirEntry) ||
481 header->function_blob_size != sizeof (FunctionBlob) ||
482 header->callback_blob_size != sizeof (CallbackBlob) ||
483 header->signal_blob_size != sizeof (SignalBlob) ||
484 header->vfunc_blob_size != sizeof (VFuncBlob) ||
485 header->arg_blob_size != sizeof (ArgBlob) ||
486 header->property_blob_size != sizeof (PropertyBlob) ||
487 header->field_blob_size != sizeof (FieldBlob) ||
488 header->value_blob_size != sizeof (ValueBlob) ||
489 header->constant_blob_size != sizeof (ConstantBlob) ||
490 header->attribute_blob_size != sizeof (AttributeBlob) ||
491 header->signature_blob_size != sizeof (SignatureBlob) ||
492 header->enum_blob_size != sizeof (EnumBlob) ||
493 header->struct_blob_size != sizeof (StructBlob) ||
494 header->object_blob_size != sizeof(ObjectBlob) ||
495 header->interface_blob_size != sizeof (InterfaceBlob) ||
496 header->union_blob_size != sizeof (UnionBlob))
500 G_TYPELIB_ERROR_INVALID_HEADER,
501 "Blob size mismatch");
505 if (!is_aligned (header->directory))
509 G_TYPELIB_ERROR_INVALID_HEADER,
510 "Misaligned directory");
514 if (!is_aligned (header->attributes))
518 G_TYPELIB_ERROR_INVALID_HEADER,
519 "Misaligned attributes");
523 if (header->attributes == 0 && header->n_attributes > 0)
527 G_TYPELIB_ERROR_INVALID_HEADER,
528 "Wrong number of attributes");
536 validate_header (ValidateContext *ctx,
539 GITypelib *typelib = ctx->typelib;
541 if (!validate_header_basic (typelib->data, typelib->len, error))
545 Header *header = (Header*)typelib->data;
546 if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error))
553 static gboolean validate_type_blob (GITypelib *typelib,
555 guint32 signature_offset,
556 gboolean return_type,
560 validate_array_type_blob (GITypelib *typelib,
562 guint32 signature_offset,
563 gboolean return_type,
566 /* FIXME validate length */
568 if (!validate_type_blob (typelib,
569 offset + G_STRUCT_OFFSET (ArrayTypeBlob, type),
577 validate_iface_type_blob (GITypelib *typelib,
579 guint32 signature_offset,
580 gboolean return_type,
583 InterfaceTypeBlob *blob;
584 InterfaceBlob *target;
586 blob = (InterfaceTypeBlob*)&typelib->data[offset];
588 target = (InterfaceBlob*) get_dir_entry_checked (typelib, blob->interface, error);
592 if (target->blob_type == 0) /* non-local */
599 validate_param_type_blob (GITypelib *typelib,
601 guint32 signature_offset,
602 gboolean return_type,
609 blob = (ParamTypeBlob*)&typelib->data[offset];
615 G_TYPELIB_ERROR_INVALID_BLOB,
616 "Pointer type exected for tag %d", blob->tag);
620 if (blob->n_types != n_params)
624 G_TYPELIB_ERROR_INVALID_BLOB,
625 "Parameter type number mismatch");
629 for (i = 0; i < n_params; i++)
631 if (!validate_type_blob (typelib,
632 offset + sizeof (ParamTypeBlob) +
633 i * sizeof (SimpleTypeBlob),
642 validate_error_type_blob (GITypelib *typelib,
644 guint32 signature_offset,
645 gboolean return_type,
650 blob = (ErrorTypeBlob*)&typelib->data[offset];
656 G_TYPELIB_ERROR_INVALID_BLOB,
657 "Pointer type exected for tag %d", blob->tag);
665 validate_type_blob (GITypelib *typelib,
667 guint32 signature_offset,
668 gboolean return_type,
671 SimpleTypeBlob *simple;
672 InterfaceTypeBlob *iface;
674 simple = (SimpleTypeBlob *)&typelib->data[offset];
676 if (simple->flags.reserved == 0 &&
677 simple->flags.reserved2 == 0)
679 if (!G_TYPE_TAG_IS_BASIC(simple->flags.tag))
683 G_TYPELIB_ERROR_INVALID_BLOB,
684 "Invalid non-basic tag %d in simple type", simple->flags.tag);
688 if (simple->flags.tag >= GI_TYPE_TAG_UTF8 &&
689 simple->flags.tag != GI_TYPE_TAG_UNICHAR &&
690 !simple->flags.pointer)
694 G_TYPELIB_ERROR_INVALID_BLOB,
695 "Pointer type exected for tag %d", simple->flags.tag);
702 iface = (InterfaceTypeBlob*)&typelib->data[simple->offset];
706 case GI_TYPE_TAG_ARRAY:
707 if (!validate_array_type_blob (typelib, simple->offset,
708 signature_offset, return_type, error))
711 case GI_TYPE_TAG_INTERFACE:
712 if (!validate_iface_type_blob (typelib, simple->offset,
713 signature_offset, return_type, error))
716 case GI_TYPE_TAG_GLIST:
717 case GI_TYPE_TAG_GSLIST:
718 if (!validate_param_type_blob (typelib, simple->offset,
719 signature_offset, return_type, 1, error))
722 case GI_TYPE_TAG_GHASH:
723 if (!validate_param_type_blob (typelib, simple->offset,
724 signature_offset, return_type, 2, error))
727 case GI_TYPE_TAG_ERROR:
728 if (!validate_error_type_blob (typelib, simple->offset,
729 signature_offset, return_type, error))
735 G_TYPELIB_ERROR_INVALID_BLOB,
736 "Wrong tag in complex type");
744 validate_arg_blob (GITypelib *typelib,
746 guint32 signature_offset,
751 if (typelib->len < offset + sizeof (ArgBlob))
755 G_TYPELIB_ERROR_INVALID,
756 "The buffer is too short");
760 blob = (ArgBlob*) &typelib->data[offset];
762 if (!validate_name (typelib, "argument", typelib->data, blob->name, error))
765 if (!validate_type_blob (typelib,
766 offset + G_STRUCT_OFFSET (ArgBlob, arg_type),
767 signature_offset, FALSE, error))
773 static SimpleTypeBlob *
774 return_type_from_signature (GITypelib *typelib,
779 if (typelib->len < offset + sizeof (SignatureBlob))
783 G_TYPELIB_ERROR_INVALID,
784 "The buffer is too short");
788 blob = (SignatureBlob*) &typelib->data[offset];
789 if (blob->return_type.offset == 0)
793 G_TYPELIB_ERROR_INVALID,
794 "No return type found in signature");
798 return (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (SignatureBlob, return_type)];
802 validate_signature_blob (GITypelib *typelib,
809 if (typelib->len < offset + sizeof (SignatureBlob))
813 G_TYPELIB_ERROR_INVALID,
814 "The buffer is too short");
818 blob = (SignatureBlob*) &typelib->data[offset];
820 if (blob->return_type.offset != 0)
822 if (!validate_type_blob (typelib,
823 offset + G_STRUCT_OFFSET (SignatureBlob, return_type),
824 offset, TRUE, error))
828 for (i = 0; i < blob->n_arguments; i++)
830 if (!validate_arg_blob (typelib,
831 offset + sizeof (SignatureBlob) +
832 i * sizeof (ArgBlob),
838 /* FIXME check constraints on return_value */
839 /* FIXME check array-length pairs */
844 validate_function_blob (ValidateContext *ctx,
846 guint16 container_type,
849 GITypelib *typelib = ctx->typelib;
852 if (typelib->len < offset + sizeof (FunctionBlob))
856 G_TYPELIB_ERROR_INVALID,
857 "The buffer is too short");
861 blob = (FunctionBlob*) &typelib->data[offset];
863 if (blob->blob_type != BLOB_TYPE_FUNCTION)
867 G_TYPELIB_ERROR_INVALID_BLOB,
868 "Wrong blob type %d, expected function", blob->blob_type);
872 if (!validate_name (typelib, "function", typelib->data, blob->name, error))
875 push_context (ctx, get_string_nofail (typelib, blob->name));
877 if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error))
880 if (blob->constructor)
882 switch (container_type)
884 case BLOB_TYPE_BOXED:
885 case BLOB_TYPE_STRUCT:
886 case BLOB_TYPE_UNION:
887 case BLOB_TYPE_OBJECT:
888 case BLOB_TYPE_INTERFACE:
893 G_TYPELIB_ERROR_INVALID_BLOB,
894 "Constructor not allowed");
899 if (blob->setter || blob->getter || blob->wraps_vfunc)
901 switch (container_type)
903 case BLOB_TYPE_OBJECT:
904 case BLOB_TYPE_INTERFACE:
909 G_TYPELIB_ERROR_INVALID_BLOB,
910 "Setter, getter or wrapper not allowed");
917 if (!(blob->setter || blob->getter || blob->wraps_vfunc))
921 G_TYPELIB_ERROR_INVALID_BLOB,
922 "Must be setter, getter or wrapper");
927 /* FIXME: validate index range */
929 if (!validate_signature_blob (typelib, blob->signature, error))
932 if (blob->constructor)
934 SimpleTypeBlob *simple = return_type_from_signature (typelib,
937 InterfaceTypeBlob *iface_type;
941 iface_type = get_type_blob (typelib, simple, error);
944 if (iface_type->tag != GI_TYPE_TAG_INTERFACE &&
945 (container_type == BLOB_TYPE_OBJECT ||
946 container_type == BLOB_TYPE_INTERFACE))
950 G_TYPELIB_ERROR_INVALID,
951 "Invalid return type '%s' for constructor '%s'",
952 g_type_tag_to_string (iface_type->tag),
953 get_string_nofail (typelib, blob->symbol));
964 validate_callback_blob (ValidateContext *ctx,
968 GITypelib *typelib = ctx->typelib;
971 if (typelib->len < offset + sizeof (CallbackBlob))
975 G_TYPELIB_ERROR_INVALID,
976 "The buffer is too short");
980 blob = (CallbackBlob*) &typelib->data[offset];
982 if (blob->blob_type != BLOB_TYPE_CALLBACK)
986 G_TYPELIB_ERROR_INVALID_BLOB,
991 if (!validate_name (typelib, "callback", typelib->data, blob->name, error))
994 push_context (ctx, get_string_nofail (typelib, blob->name));
996 if (!validate_signature_blob (typelib, blob->signature, error))
1005 validate_constant_blob (GITypelib *typelib,
1009 guint value_size[] = {
1034 SimpleTypeBlob *type;
1036 g_assert (G_N_ELEMENTS (value_size) == GI_TYPE_TAG_N_TYPES);
1038 if (typelib->len < offset + sizeof (ConstantBlob))
1042 G_TYPELIB_ERROR_INVALID,
1043 "The buffer is too short");
1047 blob = (ConstantBlob*) &typelib->data[offset];
1049 if (blob->blob_type != BLOB_TYPE_CONSTANT)
1053 G_TYPELIB_ERROR_INVALID_BLOB,
1058 if (!validate_name (typelib, "constant", typelib->data, blob->name, error))
1061 if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type),
1065 if (!is_aligned (blob->offset))
1069 G_TYPELIB_ERROR_INVALID_BLOB,
1070 "Misaligned constant value");
1074 type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)];
1075 if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
1077 if (type->flags.tag == 0)
1081 G_TYPELIB_ERROR_INVALID_BLOB,
1082 "Constant value type void");
1086 if (value_size[type->flags.tag] != 0 &&
1087 blob->size != value_size[type->flags.tag])
1091 G_TYPELIB_ERROR_INVALID_BLOB,
1092 "Constant value size mismatch");
1095 /* FIXME check string values */
1102 validate_value_blob (GITypelib *typelib,
1108 if (typelib->len < offset + sizeof (ValueBlob))
1112 G_TYPELIB_ERROR_INVALID,
1113 "The buffer is too short");
1117 blob = (ValueBlob*) &typelib->data[offset];
1119 if (!validate_name (typelib, "value", typelib->data, blob->name, error))
1126 validate_field_blob (ValidateContext *ctx,
1130 GITypelib *typelib = ctx->typelib;
1131 Header *header = (Header *)typelib->data;
1134 if (typelib->len < offset + sizeof (FieldBlob))
1138 G_TYPELIB_ERROR_INVALID,
1139 "The buffer is too short");
1143 blob = (FieldBlob*) &typelib->data[offset];
1145 if (!validate_name (typelib, "field", typelib->data, blob->name, error))
1148 if (blob->has_embedded_type)
1150 if (!validate_callback_blob (ctx, offset + header->field_blob_size, error))
1153 else if (!validate_type_blob (typelib,
1154 offset + G_STRUCT_OFFSET (FieldBlob, type),
1162 validate_property_blob (GITypelib *typelib,
1168 if (typelib->len < offset + sizeof (PropertyBlob))
1172 G_TYPELIB_ERROR_INVALID,
1173 "The buffer is too short");
1177 blob = (PropertyBlob*) &typelib->data[offset];
1179 if (!validate_name (typelib, "property", typelib->data, blob->name, error))
1182 if (!validate_type_blob (typelib,
1183 offset + G_STRUCT_OFFSET (PropertyBlob, type),
1191 validate_signal_blob (GITypelib *typelib,
1193 guint32 container_offset,
1199 if (typelib->len < offset + sizeof (SignalBlob))
1203 G_TYPELIB_ERROR_INVALID,
1204 "The buffer is too short");
1208 blob = (SignalBlob*) &typelib->data[offset];
1210 if (!validate_name (typelib, "signal", typelib->data, blob->name, error))
1213 if ((blob->run_first != 0) +
1214 (blob->run_last != 0) +
1215 (blob->run_cleanup != 0) != 1)
1219 G_TYPELIB_ERROR_INVALID_BLOB,
1220 "Invalid signal run flags");
1224 if (blob->has_class_closure)
1226 if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
1230 object = (ObjectBlob*)&typelib->data[container_offset];
1232 n_signals = object->n_signals;
1236 InterfaceBlob *iface;
1238 iface = (InterfaceBlob*)&typelib->data[container_offset];
1240 n_signals = iface->n_signals;
1243 if (blob->class_closure >= n_signals)
1247 G_TYPELIB_ERROR_INVALID_BLOB,
1248 "Invalid class closure index");
1253 if (!validate_signature_blob (typelib, blob->signature, error))
1260 validate_vfunc_blob (GITypelib *typelib,
1262 guint32 container_offset,
1268 if (typelib->len < offset + sizeof (VFuncBlob))
1272 G_TYPELIB_ERROR_INVALID,
1273 "The buffer is too short");
1277 blob = (VFuncBlob*) &typelib->data[offset];
1279 if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error))
1282 if (blob->class_closure)
1284 if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT)
1288 object = (ObjectBlob*)&typelib->data[container_offset];
1290 n_vfuncs = object->n_vfuncs;
1294 InterfaceBlob *iface;
1296 iface = (InterfaceBlob*)&typelib->data[container_offset];
1298 n_vfuncs = iface->n_vfuncs;
1301 if (blob->class_closure >= n_vfuncs)
1305 G_TYPELIB_ERROR_INVALID_BLOB,
1306 "Invalid class closure index");
1311 if (!validate_signature_blob (typelib, blob->signature, error))
1318 validate_struct_blob (ValidateContext *ctx,
1323 GITypelib *typelib = ctx->typelib;
1326 guint32 field_offset;
1328 if (typelib->len < offset + sizeof (StructBlob))
1332 G_TYPELIB_ERROR_INVALID,
1333 "The buffer is too short");
1337 blob = (StructBlob*) &typelib->data[offset];
1339 if (blob->blob_type != blob_type)
1343 G_TYPELIB_ERROR_INVALID_BLOB,
1348 if (!validate_name (typelib, "struct", typelib->data, blob->name, error))
1351 push_context (ctx, get_string_nofail (typelib, blob->name));
1353 if (!blob->unregistered)
1355 if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error))
1358 if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error))
1363 if (blob->gtype_name || blob->gtype_init)
1367 G_TYPELIB_ERROR_INVALID_BLOB,
1368 "Gtype data in struct");
1373 if (typelib->len < offset + sizeof (StructBlob) +
1374 blob->n_fields * sizeof (FieldBlob) +
1375 blob->n_methods * sizeof (FunctionBlob))
1379 G_TYPELIB_ERROR_INVALID,
1380 "The buffer is too short");
1384 field_offset = offset + sizeof (StructBlob);
1385 for (i = 0; i < blob->n_fields; i++)
1387 FieldBlob *blob = (FieldBlob*) &typelib->data[field_offset];
1389 if (!validate_field_blob (ctx,
1394 field_offset += sizeof (FieldBlob);
1395 if (blob->has_embedded_type)
1396 field_offset += sizeof (CallbackBlob);
1399 for (i = 0; i < blob->n_methods; i++)
1401 if (!validate_function_blob (ctx,
1403 i * sizeof (FunctionBlob),
1415 validate_enum_blob (ValidateContext *ctx,
1420 GITypelib *typelib = ctx->typelib;
1425 if (typelib->len < offset + sizeof (EnumBlob))
1429 G_TYPELIB_ERROR_INVALID,
1430 "The buffer is too short");
1434 blob = (EnumBlob*) &typelib->data[offset];
1436 if (blob->blob_type != blob_type)
1440 G_TYPELIB_ERROR_INVALID_BLOB,
1445 if (!blob->unregistered)
1447 if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error))
1450 if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error))
1455 if (blob->gtype_name || blob->gtype_init)
1459 G_TYPELIB_ERROR_INVALID_BLOB,
1460 "Gtype data in unregistered enum");
1465 if (!validate_name (typelib, "enum", typelib->data, blob->name, error))
1468 if (typelib->len < offset + sizeof (EnumBlob) +
1469 blob->n_values * sizeof (ValueBlob) +
1470 blob->n_methods * sizeof (FunctionBlob))
1474 G_TYPELIB_ERROR_INVALID,
1475 "The buffer is too short");
1479 offset2 = offset + sizeof (EnumBlob);
1481 push_context (ctx, get_string_nofail (typelib, blob->name));
1483 for (i = 0; i < blob->n_values; i++, offset2 += sizeof (ValueBlob))
1485 if (!validate_value_blob (typelib,
1491 v1 = (ValueBlob *)&typelib->data[offset2];
1492 for (j = 0; j < i; j++)
1494 v2 = (ValueBlob *)&typelib->data[offset2 +
1495 j * sizeof (ValueBlob)];
1497 if (v1->value == v2->value)
1500 /* FIXME should this be an error ? */
1503 G_TYPELIB_ERROR_INVALID_BLOB,
1504 "Duplicate enum value");
1511 for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
1513 if (!validate_function_blob (ctx, offset2, BLOB_TYPE_ENUM, error))
1523 validate_object_blob (ValidateContext *ctx,
1527 GITypelib *typelib = ctx->typelib;
1533 header = (Header *)typelib->data;
1535 if (typelib->len < offset + sizeof (ObjectBlob))
1539 G_TYPELIB_ERROR_INVALID,
1540 "The buffer is too short");
1544 blob = (ObjectBlob*) &typelib->data[offset];
1546 if (blob->blob_type != BLOB_TYPE_OBJECT)
1550 G_TYPELIB_ERROR_INVALID_BLOB,
1555 if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error))
1558 if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error))
1561 if (!validate_name (typelib, "object", typelib->data, blob->name, error))
1564 if (blob->parent > header->n_entries)
1568 G_TYPELIB_ERROR_INVALID_BLOB,
1569 "Invalid parent index");
1573 if (blob->parent != 0)
1577 entry = get_dir_entry_checked (typelib, blob->parent, error);
1580 if (entry->blob_type != BLOB_TYPE_OBJECT &&
1581 (entry->local || entry->blob_type != 0))
1585 G_TYPELIB_ERROR_INVALID_BLOB,
1586 "Parent not object");
1591 if (blob->gtype_struct != 0)
1595 entry = get_dir_entry_checked (typelib, blob->gtype_struct, error);
1598 if (entry->blob_type != BLOB_TYPE_STRUCT && entry->local)
1602 G_TYPELIB_ERROR_INVALID_BLOB,
1603 "Class struct invalid type or not local");
1608 if (typelib->len < offset + sizeof (ObjectBlob) +
1609 (blob->n_interfaces + blob->n_interfaces % 2) * 2 +
1610 blob->n_fields * sizeof (FieldBlob) +
1611 blob->n_properties * sizeof (PropertyBlob) +
1612 blob->n_methods * sizeof (FunctionBlob) +
1613 blob->n_signals * sizeof (SignalBlob) +
1614 blob->n_vfuncs * sizeof (VFuncBlob) +
1615 blob->n_constants * sizeof (ConstantBlob))
1620 G_TYPELIB_ERROR_INVALID,
1621 "The buffer is too short");
1625 offset2 = offset + sizeof (ObjectBlob);
1627 for (i = 0; i < blob->n_interfaces; i++, offset2 += 2)
1632 iface = *(guint16*)&typelib->data[offset2];
1633 if (iface == 0 || iface > header->n_entries)
1637 G_TYPELIB_ERROR_INVALID_BLOB,
1638 "Invalid interface index");
1642 entry = get_dir_entry_checked (typelib, iface, error);
1646 if (entry->blob_type != BLOB_TYPE_INTERFACE &&
1647 (entry->local || entry->blob_type != 0))
1651 G_TYPELIB_ERROR_INVALID_BLOB,
1652 "Not an interface");
1657 offset2 += 2 * (blob->n_interfaces %2);
1659 push_context (ctx, get_string_nofail (typelib, blob->name));
1661 for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob))
1663 if (!validate_field_blob (ctx, offset2, error))
1667 for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
1669 if (!validate_property_blob (typelib, offset2, error))
1673 for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
1675 if (!validate_function_blob (ctx, offset2, BLOB_TYPE_OBJECT, error))
1679 for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
1681 if (!validate_signal_blob (typelib, offset2, offset, error))
1685 for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
1687 if (!validate_vfunc_blob (typelib, offset2, offset, error))
1691 for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
1693 if (!validate_constant_blob (typelib, offset2, error))
1703 validate_interface_blob (ValidateContext *ctx,
1707 GITypelib *typelib = ctx->typelib;
1709 InterfaceBlob *blob;
1713 header = (Header *)typelib->data;
1715 if (typelib->len < offset + sizeof (InterfaceBlob))
1719 G_TYPELIB_ERROR_INVALID,
1720 "The buffer is too short");
1724 blob = (InterfaceBlob*) &typelib->data[offset];
1726 if (blob->blob_type != BLOB_TYPE_INTERFACE)
1730 G_TYPELIB_ERROR_INVALID_BLOB,
1731 "Wrong blob type; expected interface, got %d", blob->blob_type);
1735 if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error))
1738 if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error))
1741 if (!validate_name (typelib, "interface", typelib->data, blob->name, error))
1744 if (typelib->len < offset + sizeof (InterfaceBlob) +
1745 (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 +
1746 blob->n_properties * sizeof (PropertyBlob) +
1747 blob->n_methods * sizeof (FunctionBlob) +
1748 blob->n_signals * sizeof (SignalBlob) +
1749 blob->n_vfuncs * sizeof (VFuncBlob) +
1750 blob->n_constants * sizeof (ConstantBlob))
1755 G_TYPELIB_ERROR_INVALID,
1756 "The buffer is too short");
1760 offset2 = offset + sizeof (InterfaceBlob);
1762 for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2)
1767 req = *(guint16*)&typelib->data[offset2];
1768 if (req == 0 || req > header->n_entries)
1772 G_TYPELIB_ERROR_INVALID_BLOB,
1773 "Invalid prerequisite index");
1777 entry = g_typelib_get_dir_entry (typelib, req);
1778 if (entry->blob_type != BLOB_TYPE_INTERFACE &&
1779 entry->blob_type != BLOB_TYPE_OBJECT &&
1780 (entry->local || entry->blob_type != 0))
1784 G_TYPELIB_ERROR_INVALID_BLOB,
1785 "Not an interface or object");
1790 offset2 += 2 * (blob->n_prerequisites % 2);
1792 push_context (ctx, get_string_nofail (typelib, blob->name));
1794 for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob))
1796 if (!validate_property_blob (typelib, offset2, error))
1800 for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob))
1802 if (!validate_function_blob (ctx, offset2, BLOB_TYPE_INTERFACE, error))
1806 for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob))
1808 if (!validate_signal_blob (typelib, offset2, offset, error))
1812 for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob))
1814 if (!validate_vfunc_blob (typelib, offset2, offset, error))
1818 for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob))
1820 if (!validate_constant_blob (typelib, offset2, error))
1830 validate_union_blob (GITypelib *typelib,
1838 validate_blob (ValidateContext *ctx,
1842 GITypelib *typelib = ctx->typelib;
1845 if (typelib->len < offset + sizeof (CommonBlob))
1849 G_TYPELIB_ERROR_INVALID,
1850 "The buffer is too short");
1854 common = (CommonBlob*)&typelib->data[offset];
1856 switch (common->blob_type)
1858 case BLOB_TYPE_FUNCTION:
1859 if (!validate_function_blob (ctx, offset, 0, error))
1862 case BLOB_TYPE_CALLBACK:
1863 if (!validate_callback_blob (ctx, offset, error))
1866 case BLOB_TYPE_STRUCT:
1867 case BLOB_TYPE_BOXED:
1868 if (!validate_struct_blob (ctx, offset, common->blob_type, error))
1871 case BLOB_TYPE_ENUM:
1872 case BLOB_TYPE_FLAGS:
1873 if (!validate_enum_blob (ctx, offset, common->blob_type, error))
1876 case BLOB_TYPE_OBJECT:
1877 if (!validate_object_blob (ctx, offset, error))
1880 case BLOB_TYPE_INTERFACE:
1881 if (!validate_interface_blob (ctx, offset, error))
1884 case BLOB_TYPE_CONSTANT:
1885 if (!validate_constant_blob (typelib, offset, error))
1888 case BLOB_TYPE_UNION:
1889 if (!validate_union_blob (typelib, offset, error))
1895 G_TYPELIB_ERROR_INVALID_ENTRY,
1896 "Invalid blob type");
1904 validate_directory (ValidateContext *ctx,
1907 GITypelib *typelib = ctx->typelib;
1908 Header *header = (Header *)typelib->data;
1912 if (typelib->len < header->directory + header->n_entries * sizeof (DirEntry))
1916 G_TYPELIB_ERROR_INVALID,
1917 "The buffer is too short");
1921 for (i = 0; i < header->n_entries; i++)
1923 entry = g_typelib_get_dir_entry (typelib, i + 1);
1925 if (!validate_name (typelib, "entry", typelib->data, entry->name, error))
1928 if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) ||
1929 entry->blob_type > BLOB_TYPE_UNION)
1933 G_TYPELIB_ERROR_INVALID_DIRECTORY,
1934 "Invalid entry type");
1938 if (i < header->n_local_entries)
1944 G_TYPELIB_ERROR_INVALID_DIRECTORY,
1945 "Too few local directory entries");
1949 if (!is_aligned (entry->offset))
1953 G_TYPELIB_ERROR_INVALID_DIRECTORY,
1954 "Misaligned entry");
1958 if (!validate_blob (ctx, entry->offset, error))
1967 G_TYPELIB_ERROR_INVALID_DIRECTORY,
1968 "Too many local directory entries");
1972 if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error))
1981 validate_attributes (ValidateContext *ctx,
1984 GITypelib *typelib = ctx->typelib;
1985 Header *header = (Header *)typelib->data;
1987 if (header->size < header->attributes + header->n_attributes * sizeof (AttributeBlob))
1991 G_TYPELIB_ERROR_INVALID,
1992 "The buffer is too short");
2000 prefix_with_context (GError **error,
2001 const char *section,
2002 ValidateContext *ctx)
2004 GString *str = g_string_new (NULL);
2008 link = ctx->context_stack;
2011 g_prefix_error (error, "In %s:", section);
2015 for (; link; link = link->next)
2017 g_string_append (str, link->data);
2019 g_string_append_c (str, '/');
2021 g_string_append_c (str, ')');
2022 buf = g_string_free (str, FALSE);
2023 g_prefix_error (error, "In %s (Context: %s): ", section, buf);
2028 g_typelib_validate (GITypelib *typelib,
2031 ValidateContext ctx;
2032 ctx.typelib = typelib;
2033 ctx.context_stack = NULL;
2035 if (!validate_header (&ctx, error))
2037 prefix_with_context (error, "In header", &ctx);
2041 if (!validate_directory (&ctx, error))
2043 prefix_with_context (error, "directory", &ctx);
2047 if (!validate_attributes (&ctx, error))
2049 prefix_with_context (error, "attributes", &ctx);
2057 g_typelib_error_quark (void)
2059 static GQuark quark = 0;
2061 quark = g_quark_from_static_string ("g-typelib-error-quark");
2065 static GSList *library_paths;
2068 * g_irepository_prepend_library_path:
2069 * @directory: (type filename): a single directory to scan for shared libraries
2071 * Prepends @directory to the search path that is used to
2072 * search shared libraries referenced by imported namespaces.
2073 * Multiple calls to this function all contribute to the final
2075 * The list of paths is unique and shared for all #GIRepository
2076 * instances across the process, but it doesn't affect namespaces
2077 * imported before the call.
2079 * If the library is not found in the directories configured
2080 * in this way, loading will fall back to the system library
2081 * path (ie. LD_LIBRARY_PATH and DT_RPATH in ELF systems).
2082 * See the documentation of your dynamic linker for full details.
2087 g_irepository_prepend_library_path (const char *directory)
2089 library_paths = g_slist_prepend (library_paths,
2090 g_strdup (directory));
2093 /* Note on the GModule flags used by this function:
2095 * Glade's autoconnect feature and OpenGL's extension mechanism
2096 * as used by Clutter rely on g_module_open(NULL) to work as a means of
2097 * accessing the app's symbols. This keeps us from using
2098 * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well;
2099 * in general libraries are not expecting multiple copies of
2100 * themselves and are not expecting to be unloaded. So we just
2101 * load modules globally for now.
2104 load_one_shared_library (const char *shlib)
2109 if (!g_path_is_absolute (shlib))
2111 /* First try in configured library paths */
2112 for (p = library_paths; p; p = p->next)
2114 char *path = g_build_filename (p->data, shlib, NULL);
2116 m = g_module_open (path, G_MODULE_BIND_LAZY);
2124 /* Then try loading from standard paths */
2125 /* Do not attempt to fix up shlib to replace .la with .so:
2126 it's done by GModule anyway.
2128 return g_module_open (shlib, G_MODULE_BIND_LAZY);
2132 _g_typelib_do_dlopen (GITypelib *typelib)
2135 const char *shlib_str;
2137 header = (Header *) typelib->data;
2138 /* note that NULL shlib means to open the main app, which is allowed */
2139 if (header->shared_library)
2140 shlib_str = g_typelib_get_string (typelib, header->shared_library);
2144 if (shlib_str != NULL && shlib_str[0] != '\0')
2149 /* shared-library is a comma-separated list of libraries */
2150 shlibs = g_strsplit (shlib_str, ",", 0);
2152 /* We load all passed libs unconditionally as if the same library is loaded
2153 * again with g_module_open(), the same file handle will be returned. See bug:
2154 * http://bugzilla.gnome.org/show_bug.cgi?id=555294
2156 for (i = 0; shlibs[i]; i++)
2160 module = load_one_shared_library (shlibs[i]);
2164 g_warning ("Failed to load shared library '%s' referenced by the typelib: %s",
2165 shlibs[i], g_module_error ());
2169 typelib->modules = g_list_append (typelib->modules, module);
2173 g_strfreev (shlibs);
2177 /* If there's no shared-library entry for this module, assume that
2178 * the module is for the application. Some of the hand-written .gir files
2179 * in gobject-introspection don't have shared-library entries, but no one
2180 * is really going to be calling g_module_symbol on them either.
2182 GModule *module = g_module_open (NULL, 0);
2184 g_warning ("gtypelib.c: Failed to g_module_open (NULL): %s", g_module_error ());
2186 typelib->modules = g_list_prepend (typelib->modules, module);
2191 _g_typelib_ensure_open (GITypelib *typelib)
2193 if (typelib->open_attempted)
2195 typelib->open_attempted = TRUE;
2196 _g_typelib_do_dlopen (typelib);
2200 * g_typelib_new_from_memory: (skip)
2201 * @memory: address of memory chunk containing the typelib
2202 * @len: length of memory chunk containing the typelib
2205 * Creates a new #GITypelib from a memory location. The memory block
2206 * pointed to by @typelib will be automatically g_free()d when the
2207 * repository is destroyed.
2209 * Return value: the new #GITypelib
2212 g_typelib_new_from_memory (guint8 *memory,
2218 if (!validate_header_basic (memory, len, error))
2221 meta = g_slice_new0 (GITypelib);
2222 meta->data = memory;
2224 meta->owns_memory = TRUE;
2225 meta->modules = NULL;
2231 * g_typelib_new_from_const_memory: (skip)
2232 * @memory: address of memory chunk containing the typelib
2233 * @len: length of memory chunk containing the typelib
2236 * Creates a new #GITypelib from a memory location.
2238 * Return value: the new #GITypelib
2241 g_typelib_new_from_const_memory (const guchar *memory,
2247 if (!validate_header_basic (memory, len, error))
2250 meta = g_slice_new0 (GITypelib);
2251 meta->data = (guchar *) memory;
2253 meta->owns_memory = FALSE;
2254 meta->modules = NULL;
2260 * g_typelib_new_from_mapped_file: (skip)
2261 * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed
2264 * Creates a new #GITypelib from a #GMappedFile.
2266 * Return value: the new #GITypelib
2269 g_typelib_new_from_mapped_file (GMappedFile *mfile,
2273 guint8 *data = (guint8 *) g_mapped_file_get_contents (mfile);
2274 gsize len = g_mapped_file_get_length (mfile);
2276 if (!validate_header_basic (data, len, error))
2279 meta = g_slice_new0 (GITypelib);
2280 meta->mfile = mfile;
2281 meta->owns_memory = FALSE;
2290 * @typelib: a #GITypelib
2292 * Free a #GITypelib.
2295 g_typelib_free (GITypelib *typelib)
2298 g_mapped_file_unref (typelib->mfile);
2300 if (typelib->owns_memory)
2301 g_free (typelib->data);
2302 if (typelib->modules)
2304 g_list_foreach (typelib->modules, (GFunc) g_module_close, NULL);
2305 g_list_free (typelib->modules);
2307 g_slice_free (GITypelib, typelib);
2311 g_typelib_get_namespace (GITypelib *typelib)
2313 return g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace);
2318 * @typelib: the typelib
2319 * @symbol_name: name of symbol to be loaded
2320 * @symbol: returns a pointer to the symbol value
2322 * Loads a symbol from #GITypelib.
2324 * Return value: #TRUE on success
2327 g_typelib_symbol (GITypelib *typelib, const char *symbol_name, gpointer *symbol)
2331 _g_typelib_ensure_open (typelib);
2334 * The reason for having multiple modules dates from gir-repository
2335 * when it was desired to inject code (accessors, etc.) into an
2336 * existing library. In that situation, the first module listed
2337 * will be the custom one, which overrides the main one. A bit
2338 * inefficient, but the problem will go away when gir-repository
2341 * For modules with no shared library, we dlopen'd the current
2344 for (l = typelib->modules; l; l = l->next)
2346 GModule *module = l->data;
2348 if (g_module_symbol (module, symbol_name, symbol))