2009-06-08 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Mon, 8 Jun 2009 01:22:02 +0000 (01:22 -0000)
committerZoltan Varga <vargaz@gmail.com>
Mon, 8 Jun 2009 01:22:02 +0000 (01:22 -0000)
* image-writer.c: Improve support for the osx assembler.

* dwarfwriter.c: Avoid the usage of subsections if the assembler doesn't
support them.

svn path=/trunk/mono/; revision=135624

mono/mini/ChangeLog
mono/mini/dwarfwriter.c
mono/mini/image-writer.c
mono/mini/image-writer.h

index a6866ab19323817ffcc9995f06b8cfbcbe4e3b6a..afe1752e90eb0219d66e9d75e07f569e6494d35e 100644 (file)
@@ -1,3 +1,10 @@
+2009-06-08  Zoltan Varga  <vargaz@gmail.com>
+
+       * image-writer.c: Improve support for the osx assembler.
+
+       * dwarfwriter.c: Avoid the usage of subsections if the assembler doesn't
+       support them.
+
 2009-06-07  Zoltan Varga  <vargaz@gmail.com>
 
        * image-writer.c (append_subsection): Don't align subsections of the
index b6e33775c266594a66c5f8132b81f669b79d32e6..94f1459c5ed4b67692954051e1912c20456d93be 100644 (file)
@@ -40,6 +40,9 @@ struct _MonoDwarfWriter
        FILE *il_file;
        int il_file_line_index, loclist_index;
        GSList *cie_program;
+       FILE *fp;
+       const char *temp_prefix;
+       gboolean emit_line;
 };
 
 /*
@@ -57,6 +60,9 @@ mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file)
        w->w = writer;
        w->il_file = il_file;
 
+       w->fp = img_writer_get_fp (w->w);
+       w->temp_prefix = img_writer_get_temp_label_prefix (w->w);
+
        return w;
 }
 
@@ -621,12 +627,31 @@ emit_line_number_info_begin (MonoDwarfWriter *w)
        emit_label (w, ".Ldebug_line_end");
 }
 
+/*
+ * Some assemblers like apple's do not support subsections, so we can't place
+ * .Ldebug_info_end at the end of the section using subsections. Instead, we 
+ * define it every time something gets added to the .debug_info section.
+ * The apple assember seems to use the last definition.
+ */
+static void
+emit_debug_info_end (MonoDwarfWriter *w)
+{
+       if (!img_writer_subsections_supported (w->w))
+               fprintf (w->fp, "\n.set %sdebug_info_end,.\n", w->temp_prefix);
+}
+
 void
 mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_program)
 {
        char *s, *build_info;
        int i;
 
+       if (!img_writer_subsections_supported (w->w))
+               /* Can't emit line number info without subsections */
+               w->emit_line = FALSE;
+       else
+               w->emit_line = TRUE;
+
        w->cie_program = base_unwind_program;
 
        emit_section_change (w, ".debug_abbrev", 0);
@@ -671,11 +696,13 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra
        emit_int32 (w, 0); /* .debug_abbrev offset */
        emit_byte (w, sizeof (gpointer)); /* address size */
 
-       /* Emit this into a separate section so it gets placed at the end */
-       emit_section_change (w, ".debug_info", 1);
-       emit_int32 (w, 0); /* close everything */
-       emit_label (w, ".Ldebug_info_end");
-       emit_section_change (w, ".debug_info", 0);
+       if (img_writer_subsections_supported (w->w)) {
+               /* Emit this into a separate section so it gets placed at the end */
+               emit_section_change (w, ".debug_info", 1);
+               emit_int32 (w, 0); /* close everything */
+               emit_label (w, ".Ldebug_info_end");
+               emit_section_change (w, ".debug_info", 0);
+       }
 
        /* Compilation unit */
        emit_uleb128 (w, ABBREV_COMPILE_UNIT);
@@ -690,7 +717,10 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra
        emit_pointer_value (w, 0);
        emit_pointer_value (w, 0);
        /* offset into .debug_line section */
-       emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0);
+       if (w->emit_line)
+               emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0);
+       else
+               emit_int32 (w, 0);
 
        /* Base types */
        for (i = 0; i < G_N_ELEMENTS (basic_types); ++i) {
@@ -701,12 +731,15 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra
                emit_string (w, basic_types [i].name);
        }
 
+       emit_debug_info_end (w);
+
        /* debug_loc section */
        emit_section_change (w, ".debug_loc", 0);
        emit_label (w, ".Ldebug_loc_start");
 
        /* debug_line section */
-       emit_line_number_info_begin (w);
+       if (w->emit_line)
+               emit_line_number_info_begin (w);
 
        emit_cie (w);
 }
@@ -1248,6 +1281,9 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method,
        GArray *ln_array;
        int *native_to_il_offset = NULL;
 
+       if (!w->emit_line)
+               return;
+
        minfo = mono_debug_lookup_method (method);
 
        /* Compute the native->IL offset mapping */
@@ -1647,6 +1683,8 @@ mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod
 
        emit_line (w);
 
+       emit_debug_info_end (w);
+
        /* Emit unwind info */
        if (unwind_info) {
                emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, TRUE);
