Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Tue Jul 1 11:45:40 CEST 2003 Paolo Molaro <lupus@ximian.com>

	* image.h, image.c: added support to load an assembly from a byte array.
	* Makefile.am, assembly.c, make-bundle.pl, sample-bundle: added
	assembly bundle support.

svn path=/trunk/mono/; revision=15804
  • Loading branch information...
commit a86efec34a5732f94c4db128f5c5aa904759c2a5 1 parent 4bb7c84
Paolo Molaro authored July 01, 2003
7  mono/metadata/ChangeLog
... ...
@@ -1,3 +1,10 @@
  1
+
  2
+Tue Jul 1 11:45:40 CEST 2003 Paolo Molaro <lupus@ximian.com>
  3
+
  4
+	* image.h, image.c: added support to load an assembly from a byte array.
  5
+	* Makefile.am, assembly.c, make-bundle.pl, sample-bundle: added 
  6
+	assembly bundle support.
  7
+
1 8
 2003-06-27  Dietmar Maurer  <dietmar@ximian.com>
2 9
 
3 10
 	* threadpool.c (mono_thread_pool_add): keep a reference to the
13  mono/metadata/Makefile.am
@@ -21,6 +21,14 @@ noinst_LTLIBRARIES = libmetadata.la libmonoruntime.la
21 21
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/mono $(LIBGC_CFLAGS) $(GLIB_CFLAGS) $(GMODULE_CFLAGS) \
22 22
 	-DMONO_ASSEMBLIES=\"$(assembliesdir)\" -DMONO_CFG_DIR=\"$(confdir)\"
23 23
 
  24
+if WITH_BUNDLE
  25
+bundle_srcs = mono-bundle.s mono-bundle.h
  26
+mono-bundle.s mono-bundle.h: $(BUNDLE_FILE) $(srcdir)/make-bundle.pl
  27
+	perl $(srcdir)/make-bundle.pl $(BUNDLE_FILE) mono-bundle.h mono-bundle.s
  28
+else
  29
+bundle_srcs =
  30
+endif
  31
+
24 32
 libmonoruntime_la_SOURCES = \
25 33
 	reflection.c	\
26 34
 	object.c	\
@@ -78,6 +86,7 @@ libmetadata_la_SOURCES = \
78 86
 	loader.c	\
79 87
 	class.c		\
80 88
 	mempool.c	\
  89
+	$(bundle_srcs)	\
81 90
 	debug-helpers.c
82 91
 
83 92
 libmetadataincludedir = $(includedir)/mono/metadata
@@ -134,3 +143,7 @@ monosn_LDADD = \
134 143
 	$(GMODULE_LIBS) 		\
135 144
 	-lm
136 145
 
  146
+BUILT_SOURCES = $(bundle_srcs)
  147
+
  148
+EXTRA_DIST = make-bundle.pl sample-bundle
  149
+
48  mono/metadata/assembly.c
@@ -19,6 +19,9 @@
19 19
 #include "image.h"
20 20
 #include "cil-coff.h"
21 21
 #include "rawbuffer.h"
  22
+#ifdef WITH_BUNDLE
  23
+#include "mono-bundle.h"
  24
+#endif
22 25
 
23 26
 /* the default search path is just MONO_ASSEMBLIES */
24 27
 static const char*
@@ -310,6 +313,49 @@ absolute_dir (const gchar *filename)
310 313
 	return res;
311 314
 }
312 315
 
  316
+static MonoImage*
  317
+do_mono_assembly_open (const char *filename, MonoImageOpenStatus *status)
  318
+{
  319
+	MonoImage *image = NULL;
  320
+#ifdef WITH_BUNDLE
  321
+	int i;
  322
+	char *name = g_path_get_basename (filename);
  323
+	char *dot = strrchr (name, '.');
  324
+	GList *tmp;
  325
+	MonoAssembly *ass;
  326
+	
  327
+	if (dot)
  328
+		*dot = 0;
  329
+	if (strcmp (name, "corlib") == 0) {
  330
+		g_free (name);
  331
+		name = g_strdup ("mscorlib");
  332
+	}
  333
+	/* we do a very simple search for bundled assemblies: it's not a general purpouse
  334
+	 * assembly loading mechanism.
  335
+	 */
  336
+	for (tmp = loaded_assemblies; tmp; tmp = tmp->next) {
  337
+		ass = tmp->data;
  338
+		if (!ass->aname.name)
  339
+			continue;
  340
+		if (strcmp (name, ass->aname.name))
  341
+			continue;
  342
+		image = ass->image;
  343
+		break;
  344
+	}
  345
+	for (i = 0; !image && bundled_assemblies [i]; ++i) {
  346
+		if (strcmp (bundled_assemblies [i]->name, name) == 0) {
  347
+			image = mono_image_open_from_data ((char*)bundled_assemblies [i]->data, bundled_assemblies [i]->size, FALSE, status);
  348
+			break;
  349
+		}
  350
+	}
  351
+	g_free (name);
  352
+	if (image)
  353
+		return image;
  354
+#endif
  355
+	image = mono_image_open (filename, status);
  356
+	return image;
  357
+}
  358
+
313 359
 /**
314 360
  * mono_assembly_open:
315 361
  * @filename: Opens the assembly pointed out by this name
@@ -364,7 +410,7 @@ mono_assembly_open (const char *filename, MonoImageOpenStatus *status)
364 410
 	}
365 411
 
366 412
 	/* g_print ("file loading %s\n", fname); */
367  
-	image = mono_image_open (fname, status);
  413
+	image = do_mono_assembly_open (fname, status);
368 414
 
369 415
 	if (!image){
370 416
 		*status = MONO_IMAGE_ERROR_ERRNO;
190  mono/metadata/image.c
@@ -2,13 +2,12 @@
2 2
  * image.c: Routines for manipulating an image stored in an
3 3
  * extended PE/COFF file.
4 4
  * 
5  
- * Author:
  5
+ * Authors:
6 6
  *   Miguel de Icaza (miguel@ximian.com)
  7
+ *   Paolo Molaro (lupus@ximian.com)
7 8
  *
8  
- * (C) 2001 Ximian, Inc.  http://www.ximian.com
  9
+ * (C) 2001-2003 Ximian, Inc.  http://www.ximian.com
9 10
  *
10  
- * TODO:
11  
- *   Implement big-endian versions of the reading routines.
12 11
  */
13 12
 #include <config.h>
14 13
 #include <stdio.h>
@@ -93,6 +92,13 @@ mono_image_ensure_section_idx (MonoImage *image, int section)
93 92
 	
94 93
 	writable = sect->st_flags & SECT_FLAGS_MEM_WRITE;
95 94
 
  95
+	if (!image->f) {
  96
+		if (sect->st_raw_data_ptr + sect->st_raw_data_size > image->raw_data_len)
  97
+			return FALSE;
  98
+		/* FIXME: we ignore the writable flag since we don't patch the binary */
  99
+		iinfo->cli_sections [section] = image->raw_data + sect->st_raw_data_ptr;
  100
+		return TRUE;
  101
+	}
96 102
 	iinfo->cli_sections [section] = mono_raw_buffer_load (
97 103
 		fileno (image->f), writable,
98 104
 		sect->st_raw_data_ptr, sect->st_raw_data_size);
@@ -129,7 +135,7 @@ mono_image_ensure_section (MonoImage *image, const char *section)
129 135
 }
130 136
 
131 137
 static int
132  
-load_section_tables (MonoImage *image, MonoCLIImageInfo *iinfo)
  138