@@ -1679,6 +1717,8 @@ mono_dwarf_writer_emit_trampoline (MonoDwarfWriter *w, const char *tramp_name, c
        /* Subprogram end */
        emit_uleb128 (w, 0x0);
 
+       emit_debug_info_end (w);
+
        /* Emit unwind info */
        emit_fde (w, w->fde_index, start_symbol, end_symbol, code, code_size, unwind_info, FALSE);
        w->fde_index ++;
index 71a57e88565bd7cd99822c05678f9744ad3d1063..ce2bf72a5db775c0ffb977e32e040be8d111a4e0 100644 (file)
@@ -157,6 +157,7 @@ struct _MonoImageWriter {
        char *tmpfname;
        int mode; /* emit mode */
        int col_count; /* bytes emitted per .byte line */
+       int label_gen;
 };
 
 static G_GNUC_UNUSED int
@@ -1421,7 +1422,10 @@ asm_writer_emit_section_change (MonoImageWriter *acfg, const char *section_name,
 #elif defined(TARGET_ASM_APPLE)
        if (strcmp(section_name, ".bss") == 0)
                fprintf (acfg->fp, "%s\n", ".data");
-       else
+       else if (strstr (section_name, ".debug") == section_name) {
+               //g_assert (subsection_index == 0);
+               fprintf (acfg->fp, ".section __DWARF, __%s,regular,debug\n", section_name + 1);
+       } else
                fprintf (acfg->fp, "%s\n", section_name);
 #elif defined(TARGET_ARM) || defined(TARGET_POWERPC)
        /* ARM gas doesn't seem to like subsections of .bss */
@@ -1441,6 +1445,17 @@ asm_writer_emit_section_change (MonoImageWriter *acfg, const char *section_name,
 #endif
 }
 
+static inline
+const char *get_label (const char *s)
+{
+#ifdef TARGET_ASM_APPLE
+       if (s [0] == '.' && s [1] == 'L')
+               /* apple uses "L" instead of ".L" to mark temporary labels */
+               s ++;
+#endif
+       return s;
+}
+
 static void
 asm_writer_emit_symbol_type (MonoImageWriter *acfg, const char *name, gboolean func)
 {
@@ -1493,11 +1508,10 @@ static void
 asm_writer_emit_label (MonoImageWriter *acfg, const char *name)
 {
        asm_writer_emit_unset_mode (acfg);
-#if (defined(__ppc__) && defined(TARGET_ASM_APPLE)) || defined(PLATFORM_WIN32)
-    // mach-o always uses a '_' prefix.
+#if defined(PLATFORM_WIN32)
        fprintf (acfg->fp, "_%s:\n", name);
 #else
-       fprintf (acfg->fp, "%s:\n", name);
+       fprintf (acfg->fp, "%s:\n", get_label (name));
 #endif
 
 #if defined(PLATFORM_WIN32)
@@ -1608,10 +1622,31 @@ asm_writer_emit_int32 (MonoImageWriter *acfg, int value)
 static void
 asm_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset)
 {
+#ifdef TARGET_ASM_APPLE
+       char symbol [128];
+#endif
+
        if (acfg->mode != EMIT_LONG) {
                acfg->mode = EMIT_LONG;
                acfg->col_count = 0;
        }
+
+#ifdef TARGET_ASM_APPLE
+       /* The apple assembler needs a separate symbol to be able to handle complex expressions */
+       sprintf (symbol, "LTMP_SYM%d", acfg->label_gen);
+       start = get_label (start);
+       end = get_label (end);
+       acfg->label_gen ++;
+       if (offset > 0)
+               fprintf (acfg->fp, "\n%s=%s - %s + %d", symbol, end, start, offset);
+       else if (offset < 0)
+               fprintf (acfg->fp, "\n%s=%s - %s %d", symbol, end, start, offset);
+       else
+               fprintf (acfg->fp, "\n%s=%s - %s", symbol, end, start);
+
+       fprintf (acfg->fp, "\n\t%s ", AS_INT32_DIRECTIVE);
+       fprintf (acfg->fp, "%s", symbol);
+#else
        if ((acfg->col_count++ % 8) == 0)
                fprintf (acfg->fp, "\n\t%s ", AS_INT32_DIRECTIVE);
        else
@@ -1622,6 +1657,7 @@ asm_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char*
                fprintf (acfg->fp, "%s - %s %d", end, start, offset);
        else
                fprintf (acfg->fp, "%s - %s", end, start);
+#endif
 }
 
 static void
@@ -1936,3 +1972,29 @@ img_writer_destroy (MonoImageWriter *w)
        mono_mempool_destroy (w->mempool);
        g_free (w);
 }
+
+gboolean
+img_writer_subsections_supported (MonoImageWriter *acfg)
+{
+#ifdef TARGET_ASM_APPLE
+       return acfg->use_bin_writer;
+#else
+       return TRUE;
+#endif
+}
+
+FILE *
+img_writer_get_fp (MonoImageWriter *acfg)
+{
+       return acfg->fp;
+}
+
+const char *
+img_writer_get_temp_label_prefix (MonoImageWriter *acfg)
+{
+#ifdef TARGET_ASM_APPLE
+       return "L";
+#else
+       return ".L";
+#endif
+}
index 0e6a8120b1527feef10e2ca1234224d2cd2982dc..d7e99b415620ef8889342b7067c523ae551befd1 100644 (file)
@@ -76,4 +76,10 @@ void img_writer_emit_reloc (MonoImageWriter *acfg, int reloc_type, const char *s
 
 void img_writer_emit_unset_mode (MonoImageWriter *acfg) MONO_INTERNAL;
 
+gboolean img_writer_subsections_supported (MonoImageWriter *acfg) MONO_INTERNAL;
+
+FILE * img_writer_get_fp (MonoImageWriter *acfg) MONO_INTERNAL;
+
+const char *img_writer_get_temp_label_prefix (MonoImageWriter *acfg) MONO_INTERNAL;
+
 #endif