+load_section_tables (MonoImage *image, MonoCLIImageInfo *iinfo, guint32 offset)
133 139
 {
134 140
 	const int top = iinfo->cli_header.coff.coff_sections;
135 141
 	int i;
@@ -140,9 +146,16 @@ load_section_tables (MonoImage *image, MonoCLIImageInfo *iinfo)
140 146
 	
141 147
 	for (i = 0; i < top; i++){
142 148
 		MonoSectionTable *t = &iinfo->cli_section_tables [i];
143  
-		
144  
-		if (fread (t, sizeof (MonoSectionTable), 1, image->f) != 1)
145  
-			return FALSE;
  149
+
  150
+		if (!image->f) {
  151
+			if (offset + sizeof (MonoSectionTable) > image->raw_data_len)
  152
+				return FALSE;
  153
+			memcpy (t, image->raw_data + offset, sizeof (MonoSectionTable));
  154
+			offset += sizeof (MonoSectionTable);
  155
+		} else {
  156
+			if (fread (t, sizeof (MonoSectionTable), 1, image->f) != 1)
  157
+				return FALSE;
  158
+		}
146 159
 
147 160
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
148 161
 		t->st_virtual_size = GUINT32_FROM_LE (t->st_virtual_size);
@@ -175,11 +188,17 @@ load_cli_header (MonoImage *image, MonoCLIImageInfo *iinfo)
175 188
 	if (offset == INVALID_ADDRESS)
176 189
 		return FALSE;
177 190
 
178  
-	if (fseek (image->f, offset, SEEK_SET) != 0)
179  
-		return FALSE;
  191
+	if (!image->f) {
  192
+		if (offset + sizeof (MonoCLIHeader) > image->raw_data_len)
  193
+			return FALSE;
  194
+		memcpy (&iinfo->cli_cli_header, image->raw_data + offset, sizeof (MonoCLIHeader));
  195
+	} else {
  196
+		if (fseek (image->f, offset, SEEK_SET) != 0)
  197
+			return FALSE;
180 198
 	
181  
-	if ((n = fread (&iinfo->cli_cli_header, sizeof (MonoCLIHeader), 1, image->f)) != 1)
182  
-		return FALSE;
  199
+		if ((n = fread (&iinfo->cli_cli_header, sizeof (MonoCLIHeader), 1, image->f)) != 1)
  200
+			return FALSE;
  201
+	}
183 202
 
184 203
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
185 204
 #define SWAP32(x) (x) = GUINT32_FROM_LE ((x))
@@ -243,10 +262,16 @@ load_metadata_ptrs (MonoImage *image, MonoCLIImageInfo *iinfo)
243 262
 	
244 263
 	offset = mono_cli_rva_image_map (iinfo, iinfo->cli_cli_header.ch_metadata.rva);
245 264
 	size = iinfo->cli_cli_header.ch_metadata.size;
246  
-	
247  
-	image->raw_metadata = mono_raw_buffer_load (fileno (image->f), FALSE, offset, size);
248  
-	if (image->raw_metadata == NULL)
249  
-		return FALSE;
  265
+
  266
+	if (!image->f) {
  267
+		if (offset + size > image->raw_data_len)
  268
+			return FALSE;
  269
+		image->raw_metadata = image->raw_data + offset;
  270
+	} else {
  271
+		image->raw_metadata = mono_raw_buffer_load (fileno (image->f), FALSE, offset, size);
  272
+		if (image->raw_metadata == NULL)
  273
+			return FALSE;
  274
+	}
250 275
 
251 276
 	ptr = image->raw_metadata;
252 277
 
@@ -437,22 +462,9 @@ load_class_names (MonoImage *image)
437 462
 	}
438 463
 }
439 464
 
440  
-static MonoImage *
441  
-do_mono_image_open (const char *fname, MonoImageOpenStatus *status)
  465
+void
  466
+mono_image_init (MonoImage *image)
442 467
 {
443  
-	MonoCLIImageInfo *iinfo;
444  
-	MonoDotNetHeader *header;
445  
-	MonoMSDOSHeader msdos;
446  
-	MonoImage *image;
447  
-	int n;
448  
-
449  
-	image = g_new0 (MonoImage, 1);
450  
-	image->ref_count = 1;
451  
-	image->f = fopen (fname, "rb");
452  
-	image->name = g_strdup (fname);
453  
-	iinfo = g_new0 (MonoCLIImageInfo, 1);
454  
-	image->image_info = iinfo;
455  
-
456 468
 	image->method_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
457 469
 	image->class_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
458 470
 	image->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
@@ -475,31 +487,55 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status)
475 487
 	image->remoting_invoke_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
476 488
 	image->synchronized_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
477 489
 
  490
+
  491
+}
  492
+
  493
+static MonoImage *
  494
+do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status)
  495
+{
  496
+	MonoCLIImageInfo *iinfo;
  497
+	MonoDotNetHeader *header;
  498
+	MonoMSDOSHeader msdos;
  499
+	int n;
  500
+	guint32 offset = 0;
  501
+
  502
+	mono_image_init (image);
  503
+
  504
+	iinfo = image->image_info;
478 505
 	header = &iinfo->cli_header;
479 506
 		
480  
-	if (image->f == NULL){
481  
-		if (status)
482  
-			*status = MONO_IMAGE_ERROR_ERRNO;
483  
-		mono_image_close (image);
484  
-		return NULL;
485  
-	}
486  
-
487 507
 	if (status)
488 508
 		*status = MONO_IMAGE_IMAGE_INVALID;
489  
-	
490  
-	if (fread (&msdos, sizeof (msdos), 1, image->f) != 1)
491  
-		goto invalid_image;
  509
+
  510
+	if (!image->f) {
  511
+		if (offset + sizeof (msdos) > image->raw_data_len)
  512
+			goto invalid_image;
  513
+		memcpy (&msdos, image->raw_data + offset, sizeof (msdos));
  514
+	} else {
  515
+		if (fread (&msdos, sizeof (msdos), 1, image->f) != 1)
  516
+			goto invalid_image;
  517
+	}
492 518
 	
493 519
 	if (!(msdos.msdos_sig [0] == 'M' && msdos.msdos_sig [1] == 'Z'))
494 520
 		goto invalid_image;
495 521
 	
496 522
 	msdos.pe_offset = GUINT32_FROM_LE (msdos.pe_offset);
497 523
 
498  
-	if (msdos.pe_offset != sizeof (msdos))
499  
-		fseek (image->f, msdos.pe_offset, SEEK_SET);
500  
-	
501  
-	if ((n = fread (header, sizeof (MonoDotNetHeader), 1, image->f)) != 1)
502  
-		goto invalid_image;
  524
+	if (msdos.pe_offset != sizeof (msdos)) {
  525
+		if (image->f)
  526
+			fseek (image->f, msdos.pe_offset, SEEK_SET);
  527
+	}
  528
+	offset = msdos.pe_offset;
  529
+
  530
+	if (!image->f) {
  531
+		if (offset + sizeof (MonoDotNetHeader) > image->raw_data_len)
  532
+			goto invalid_image;
  533
+		memcpy (header, image->raw_data + offset, sizeof (MonoDotNetHeader));
  534
+		offset += sizeof (MonoDotNetHeader);
  535
+	} else {
  536
+		if ((n = fread (header, sizeof (MonoDotNetHeader), 1, image->f)) != 1)
  537
+			goto invalid_image;
  538
+	}
503 539
 
504 540
 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
505 541
 #define SWAP32(x) (x) = GUINT32_FROM_LE ((x))
@@ -596,7 +632,7 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status)
596 632
 	 * FIXME: byte swap all addresses here for header.
597 633
 	 */
598 634
 	
599  
-	if (!load_section_tables (image, iinfo))
  635
+	if (!load_section_tables (image, iinfo, offset))
600 636
 		goto invalid_image;
601 637
 	
602 638
 	/* Load the CLI header */
@@ -632,6 +668,29 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status)
632 668
 		return NULL;
633 669
 }
634 670
 
  671
+static MonoImage *
  672
+do_mono_image_open (const char *fname, MonoImageOpenStatus *status)
  673
+{
  674
+	MonoCLIImageInfo *iinfo;
  675
+	MonoImage *image;
  676
+	FILE *filed;
  677
+
  678
+	if ((filed = fopen (fname, "rb")) == NULL){
  679
+		if (status)
  680
+			*status = MONO_IMAGE_ERROR_ERRNO;
  681
+		return NULL;
  682
+	}
  683
+
  684
+	image = g_new0 (MonoImage, 1);
  685
+	image->ref_count = 1;
  686
+	image->f = filed;
  687
+	image->name = g_strdup (fname);
  688
+	iinfo = g_new0 (MonoCLIImageInfo, 1);
  689
+	image->image_info = iinfo;
  690
+
  691
+	return do_mono_image_load (image, status);
  692
+}
  693
+
635 694
 MonoImage *
636 695
 mono_image_loaded (const char *name) {
637 696
 	if (strcmp (name, "mscorlib") == 0)
@@ -648,6 +707,41 @@ mono_image_loaded_by_guid (const char *guid) {
648 707
 	return NULL;
649 708
 }
650 709
 
  710
+MonoImage *
  711
+mono_image_open_from_data (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status)
  712
+{
  713
+	MonoCLIImageInfo *iinfo;
  714
+	MonoImage *image;
  715
+	char *datac;
  716
+
  717
+	if (!data || !data_len) {
  718
+		if (status)
  719
+			*status = MONO_IMAGE_IMAGE_INVALID;
  720
+		return NULL;
  721
+	}
  722
+	datac = data;
  723
+	if (need_copy) {
  724
+		datac = g_try_malloc (data_len);
  725
+		if (!datac) {
  726
+			if (status)
  727
+				*status = MONO_IMAGE_ERROR_ERRNO;
  728
+			return NULL;
  729
+		}
  730
+		memcpy (datac, data, data_len);
  731
+	}
  732
+
  733
+	image = g_new0 (MonoImage, 1);
  734
+	image->ref_count = 1;
  735
+	image->raw_data = datac;
  736
+	image->raw_data_len = data_len;
  737
+	image->raw_data_allocated = need_copy;
  738
+	image->name = g_strdup_printf ("data-%p", datac);
  739
+	iinfo = g_new0 (MonoCLIImageInfo, 1);
  740
+	image->image_info = iinfo;
  741
+
  742
+	return do_mono_image_load (image, status);
  743
+}
  744
+
651 745
 /**
652 746
  * mono_image_open:
653 747
  * @fname: filename that points to the module we want to open
@@ -715,6 +809,8 @@ mono_image_close (MonoImage *image)
715 809
 	
716 810
 	if (image->f)
717 811
 		fclose (image->f);
  812
+	if (image->raw_data_allocated)
  813
+		g_free (image->raw_data);
718 814
 
719 815
 	g_free (image->name);
720 816
 
7  mono/metadata/image.h
@@ -51,6 +51,10 @@ typedef struct {
51 51
 struct _MonoImage {
52 52
 	int   ref_count;
53 53
 	FILE *f;
  54
+	/* if f is NULL the image was loaded rom raw data */
  55
+	char *raw_data;
  56
+	guint32 raw_data_len;
  57
+	gboolean raw_data_allocated;
54 58
 	char *name;
55 59
 	const char *assembly_name;
56 60
 	const char *module_name;
@@ -136,8 +140,11 @@ typedef enum {
136 140
 
137 141
 MonoImage    *mono_image_open     (const char *fname,
138 142
 				   MonoImageOpenStatus *status);
  143
+MonoImage    *mono_image_open_from_data (char *data, guint32 data_len, gboolean need_copy,
  144
+                                         MonoImageOpenStatus *status);
139 145
 MonoImage    *mono_image_loaded   (const char *name);
140 146
 MonoImage    *mono_image_loaded_by_guid (const char *guid);
  147
+void          mono_image_init     (MonoImage *image);
141 148
 void          mono_image_close    (MonoImage *image);
142 149
 const char   *mono_image_strerror (MonoImageOpenStatus status);
143 150
 
104  mono/metadata/make-bundle.pl
... ...
@@ -0,0 +1,104 @@
  1
+#!/usr/bin/perl -w
  2
+# Copyright (C) 2003 Ximian, Inc.
  3
+# Paolo Molaro (lupus@ximian.com)
  4
+#
  5
+# Create an header file to be included in the mono libraries to
  6
+# bundle assemblies inside the runtime.
  7
+# The template file contains a list of assemblies, one per line,
  8
+# with the name followed by a ':' and the filename.
  9
+# Lines starting with '#' and empty lines are ignored.
  10
+# See sample-bundle for an example.
  11
+# We need to use an assembly file because gcc can't handle large arrays:-(
  12
+
  13
+if ($#ARGV != 2) {
  14
+	die "Usage: make-bundle.pl template headerfile.h asm-file\n";
  15
+}
  16
+
  17
+my $template = $ARGV [0];
  18
+my $header = $ARGV [1];
  19
+my $output = $ARGV [2];
  20
+my %assemblies = ();
  21
+
  22
+my $line = 0;
  23
+open (T, $template) || die "Cannot open bundle template: $!\n";
  24
+while (<T>) {
  25
+	++$line;
  26
+	next if (/^\s*#/);
  27
+	next if (/^\s*$/);
  28
+	if (/^([a-zA-Z0-9-.]+):\s*(.+?)\s*$/) {
  29
+		my ($name, $filename) = ($1, $2);
  30
+		if (exists $assemblies {$name}) {
  31
+			die "Assembly $name defined multiple times.\n";
  32
+		} else {
  33
+			$assemblies {$name} = $filename;
  34
+		}
  35
+	} else {
  36
+		die "Unknown format at line $line: $_";
  37
+	}
  38
+}
  39
+close (T);
  40
+
  41
+open (O, ">$output.tmp") || die "Cannot open $output: $!\n";
  42
+open (H, ">$header.tmp") || die "Cannot open $output: $!\n";
  43
+print H <<"EOF";
  44
+/* File generated by make-bundle: do not edit! */
  45
+
  46
+#ifndef __MONO_BUNDLE_H__
  47
+#define __MONO_BUNDLE_H__
  48
+
  49
+typedef struct {
  50
+	const char *name;
  51
+	const unsigned char *data;
  52
+	const unsigned int size;
  53
+} MonoBundledAssembly;
  54
+
  55
+EOF
  56
+
  57
+my $bundle_entries = "";
  58
+
  59
+foreach my $name (sort keys %assemblies) {
  60
+	my $file = $assemblies {$name};
  61
+	my ($nread, $buf, $i, $cname, $need_eol, $size);
  62
+	$cname = $name;
  63
+	$cname =~ s/[-.]/_/g;
  64
+	open (F, $file) || die "Cannot open $file: $!\n";
  65
+	$size = -s F;
  66
+#	print O "/* assembly $name from $file */\n";
  67
+#	print O "static const unsigned char assembly_data_$cname [] = {\n";
  68
+	print O ".globl assembly_data_$cname\n";
  69
+	print O "\t.section .rodata\n";
  70
+	print O "\t.align 32\n";
  71
+	print O "\t.type assembly_data_$cname, \@object\n";
  72
+	print O "\t.size assembly_data_$cname, $size\n";
  73
+	print O "assembly_data_$cname:\n";
  74
+	print H "extern const unsigned char assembly_data_$cname [];\n";
  75
+	print H "static const MonoBundledAssembly assembly_bundle_$cname = {\"$name\", assembly_data_$cname, $size};\n";
  76
+	$bundle_entries .= "\t&assembly_bundle_$cname,\n";
  77
+	$need_eol = 0;
  78
+	print "Adding assembly '$name' from $file...\n";
  79
+	while (($n = sysread (F, $buf, 32))) {
  80
+		for ($i = 0; $i < $n; ++$i) {
  81
+			print O "\t.byte ", ord (substr ($buf, $i, 1)), "\n";
  82
+		}
  83
+#		print O ",\n" if ($need_eol);
  84
+#		$need_eol = 1;
  85
+#		print O "\t";
  86
+#		for ($i = 0; $i < $n; ++$i) {
  87
+#			print O ", " if $i > 0;
  88
+#			print O ord (substr ($buf, $i, 1));
  89
+#		}
  90
+	}
  91
+#	print O "\n};\n\n";
  92
+	close (F);
  93
+}
  94
+
  95
+print H "\nstatic const MonoBundledAssembly* bundled_assemblies [] = {\n";
  96
+print H $bundle_entries;
  97
+print H "\tNULL\n";
  98
+print H "};\n\n";
  99
+print H "#endif /* __MONO_BUNDLE_H__ */\n";
  100
+close (O);
  101
+close (H);
  102
+rename ("$header.tmp", $header);
  103
+rename ("$output.tmp", $output);
  104
+
5  mono/metadata/sample-bundle
... ...
@@ -0,0 +1,5 @@
  1
+# sample bundle template for use with the configure option --with-bundle=...
  2
+
  3
+console: ../tests/console.exe
  4
+mscorlib: /usr/local/lib/corlib.dll
  5
+

0 notes on commit a86efec

Please sign in to comment.
Something went wrong with that request. Please try again.