[mono] Remove gdb xdebug and binary writer support, it hasn't worked in a while....
authorZoltan Varga <vargaz@gmail.com>
Tue, 3 Aug 2021 15:24:52 +0000 (11:24 -0400)
committerGitHub <noreply@github.com>
Tue, 3 Aug 2021 15:24:52 +0000 (17:24 +0200)
* [mono] Remove gdb xdebug support, it hasn't worked in a while.

* [mono] Remove binary writer code, it haven't been used or worked in a while.

* Remove MONO_DEBUG=gdb option.

src/mono/mono/mini/CMakeLists.txt
src/mono/mono/mini/aot-compiler.c
src/mono/mono/mini/driver.c
src/mono/mono/mini/image-writer.c
src/mono/mono/mini/image-writer.h
src/mono/mono/mini/mini-runtime.c
src/mono/mono/mini/mini-runtime.h
src/mono/mono/mini/mini.c
src/mono/mono/mini/mini.h
src/mono/mono/mini/xdebug.c [deleted file]

index b07e585..3e9ca49 100644 (file)
@@ -144,7 +144,6 @@ set(mini_common_sources
     dwarfwriter.c
     mini-gc.h
     mini-gc.c
-    xdebug.c
     mini-llvm.h
     mini-llvm-cpp.h
     llvm-jit.h
index ba1c7ea..369016e 100644 (file)
@@ -14299,7 +14299,7 @@ emit_aot_image (MonoAotCompile *acfg)
                return 1;
        }
        if (acfg->fp)
-               acfg->w = mono_img_writer_create (acfg->fp, FALSE);
+               acfg->w = mono_img_writer_create (acfg->fp);
 
        /* Compute symbols for methods */
        for (i = 0; i < acfg->nmethods; ++i) {
index f2792e4..3e7a07c 100644 (file)
@@ -216,9 +216,6 @@ parse_debug_options (const char* p)
                } else if (!strncmp (p, "mdb-optimizations", 17)) {
                        opt->mdb_optimizations = TRUE;
                        p += 17;
-               } else if (!strncmp (p, "gdb", 3)) {
-                       opt->gdb = TRUE;
-                       p += 3;
                } else if (!strncmp (p, "ignore", 6)) {
                        opt->enabled = FALSE;
                        p += 6;
index 97d1a04..cc81ac7 100644 (file)
 #include <fcntl.h>
 #include <ctype.h>
 #include <string.h>
-#ifndef HOST_WIN32
-#include <sys/time.h>
-#else
-#include <winsock2.h>
-#include <windows.h>
-#endif
-
 #include <errno.h>
 #include <sys/stat.h>
-#include <limits.h>    /* for PAGESIZE */
-#ifndef PAGESIZE
-#define PAGESIZE 4096
-#endif
 
 #include "image-writer.h"
 
-#ifndef HOST_WIN32
-#include <mono/utils/freebsd-elf32.h>
-#include <mono/utils/freebsd-elf64.h>
-#endif
-
 #include "mini.h"
 
-#define TV_DECLARE(name) gint64 name
-#define TV_GETTIME(tv) tv = mono_100ns_ticks ()
-#define TV_ELAPSED(start,end) (((end) - (start)) / 10)
-
 /* 
  * The used assembler dialect
  * TARGET_ASM_APPLE == apple assembler on OSX
 
 #define ROUND_DOWN(VALUE,SIZE) ((VALUE) & ~((SIZE) - 1))
 
-#ifdef USE_BIN_WRITER
-
-typedef struct _BinSymbol BinSymbol;
-typedef struct _BinReloc BinReloc;
-typedef struct _BinSection BinSection;
-
-#endif
-
 /* emit mode */
 enum {
        EMIT_NONE,
@@ -141,24 +113,12 @@ enum {
 struct _MonoImageWriter {
        MonoMemPool *mempool;
        char *outfile;
-       gboolean use_bin_writer;
        const char *current_section;
        int current_subsection;
        const char *section_stack [16];
        int subsection_stack [16];
        int stack_pos;
        FILE *fp;
-       /* Bin writer */
-#ifdef USE_BIN_WRITER
-       BinSymbol *symbols;
-       BinSection *sections;
-       BinSection *cur_section;
-       BinReloc *relocations;
-       GHashTable *labels;
-       int num_relocs;
-       guint8 *out_buf;
-       int out_buf_size, out_buf_pos;
-#endif
        /* Asm writer */
        char *tmpfname;
        int mode; /* emit mode */
@@ -175,1482 +135,6 @@ ilog2(int value)
        return count;
 }
 
-#ifdef USE_BIN_WRITER
-
-typedef struct _BinLabel BinLabel;
-struct _BinLabel {
-       char *name;
-       BinSection *section;
-       int offset;
-};
-
-struct _BinReloc {
-       BinReloc *next;
-       char *val1;
-       char *val2;
-       BinSection *val2_section;
-       int val2_offset;
-       int offset;
-       BinSection *section;
-       int section_offset;
-       int reloc_type;
-};
-
-struct _BinSymbol {
-       BinSymbol *next;
-       char *name;
-       BinSection *section;
-       int offset;
-       gboolean is_function;
-       gboolean is_global;
-       char *end_label;
-};
-
-struct _BinSection {
-       BinSection *next;
-       BinSection *parent;
-       char *name;
-       int subsection;
-       guint8 *data;
-       int data_len;
-       int cur_offset;
-       int file_offset;
-       int virt_offset;
-       int shidx;
-       guint64 addr;
-       gboolean has_addr;
-};
-
-static void
-bin_writer_emit_start (MonoImageWriter *acfg)
-{
-       acfg->labels = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-static void
-bin_writer_emit_section_change (MonoImageWriter *acfg, const char *section_name, int subsection_index)
-{
-       BinSection *section;
-
-       if (acfg->cur_section && acfg->cur_section->subsection == subsection_index
-                       && strcmp (acfg->cur_section->name, section_name) == 0)
-               return;
-       for (section = acfg->sections; section; section = section->next) {
-               if (section->subsection == subsection_index && strcmp (section->name, section_name) == 0) {
-                       acfg->cur_section = section;
-                       return;
-               }
-       }
-       if (!section) {
-               section = g_new0 (BinSection, 1);
-               section->name = g_strdup (section_name);
-               section->subsection = subsection_index;
-               section->next = acfg->sections;
-               acfg->sections = section;
-               acfg->cur_section = section;
-       }
-}
-
-static void
-bin_writer_set_section_addr (MonoImageWriter *acfg, guint64 addr)
-{
-       acfg->cur_section->addr = addr;
-       acfg->cur_section->has_addr = TRUE;
-}
-
-static void
-bin_writer_emit_symbol_inner (MonoImageWriter *acfg, const char *name, const char *end_label, gboolean is_global, gboolean func)
-{
-       BinSymbol *symbol = g_new0 (BinSymbol, 1);
-       symbol->name = g_strdup (name);
-       if (end_label)
-               symbol->end_label = g_strdup (end_label);
-       symbol->is_function = func;
-       symbol->is_global = is_global;
-       symbol->section = acfg->cur_section;
-       /* FIXME: we align after this call... */
-       symbol->offset = symbol->section->cur_offset;
-       symbol->next = acfg->symbols;
-       acfg->symbols = symbol;
-}
-
-static void
-bin_writer_emit_global (MonoImageWriter *acfg, const char *name, gboolean func)
-{
-       bin_writer_emit_symbol_inner (acfg, name, NULL, TRUE, func);
-}
-
-static void
-bin_writer_emit_local_symbol (MonoImageWriter *acfg, const char *name, const char *end_label, gboolean func)
-{
-       bin_writer_emit_symbol_inner (acfg, name, end_label, FALSE, func);
-}
-
-static void
-bin_writer_emit_label (MonoImageWriter *acfg, const char *name)
-{
-       BinLabel *label = g_new0 (BinLabel, 1);
-       label->name = g_strdup (name);
-       label->section = acfg->cur_section;
-       label->offset = acfg->cur_section->cur_offset;
-       g_hash_table_insert (acfg->labels, label->name, label);
-}
-
-static void
-bin_writer_emit_ensure_buffer (BinSection *section, int size)
-{
-       int new_offset = section->cur_offset + size;
-       if (new_offset >= section->data_len) {
-               int new_size = section->data_len? section->data_len * 2: 256;
-               guint8 *data;
-               while (new_size <= new_offset)
-                       new_size *= 2;
-               data = (guint8 *)g_malloc0 (new_size);
-               memcpy (data, section->data, section->data_len);
-               g_free (section->data);
-               section->data = data;
-               section->data_len = new_size;
-       }
-}
-
-static void
-bin_writer_emit_bytes (MonoImageWriter *acfg, const guint8* buf, int size)
-{
-       bin_writer_emit_ensure_buffer (acfg->cur_section, size);
-       memcpy (acfg->cur_section->data + acfg->cur_section->cur_offset, buf, size);
-       acfg->cur_section->cur_offset += size;
-}
-
-static void
-bin_writer_emit_string (MonoImageWriter *acfg, const char *value)
-{
-       int size = strlen (value) + 1;
-       bin_writer_emit_bytes (acfg, (const guint8*)value, size);
-}
-
-static void
-bin_writer_emit_line (MonoImageWriter *acfg)
-{
-       /* Nothing to do in binary writer */
-}
-
-static void 
-bin_writer_emit_alignment (MonoImageWriter *acfg, int size)
-{
-       int offset = acfg->cur_section->cur_offset;
-       int add;
-       offset += (size - 1);
-       offset &= ~(size - 1);
-       add = offset - acfg->cur_section->cur_offset;
-       if (add) {
-               bin_writer_emit_ensure_buffer (acfg->cur_section, add);
-               acfg->cur_section->cur_offset += add;
-       }
-}
-
-static void
-bin_writer_emit_pointer_unaligned (MonoImageWriter *acfg, const char *target)
-{
-       BinReloc *reloc;
-
-       if (!target) {
-               acfg->cur_section->cur_offset += sizeof (gpointer);
-               return;
-       }
-
-       reloc = g_new0 (BinReloc, 1);
-       reloc->val1 = g_strdup (target);
-       reloc->section = acfg->cur_section;
-       reloc->section_offset = acfg->cur_section->cur_offset;
-       reloc->next = acfg->relocations;
-       acfg->relocations = reloc;
-       if (strcmp (reloc->section->name, ".data") == 0) {
-               acfg->num_relocs++;
-               //g_print ("reloc: %s at %d\n", target, acfg->cur_section->cur_offset);
-       }
-       acfg->cur_section->cur_offset += sizeof (gpointer);
-}
-
-static void
-bin_writer_emit_pointer (MonoImageWriter *acfg, const char *target)
-{
-       bin_writer_emit_alignment (acfg, sizeof (gpointer));
-       bin_writer_emit_pointer_unaligned (acfg, target);
-}
-
-static void
-bin_writer_emit_int16 (MonoImageWriter *acfg, int value)
-{
-       guint8 *data;
-       bin_writer_emit_ensure_buffer (acfg->cur_section, 2);
-       data = acfg->cur_section->data + acfg->cur_section->cur_offset;
-       acfg->cur_section->cur_offset += 2;
-       /* FIXME: little endian */
-       data [0] = value;
-       data [1] = value >> 8;
-}
-
-static void
-bin_writer_emit_int32 (MonoImageWriter *acfg, int value)
-{
-       guint8 *data;
-       bin_writer_emit_ensure_buffer (acfg->cur_section, 4);
-       data = acfg->cur_section->data + acfg->cur_section->cur_offset;
-       acfg->cur_section->cur_offset += 4;
-       /* FIXME: little endian */
-       data [0] = value;
-       data [1] = value >> 8;
-       data [2] = value >> 16;
-       data [3] = value >> 24;
-}
-
-static BinReloc*
-create_reloc (MonoImageWriter *acfg, const char *end, const char* start, int offset)
-{
-       BinReloc *reloc;
-       reloc = (BinReloc *)mono_mempool_alloc0 (acfg->mempool, sizeof (BinReloc));
-       reloc->val1 = mono_mempool_strdup (acfg->mempool, end);
-       if (start)
-       {
-               if (strcmp (start, ".") == 0) {
-                       reloc->val2_section = acfg->cur_section;
-                       reloc->val2_offset = acfg->cur_section->cur_offset;
-               } else {
-                       reloc->val2 = mono_mempool_strdup (acfg->mempool, start);
-               }
-       }
-       reloc->offset = offset;
-       reloc->section = acfg->cur_section;
-       reloc->section_offset = acfg->cur_section->cur_offset;
-       reloc->next = acfg->relocations;
-       acfg->relocations = reloc;
-       return reloc;
-}
-
-static void
-bin_writer_emit_symbol (MonoImageWriter *acfg, const char *symbol)
-{
-       create_reloc (acfg, symbol, NULL, 0);
-       acfg->cur_section->cur_offset += 4;
-}
-
-static void
-bin_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset)
-{
-       create_reloc (acfg, end, start, offset);
-       acfg->cur_section->cur_offset += 4;
-       /*if (strcmp (reloc->section->name, ".data") == 0) {
-               acfg->num_relocs++;
-               g_print ("reloc: %s - %s + %d at %d\n", end, start, offset, acfg->cur_section->cur_offset - 4);
-       }*/
-}
-
-/* 
- * Emit a relocation entry of type RELOC_TYPE against symbol SYMBOL at the current PC.
- * Do not advance PC.
- */
-static G_GNUC_UNUSED void
-bin_writer_emit_reloc (MonoImageWriter *acfg, int reloc_type, const char *symbol, int addend)
-{
-       BinReloc *reloc = create_reloc (acfg, symbol, ".", addend);
-       reloc->reloc_type = reloc_type;
-}
-
-static void
-bin_writer_emit_zero_bytes (MonoImageWriter *acfg, int num)
-{
-       bin_writer_emit_ensure_buffer (acfg->cur_section, num);
-       acfg->cur_section->cur_offset += num;
-}
-
-static void
-bin_writer_fwrite (MonoImageWriter *acfg, void *val, size_t size, size_t nmemb)
-{
-       if (acfg->fp)
-               fwrite (val, size, nmemb, acfg->fp);
-       else {
-               g_assert (acfg->out_buf_pos + (size * nmemb) <= acfg->out_buf_size);
-               memcpy (acfg->out_buf + acfg->out_buf_pos, val, size * nmemb);
-               acfg->out_buf_pos += (size * nmemb);
-       }
-}
-
-static void
-bin_writer_fseek (MonoImageWriter *acfg, int offset)
-{
-       if (acfg->fp)
-               fseek (acfg->fp, offset, SEEK_SET);
-       else
-               acfg->out_buf_pos = offset;
-}
-
-#ifdef USE_MACH_WRITER
-
-/*
- * This is a minimal implementation designed to support xdebug on 32 bit osx
- * FIXME: 64 bit support
- */
-
-#include <mach-o/loader.h>
-
-static gsize
-get_label_addr (MonoImageWriter *acfg, const char *name)
-{
-       int offset;
-       BinLabel *lab;
-       BinSection *section;
-       gsize value;
-
-       lab = g_hash_table_lookup (acfg->labels, name);
-       if (!lab)
-               g_error ("Undefined label: '%s'.\n", name);
-       section = lab->section;
-       offset = lab->offset;
-       if (section->parent) {
-               value = section->parent->virt_offset + section->cur_offset + offset;
-       } else {
-               value = section->virt_offset + offset;
-       }
-       return value;
-}
-
-
-static void
-resolve_reloc (MonoImageWriter *acfg, BinReloc *reloc, guint8 **out_data, gsize *out_vaddr, gsize *out_start_val, gsize *out_end_val)
-{
-       guint8 *data;
-       gssize end_val, start_val;
-       gsize vaddr;
-
-       end_val = get_label_addr (acfg, reloc->val1);
-       if (reloc->val2) {
-               start_val = get_label_addr (acfg, reloc->val2);
-       } else if (reloc->val2_section) {
-               start_val = reloc->val2_offset;
-               if (reloc->val2_section->parent)
-                       start_val += reloc->val2_section->parent->virt_offset + reloc->val2_section->cur_offset;
-               else
-                       start_val += reloc->val2_section->virt_offset;
-       } else {
-               start_val = 0;
-       }
-       end_val = end_val - start_val + reloc->offset;
-       if (reloc->section->parent) {
-               data = reloc->section->parent->data;
-               data += reloc->section->cur_offset;
-               data += reloc->section_offset;
-               vaddr = reloc->section->parent->virt_offset;
-               vaddr += reloc->section->cur_offset;
-               vaddr += reloc->section_offset;
-       } else {
-               data = reloc->section->data;
-               data += reloc->section_offset;
-               vaddr = reloc->section->virt_offset;
-               vaddr += reloc->section_offset;
-       }
-
-       *out_start_val = start_val;
-       *out_end_val = end_val;
-       *out_data = data;
-       *out_vaddr = vaddr;
-}
-
-static void
-resolve_relocations (MonoImageWriter *acfg)
-{
-       BinReloc *reloc;
-       guint8 *data;
-       gsize end_val, start_val;
-       gsize vaddr;
-
-       /* Only resolve static relocations */
-       for (reloc = acfg->relocations; reloc; reloc = reloc->next) {
-               resolve_reloc (acfg, reloc, &data, &vaddr, &start_val, &end_val);
-               data [0] = end_val;
-               data [1] = end_val >> 8;
-               data [2] = end_val >> 16;
-               data [3] = end_val >> 24;
-       }
-}
-
-static int
-bin_writer_emit_writeout (MonoImageWriter *acfg)
-{
-       BinSection *s;
-       int sindex, file_size, nsections, file_offset, vmaddr;
-       struct mach_header header;
-       struct segment_command segment;
-       struct section *sections;
-
-       /* Assing vm addresses to sections */
-       nsections = 0;
-       vmaddr = 0;
-       for (s = acfg->sections; s; s = s->next) {
-               s->virt_offset = vmaddr;
-               vmaddr += s->cur_offset;
-               nsections ++;
-       }
-
-       resolve_relocations (acfg);
-
-       file_offset = 0;
-
-       memset (&header, 0, sizeof (header));
-       header.magic = MH_MAGIC;
-       header.cputype = CPU_TYPE_X86;
-       header.cpusubtype = CPU_SUBTYPE_X86_ALL;
-       header.filetype = MH_OBJECT;
-       header.ncmds = 0;
-       header.sizeofcmds = 0;
-       header.flags = 0;
-
-       file_offset += sizeof (header);
-
-       memset (&segment, 0, sizeof (segment));
-       segment.cmd = LC_SEGMENT;
-       segment.cmdsize = sizeof (segment);
-       segment.maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
-       segment.initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
-
-       file_offset += sizeof (segment);
-       file_offset += nsections * sizeof (struct section);
-
-       sections = g_new0 (struct section, nsections);
-       sindex = 0;
-       for (s = acfg->sections; s; s = s->next) {
-               s->file_offset = file_offset;
-
-               /* .debug_line -> __debug_line */
-               sprintf (sections [sindex].sectname, "__%s", s->name + 1);
-               sprintf (sections [sindex].segname, "%s", "__DWARF");
-               sections [sindex].addr = s->virt_offset;
-               sections [sindex].size = s->cur_offset;
-               sections [sindex].offset = s->file_offset;
-
-               file_offset += s->cur_offset;
-
-               segment.nsects ++;
-               segment.cmdsize += sizeof (struct section);
-
-               sindex ++;
-       }
-
-       header.ncmds ++;
-       header.sizeofcmds += segment.cmdsize;
-
-       /* Emit data */
-       file_size = file_offset;
-
-       if (!acfg->fp) {
-               acfg->out_buf_size = file_size;
-               acfg->out_buf = g_malloc (acfg->out_buf_size);
-       }
-
-       bin_writer_fwrite (acfg, &header, sizeof (header), 1);
-       bin_writer_fwrite (acfg, &segment, sizeof (segment), 1);
-       bin_writer_fwrite (acfg, sections, sizeof (struct section), nsections);
-       for (s = acfg->sections; s; s = s->next) {
-               if (!acfg->fp)
-                       g_assert (acfg->out_buf_pos == s->file_offset);
-               bin_writer_fwrite (acfg, s->data, s->cur_offset, 1);
-       }
-
-       if (acfg->fp)
-               fclose (acfg->fp);
-
-       return 0;
-}
-
-#endif
-
-#ifdef USE_ELF_WRITER
-
-enum {
-       SECT_NULL,
-       SECT_HASH,
-       SECT_DYNSYM,
-       SECT_DYNSTR,
-       SECT_REL_DYN,
-       SECT_RELA_DYN,
-       SECT_TEXT,
-       SECT_RODATA,
-       SECT_DYNAMIC,
-       SECT_GOT_PLT,
-       SECT_DATA,
-       SECT_BSS,
-       SECT_DEBUG_FRAME,
-       SECT_DEBUG_INFO,
-       SECT_DEBUG_ABBREV,
-       SECT_DEBUG_LINE,
-       SECT_DEBUG_LOC,
-       SECT_SHSTRTAB,
-       SECT_SYMTAB,
-       SECT_STRTAB,
-       SECT_NUM
-};
-
-#if TARGET_SIZEOF_VOID_P == 4
-
-typedef Elf32_Ehdr ElfHeader;
-typedef Elf32_Shdr ElfSectHeader;
-typedef Elf32_Phdr ElfProgHeader;
-typedef Elf32_Sym ElfSymbol;
-typedef Elf32_Rel ElfReloc;
-typedef Elf32_Rela ElfRelocA;
-typedef Elf32_Dyn ElfDynamic;
-
-#else
-
-typedef Elf64_Ehdr ElfHeader;
-typedef Elf64_Shdr ElfSectHeader;
-typedef Elf64_Phdr ElfProgHeader;
-typedef Elf64_Sym ElfSymbol;
-typedef Elf64_Rel ElfReloc;
-typedef Elf64_Rela ElfRelocA;
-typedef Elf64_Dyn ElfDynamic;
-
-#endif
-
-typedef struct {
-       const char *name;
-       int type;
-       int esize;
-       int flags;
-       int align;
-} SectInfo;
-
-static SectInfo section_info [] = {
-       {"", 0, 0, 0, 0},
-       {".hash", SHT_HASH, 4, 2, TARGET_SIZEOF_VOID_P},
-       {".dynsym", SHT_DYNSYM, sizeof (ElfSymbol), 2, TARGET_SIZEOF_VOID_P},
-       {".dynstr", SHT_STRTAB, 0, 2, 1},
-       {".rel.dyn", SHT_REL, sizeof (ElfReloc), 2, TARGET_SIZEOF_VOID_P},
-       {".rela.dyn", SHT_RELA, sizeof (ElfRelocA), 2, TARGET_SIZEOF_VOID_P},
-       {".text", SHT_PROGBITS, 0, 6, 4096},
-       {".rodata", SHT_PROGBITS, 0, SHF_ALLOC, 4096},
-       {".dynamic", SHT_DYNAMIC, sizeof (ElfDynamic), 3, TARGET_SIZEOF_VOID_P},
-       {".got.plt", SHT_PROGBITS, TARGET_SIZEOF_VOID_P, 3, TARGET_SIZEOF_VOID_P},
-       {".data", SHT_PROGBITS, 0, 3, 8},
-       {".bss", SHT_NOBITS, 0, 3, 8},
-       {".debug_frame", SHT_PROGBITS, 0, 0, 8},
-       {".debug_info", SHT_PROGBITS, 0, 0, 1},
-       {".debug_abbrev", SHT_PROGBITS, 0, 0, 1},
-       {".debug_line", SHT_PROGBITS, 0, 0, 1},
-       {".debug_loc", SHT_PROGBITS, 0, 0, 1},
-       {".shstrtab", SHT_STRTAB, 0, 0, 1},
-       {".symtab", SHT_SYMTAB, sizeof (ElfSymbol), 0, TARGET_SIZEOF_VOID_P},
-       {".strtab", SHT_STRTAB, 0, 0, 1}
-};
-
-typedef struct {
-       GString *data;
-       GHashTable *hash;
-} ElfStrTable;
-
-static int
-str_table_add (ElfStrTable *table, const char* value)
-{
-       int idx;
-       if (!table->data) {
-               table->data = g_string_new_len ("", 1);
-               table->hash = g_hash_table_new (g_str_hash, g_str_equal);
-       }
-       idx = GPOINTER_TO_UINT (g_hash_table_lookup (table->hash, value));
-       if (idx)
-               return idx;
-       idx = table->data->len;
-       g_string_append (table->data, value);
-       g_string_append_c (table->data, 0);
-       g_hash_table_insert (table->hash, (void*)value, GUINT_TO_POINTER (idx));
-       return idx;
-}
-
-static void
-append_subsection (MonoImageWriter *acfg, ElfSectHeader *sheaders, BinSection *sect, BinSection *add)
-{
-       int offset = sect->cur_offset;
-       /*offset += (sheaders [sect->shidx].sh_addralign - 1);
-       offset &= ~(sheaders [sect->shidx].sh_addralign - 1);*/
-       /* 
-        * FIXME: we shouldn't align subsections at all, but if we don't then the
-        * stuff inside the subsections which is aligned won't get aligned.
-        */
-       if (strcmp (sect->name, ".debug_line") != 0) {
-               offset += (8 - 1);
-               offset &= ~(8 - 1);
-       }
-       bin_writer_emit_ensure_buffer (sect, offset);
-       //g_print ("section %s aligned to %d from %d\n", sect->name, offset, sect->cur_offset);
-       sect->cur_offset = offset;
-
-       bin_writer_emit_ensure_buffer (sect, add->cur_offset);
-       memcpy (sect->data + sect->cur_offset, add->data, add->cur_offset);
-       add->parent = sect;
-       sect->cur_offset += add->cur_offset;
-       add->cur_offset = offset; /* it becomes the offset in the parent section */
-       //g_print ("subsection %d of %s added at offset %d (align: %d)\n", add->subsection, sect->name, add->cur_offset, (int)sheaders [sect->shidx].sh_addralign);
-       add->data = NULL;
-       add->data_len = 0;
-}
-
-/* merge the subsections */
-static int
-collect_sections (MonoImageWriter *acfg, ElfSectHeader *sheaders, BinSection **out, int num)
-{
-       int i, j, maxs, num_sections;
-       BinSection *sect;
-
-       num_sections = 0;
-       maxs = 0;
-       for (sect = acfg->sections; sect; sect = sect->next) {
-               if (sect->subsection == 0) {
-                       out [num_sections++] = sect;
-                       g_assert (num_sections < num);
-               }
-               maxs = MAX (maxs, sect->subsection);
-       }
-       for (i = 0; i < num_sections; i++) {
-               for (j = 1; j <= maxs; ++j) {
-                       for (sect = acfg->sections; sect; sect = sect->next) {
-                               if (sect->subsection == j && strcmp (out [i]->name, sect->name) == 0) {
-                                       append_subsection (acfg, sheaders, out [i], sect);
-                               }
-                       }
-               }
-       }
-       return num_sections;
-}
-
-static unsigned long
-elf_hash (const unsigned char *name)
-{
-       unsigned long h = 0, g;
-       while (*name) {
-               h = (h << 4) + *name++;
-               if ((g = h & 0xf0000000))
-                       h ^= g >> 24;
-               h &= ~g;
-       }
-       return h;
-}
-
-#define NUM_BUCKETS 17
-
-static int*
-build_hash (MonoImageWriter *acfg, int num_sections, ElfStrTable *dynstr)
-{
-       int *data;
-       int num_symbols = 1 + num_sections + 3;
-       BinSymbol *symbol;
-
-       for (symbol = acfg->symbols; symbol; symbol = symbol->next) {
-               if (!symbol->is_global)
-                       continue;
-               num_symbols++;
-               str_table_add (dynstr, symbol->name);
-               /*g_print ("adding sym: %s\n", symbol->name);*/
-       }
-       str_table_add (dynstr, "__bss_start");
-       str_table_add (dynstr, "_edata");
-       str_table_add (dynstr, "_end");
-
-       data = g_new0 (int, num_symbols + 2 + NUM_BUCKETS);
-       data [0] = NUM_BUCKETS;
-       data [1] = num_symbols;
-
-       return data;
-}
-
-static gsize
-get_label_addr (MonoImageWriter *acfg, const char *name)
-{
-       int offset;
-       BinLabel *lab;
-       BinSection *section;
-       gsize value;
-
-       lab = (BinLabel *)g_hash_table_lookup (acfg->labels, name);
-       if (!lab)
-               g_error ("Undefined label: '%s'.\n", name);
-       section = lab->section;
-       offset = lab->offset;
-       if (section->parent) {
-               value = section->parent->virt_offset + section->cur_offset + offset;
-       } else {
-               value = section->virt_offset + offset;
-       }
-       return value;
-}
-
-static ElfSymbol*
-collect_syms (MonoImageWriter *acfg, int *hash, ElfStrTable *strtab, ElfSectHeader *sheaders, int *num_syms)
-{
-       ElfSymbol *symbols;
-       BinSymbol *symbol;
-       BinSection *section;
-       int i;
-       int *bucket;
-       int *chain;
-       unsigned long hashc;
-
-       if (hash)
-               symbols = g_new0 (ElfSymbol, hash [1]);
-       else {
-               i = 0;
-               for (symbol = acfg->symbols; symbol; symbol = symbol->next)
-                       i ++;
-               
-               symbols = g_new0 (ElfSymbol, i + SECT_NUM + 10); /* FIXME */
-       }
-
-       /* the first symbol is undef, all zeroes */
-       i = 1;
-       if (sheaders) {
-               int j;
-               for (j = 1; j < SECT_NUM; ++j) {
-                       symbols [i].st_info = ELF32_ST_INFO (STB_LOCAL, STT_SECTION);
-                       symbols [i].st_shndx = j;
-                       symbols [i].st_value = sheaders [j].sh_addr;
-                       ++i;
-               }
-       } else {
-               for (section = acfg->sections; section; section = section->next) {
-                       if (section->parent)
-                               continue;
-                       symbols [i].st_info = ELF32_ST_INFO (STB_LOCAL, STT_SECTION);
-                       if (strcmp (section->name, ".text") == 0) {
-                               symbols [i].st_shndx = SECT_TEXT;
-                               section->shidx = SECT_TEXT;
-                               section->file_offset = 4096;
-                               symbols [i].st_value = section->virt_offset;
-                       } else if (strcmp (section->name, ".rodata") == 0) {
-                               symbols [i].st_shndx = SECT_RODATA;
-                               section->shidx = SECT_RODATA;
-                               section->file_offset = 4096;
-                               symbols [i].st_value = section->virt_offset;
-                       } else if (strcmp (section->name, ".data") == 0) {
-                               symbols [i].st_shndx = SECT_DATA;
-                               section->shidx = SECT_DATA;
-                               section->file_offset = 4096 + 28; /* FIXME */
-                               symbols [i].st_value = section->virt_offset;
-                       } else if (strcmp (section->name, ".bss") == 0) {
-                               symbols [i].st_shndx = SECT_BSS;
-                               section->shidx = SECT_BSS;
-                               section->file_offset = 4096 + 28 + 8; /* FIXME */
-                               symbols [i].st_value = section->virt_offset;
-                       }
-                       ++i;
-               }
-       }
-       for (symbol = acfg->symbols; symbol; symbol = symbol->next) {
-               int offset;
-               BinLabel *lab;
-               if (!symbol->is_global && hash)
-                       continue;
-               symbols [i].st_info = ELF32_ST_INFO (symbol->is_global ? STB_GLOBAL : STB_LOCAL, symbol->is_function? STT_FUNC : STT_OBJECT);
-               symbols [i].st_name = str_table_add (strtab, symbol->name);
-               /*g_print ("sym name %s tabled to %d\n", symbol->name, symbols [i].st_name);*/
-               section = symbol->section;
-               symbols [i].st_shndx = section->parent? section->parent->shidx: section->shidx;
-               lab = (BinLabel *)g_hash_table_lookup (acfg->labels, symbol->name);
-               offset = lab->offset;
-               if (section->parent) {
-                       symbols [i].st_value = section->parent->virt_offset + section->cur_offset + offset;
-               } else {
-                       symbols [i].st_value = section->virt_offset + offset;
-               }
-
-               if (symbol->end_label) {
-                       BinLabel *elab = (BinLabel *)g_hash_table_lookup (acfg->labels, symbol->end_label);
-                       g_assert (elab);
-                       symbols [i].st_size = elab->offset - lab->offset;
-               }
-               ++i;
-       }
-       /* add special symbols */
-       symbols [i].st_name = str_table_add (strtab, "__bss_start");
-       symbols [i].st_shndx = 0xfff1;
-       symbols [i].st_info = ELF32_ST_INFO (STB_GLOBAL, 0);
-       ++i;
-       symbols [i].st_name = str_table_add (strtab, "_edata");
-       symbols [i].st_shndx = 0xfff1;
-       symbols [i].st_info = ELF32_ST_INFO (STB_GLOBAL, 0);
-       ++i;
-       symbols [i].st_name = str_table_add (strtab, "_end");
-       symbols [i].st_shndx = 0xfff1;
-       symbols [i].st_info = ELF32_ST_INFO (STB_GLOBAL, 0);
-       ++i;
-
-       if (num_syms)
-               *num_syms = i;
-
-       /* add to hash table */
-       if (hash) {
-               bucket = hash + 2;
-               chain = hash + 2 + hash [0];
-               for (i = 0; i < hash [1]; ++i) {
-                       int slot;
-                       /*g_print ("checking %d '%s' (sym %d)\n", symbols [i].st_name, strtab->data->str + symbols [i].st_name, i);*/
-                       if (!symbols [i].st_name)
-                               continue;
-                       hashc = elf_hash ((guint8*)strtab->data->str + symbols [i].st_name);
-                       slot = hashc % hash [0];
-                       /*g_print ("hashing '%s' at slot %d (sym %d)\n", strtab->data->str + symbols [i].st_name, slot, i);*/
-                       if (bucket [slot]) {
-                               chain [i] = bucket [slot];
-                               bucket [slot] = i;
-                       } else {
-                               bucket [slot] = i;
-                       }
-               }
-       }
-       return symbols;
-}
-
-static void
-reloc_symbols (MonoImageWriter *acfg, ElfSymbol *symbols, ElfSectHeader *sheaders, ElfStrTable *strtab, gboolean dynamic)
-{
-       BinSection *section;
-       BinSymbol *symbol;
-       int i;
-
-       i = 1;
-       if (dynamic) {
-               for (section = acfg->sections; section; section = section->next) {
-                       if (section->parent)
-                               continue;
-                       symbols [i].st_value = sheaders [section->shidx].sh_addr;
-                       ++i;
-               }
-       } else {
-               for (i = 1; i < SECT_NUM; ++i) {
-                       symbols [i].st_value = sheaders [i].sh_addr;
-               }
-       }
-       for (symbol = acfg->symbols; symbol; symbol = symbol->next) {
-               int offset;
-               BinLabel *lab;
-               if (dynamic && !symbol->is_global)
-                       continue;
-               section = symbol->section;
-               lab = (BinLabel *)g_hash_table_lookup (acfg->labels, symbol->name);
-               offset = lab->offset;
-               if (section->parent) {
-                       symbols [i].st_value = sheaders [section->parent->shidx].sh_addr + section->cur_offset + offset;
-               } else {
-                       symbols [i].st_value = sheaders [section->shidx].sh_addr + offset;
-               }
-               ++i;
-       }
-       /* __bss_start */
-       symbols [i].st_value = sheaders [SECT_BSS].sh_addr;
-       ++i;
-       /* _edata */
-       symbols [i].st_value = sheaders [SECT_DATA].sh_addr + sheaders [SECT_DATA].sh_size;
-       ++i;
-       /* _end */
-       symbols [i].st_value = sheaders [SECT_BSS].sh_addr + sheaders [SECT_BSS].sh_size;
-       ++i;
-}
-
-static void
-resolve_reloc (MonoImageWriter *acfg, BinReloc *reloc, guint8 **out_data, gsize *out_vaddr, gsize *out_start_val, gsize *out_end_val)
-{
-       guint8 *data;
-       gssize end_val, start_val;
-       gsize vaddr;
-
-       end_val = get_label_addr (acfg, reloc->val1);
-       if (reloc->val2) {
-               start_val = get_label_addr (acfg, reloc->val2);
-       } else if (reloc->val2_section) {
-               start_val = reloc->val2_offset;
-               if (reloc->val2_section->parent)
-                       start_val += reloc->val2_section->parent->virt_offset + reloc->val2_section->cur_offset;
-               else
-                       start_val += reloc->val2_section->virt_offset;
-       } else {
-               start_val = 0;
-       }
-       end_val = end_val - start_val + reloc->offset;
-       if (reloc->section->parent) {
-               data = reloc->section->parent->data;
-               data += reloc->section->cur_offset;
-               data += reloc->section_offset;
-               vaddr = reloc->section->parent->virt_offset;
-               vaddr += reloc->section->cur_offset;
-               vaddr += reloc->section_offset;
-       } else {
-               data = reloc->section->data;
-               data += reloc->section_offset;
-               vaddr = reloc->section->virt_offset;
-               vaddr += reloc->section_offset;
-       }
-
-       *out_start_val = start_val;
-       *out_end_val = end_val;
-       *out_data = data;
-       *out_vaddr = vaddr;
-}
-
-#ifdef USE_ELF_RELA
-
-static ElfRelocA*
-resolve_relocations (MonoImageWriter *acfg)
-{
-       BinReloc *reloc;
-       guint8 *data;
-       gsize end_val, start_val;
-       ElfRelocA *rr;
-       int i;
-       gsize vaddr;
-
-       rr = g_new0 (ElfRelocA, acfg->num_relocs);
-       i = 0;
-
-       for (reloc = acfg->relocations; reloc; reloc = reloc->next) {
-               resolve_reloc (acfg, reloc, &data, &vaddr, &start_val, &end_val);
-               /* FIXME: little endian */
-               data [0] = end_val;
-               data [1] = end_val >> 8;
-               data [2] = end_val >> 16;
-               data [3] = end_val >> 24;
-               // FIXME:
-               if (start_val == 0 && reloc->val1 [0] != '.') {
-                       rr [i].r_offset = vaddr;
-                       rr [i].r_info = R_X86_64_RELATIVE;
-                       rr [i].r_addend = end_val;
-                       ++i;
-                       g_assert (i <= acfg->num_relocs);
-               }
-       }
-       return rr;
-}
-
-#else /* USE_ELF_RELA */
-
-static void
-do_reloc (MonoImageWriter *acfg, BinReloc *reloc, guint8 *data, gssize addr)
-{
-#ifdef TARGET_ARM
-       /*
-        * We use the official ARM relocation types, but implement only the stuff actually
-        * needed by the code we generate.
-        */
-       switch (reloc->reloc_type) {
-       case R_ARM_CALL:
-       case R_ARM_JUMP24: {
-               guint32 *code = (guint32*)(gpointer)data;
-               guint32 ins = *code;
-               int diff = addr;
-
-               if (reloc->reloc_type == R_ARM_CALL)
-                       /* bl */
-                       g_assert (data [3] == 0xeb);
-               else
-                       /* b */
-                       g_assert (data [3] == 0xea);
-               if (diff >= 0 && diff <= 33554431) {
-                       diff >>= 2;
-                       ins = (ins & 0xff000000) | diff;
-                       *code = ins;
-               } else if (diff <= 0 && diff >= -33554432) {
-                       diff >>= 2;
-                       ins = (ins & 0xff000000) | (diff & ~0xff000000);
-                       *code = ins;
-               } else {
-                       g_assert_not_reached ();
-               }
-               break;
-       }
-       case R_ARM_ALU_PC_G0_NC: {
-               /* Generated by emit_plt () */
-               guint8 *code = data;
-               guint32 val = addr;
-
-               g_assert (val <= 0xffffff);
-               if (val & 0xff0000)
-                       ARM_ADD_REG_IMM (code, ARMREG_IP, ARMREG_PC, (val & 0xFF0000) >> 16, 16);
-               else
-                       ARM_ADD_REG_IMM (code, ARMREG_IP, ARMREG_PC, 0, 0);
-               ARM_ADD_REG_IMM (code, ARMREG_IP, ARMREG_IP, (val & 0xFF00) >> 8, 24);
-               ARM_LDR_IMM (code, ARMREG_PC, ARMREG_IP, val & 0xFF);
-               break;
-       }               
-       default:
-               g_assert_not_reached ();
-       }
-#else
-       g_assert_not_reached ();
-#endif
-}
-
-static ElfReloc*
-resolve_relocations (MonoImageWriter *acfg)
-{
-       BinReloc *reloc;
-       guint8 *data;
-       gsize end_val, start_val;
-       ElfReloc *rr;
-       int i;
-       gsize vaddr;
-
-       rr = g_new0 (ElfReloc, acfg->num_relocs);
-       i = 0;
-
-       for (reloc = acfg->relocations; reloc; reloc = reloc->next) {
-               resolve_reloc (acfg, reloc, &data, &vaddr, &start_val, &end_val);
-               /* FIXME: little endian */
-               if (reloc->reloc_type) {
-                       /* Must be static */
-                       g_assert (start_val > 0);
-                       do_reloc (acfg, reloc, data, end_val);
-               } else {
-                       data [0] = end_val;
-                       data [1] = end_val >> 8;
-                       data [2] = end_val >> 16;
-                       data [3] = end_val >> 24;
-               }
-               // FIXME:
-               if (start_val == 0 && reloc->val1 [0] != '.') {
-                       rr [i].r_offset = vaddr;
-                       rr [i].r_info = R_386_RELATIVE;
-                       ++i;
-                       g_assert (i <= acfg->num_relocs);
-               }
-       }
-       return rr;
-}
-
-#endif /* USE_ELF_RELA */
-
-static int normal_sections [] = { SECT_DATA, SECT_DEBUG_FRAME, SECT_DEBUG_INFO, SECT_DEBUG_ABBREV, SECT_DEBUG_LINE, SECT_DEBUG_LOC };
-
-static int
-bin_writer_emit_writeout (MonoImageWriter *acfg)
-{
-       ElfHeader header;
-       ElfProgHeader progh [4];
-       ElfSectHeader secth [SECT_NUM];
-#ifdef USE_ELF_RELA
-       ElfRelocA *relocs;
-#else
-       ElfReloc *relocs;
-#endif
-       ElfStrTable str_table = {NULL, NULL};
-       ElfStrTable sh_str_table = {NULL, NULL};
-       ElfStrTable dyn_str_table = {NULL, NULL};
-       BinSection* all_sections [32];
-       BinSection* sections [SECT_NUM];
-       ElfSymbol *dynsym;
-       ElfSymbol *symtab;
-       ElfDynamic dynamic [14];
-       int *hash;
-       int i, num_sections, file_offset, virt_offset, size;
-       int num_local_syms;
-
-       /* Section headers */
-       memset (&secth, 0, sizeof (secth));
-       memset (&dynamic, 0, sizeof (dynamic));
-       memset (&header, 0, sizeof (header));
-
-       for (i = 1; i < SECT_NUM; ++i) {
-               secth [i].sh_name = str_table_add (&sh_str_table, section_info [i].name);
-               secth [i].sh_type = section_info [i].type;
-               secth [i].sh_addralign = section_info [i].align;
-               secth [i].sh_flags = section_info [i].flags;
-               secth [i].sh_entsize = section_info [i].esize;
-       }
-       secth [SECT_DYNSYM].sh_info = TARGET_SIZEOF_VOID_P == 4 ? 4 : 2;
-       secth [SECT_SYMTAB].sh_info = TARGET_SIZEOF_VOID_P == 4 ? 20 : 17;
-       secth [SECT_HASH].sh_link = SECT_DYNSYM;
-       secth [SECT_DYNSYM].sh_link = SECT_DYNSTR;
-       secth [SECT_REL_DYN].sh_link = SECT_DYNSYM;
-       secth [SECT_RELA_DYN].sh_link = SECT_DYNSYM;
-       secth [SECT_DYNAMIC].sh_link = SECT_DYNSTR;
-       secth [SECT_SYMTAB].sh_link = SECT_STRTAB;
-
-       num_sections = collect_sections (acfg, secth, all_sections, 16);
-       hash = build_hash (acfg, num_sections, &dyn_str_table);
-#if 0
-       g_print ("num_sections: %d\n", num_sections);
-       g_print ("dynsym: %d, dynstr size: %d\n", hash [1], (int)dyn_str_table.data->len);
-       for (i = 0; i < num_sections; ++i) {
-               g_print ("section %s, size: %d, %x\n", all_sections [i]->name, all_sections [i]->cur_offset, all_sections [i]->cur_offset);
-       }
-#endif
-       /* Associate the bin sections with the ELF sections */
-       memset (sections, 0, sizeof (sections));
-       for (i = 0; i < num_sections; ++i) {
-               BinSection *sect = all_sections [i];
-               int j;
-
-               for (j = 0; j < SECT_NUM; ++j) {
-                       if (strcmp (sect->name, section_info [j].name) == 0) {
-                               sect->shidx = j;
-                               break;
-                       }
-               }
-
-               sections [all_sections [i]->shidx] = sect;
-       }
-
-       /* at this point we know where in the file the first segment sections go */
-       dynsym = collect_syms (acfg, hash, &dyn_str_table, NULL, NULL);
-       num_local_syms = hash [1];
-       symtab = collect_syms (acfg, NULL, &str_table, secth, &num_local_syms);
-
-       file_offset = virt_offset = sizeof (header) + sizeof (progh);
-       secth [SECT_HASH].sh_addr = secth [SECT_HASH].sh_offset = file_offset;
-       size = sizeof (int) * (2 + hash [0] + hash [1]);
-       virt_offset = (file_offset += size);
-       secth [SECT_HASH].sh_size = size;
-       secth [SECT_DYNSYM].sh_addr = secth [SECT_DYNSYM].sh_offset = file_offset;
-       size = sizeof (ElfSymbol) * hash [1];
-       virt_offset = (file_offset += size);
-       secth [SECT_DYNSYM].sh_size = size;
-       secth [SECT_DYNSTR].sh_addr = secth [SECT_DYNSTR].sh_offset = file_offset;
-       size = dyn_str_table.data->len;
-       virt_offset = (file_offset += size);
-       secth [SECT_DYNSTR].sh_size = size;
-       file_offset += 4-1;
-       file_offset &= ~(4-1);
-       secth [SECT_REL_DYN].sh_addr = secth [SECT_REL_DYN].sh_offset = file_offset;
-#ifndef USE_ELF_RELA
-       size = sizeof (ElfReloc) * acfg->num_relocs;
-#else
-       size = 0;
-#endif
-       virt_offset = (file_offset += size);
-       secth [SECT_REL_DYN].sh_size = size;
-       secth [SECT_RELA_DYN].sh_addr = secth [SECT_RELA_DYN].sh_offset = file_offset;
-#ifdef USE_ELF_RELA
-       size = sizeof (ElfRelocA) * acfg->num_relocs;
-#else
-       size = 0;
-#endif
-       virt_offset = (file_offset += size);
-       secth [SECT_RELA_DYN].sh_size = size;
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_TEXT].sh_addralign);
-       virt_offset = file_offset;
-       secth [SECT_TEXT].sh_addr = secth [SECT_TEXT].sh_offset = file_offset;
-       if (sections [SECT_TEXT]) {
-               if (sections [SECT_TEXT]->has_addr) {
-                       secth [SECT_TEXT].sh_addr = sections [SECT_TEXT]->addr;
-                       secth [SECT_TEXT].sh_flags &= ~SHF_ALLOC;
-               }
-               size = sections [SECT_TEXT]->cur_offset;
-               secth [SECT_TEXT].sh_size = size;
-               file_offset += size;
-       }
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_RODATA].sh_addralign);
-       virt_offset = file_offset;
-       secth [SECT_RODATA].sh_addr = virt_offset;
-       secth [SECT_RODATA].sh_offset = file_offset;
-       if (sections [SECT_RODATA]) {
-               size = sections [SECT_RODATA]->cur_offset;
-               secth [SECT_RODATA].sh_size = size;
-               file_offset += size;
-               virt_offset += size;
-       }
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_DYNAMIC].sh_addralign);
-       virt_offset = file_offset;
-
-       /* .dynamic, .got.plt, .data, .bss here */
-       /* Have to increase the virt offset since these go to a separate segment */
-       virt_offset += PAGESIZE;
-       secth [SECT_DYNAMIC].sh_addr = virt_offset;
-       secth [SECT_DYNAMIC].sh_offset = file_offset;
-       size = sizeof (dynamic);
-       secth [SECT_DYNAMIC].sh_size = size;
-       file_offset += size;
-       virt_offset += size;
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_GOT_PLT].sh_addralign);
-       virt_offset = ALIGN_TO (virt_offset, secth [SECT_GOT_PLT].sh_addralign);
-       secth [SECT_GOT_PLT].sh_addr = virt_offset;
-       secth [SECT_GOT_PLT].sh_offset = file_offset;
-       size = 3 * TARGET_SIZEOF_VOID_P;
-       secth [SECT_GOT_PLT].sh_size = size;
-       file_offset += size;
-       virt_offset += size;
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_DATA].sh_addralign);
-       virt_offset = ALIGN_TO (virt_offset, secth [SECT_DATA].sh_addralign);
-       secth [SECT_DATA].sh_addr = virt_offset;
-       secth [SECT_DATA].sh_offset = file_offset;
-       if (sections [SECT_DATA]) {
-               size = sections [SECT_DATA]->cur_offset;
-               secth [SECT_DATA].sh_size = size;
-               file_offset += size;
-               virt_offset += size;
-       }
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_BSS].sh_addralign);
-       virt_offset = ALIGN_TO (virt_offset, secth [SECT_BSS].sh_addralign);
-       secth [SECT_BSS].sh_addr = virt_offset;
-       secth [SECT_BSS].sh_offset = file_offset;
-       if (sections [SECT_BSS]) {
-               size = sections [SECT_BSS]->cur_offset;
-               secth [SECT_BSS].sh_size = size;
-       }
-
-       /* virtual doesn't matter anymore */
-       file_offset = ALIGN_TO (file_offset, secth [SECT_DEBUG_FRAME].sh_addralign);
-       secth [SECT_DEBUG_FRAME].sh_offset = file_offset;
-       if (sections [SECT_DEBUG_FRAME])
-               size = sections [SECT_DEBUG_FRAME]->cur_offset;
-       else
-               size = 0;
-       secth [SECT_DEBUG_FRAME].sh_size = size;
-       file_offset += size;
-
-       secth [SECT_DEBUG_INFO].sh_offset = file_offset;
-       if (sections [SECT_DEBUG_INFO])
-               size = sections [SECT_DEBUG_INFO]->cur_offset;
-       else
-               size = 0;
-       secth [SECT_DEBUG_INFO].sh_size = size;
-       file_offset += size;
-
-       secth [SECT_DEBUG_ABBREV].sh_offset = file_offset;
-       if (sections [SECT_DEBUG_ABBREV])
-               size = sections [SECT_DEBUG_ABBREV]->cur_offset;
-       else
-               size = 0;
-       secth [SECT_DEBUG_ABBREV].sh_size = size;
-       file_offset += size;
-
-       secth [SECT_DEBUG_LINE].sh_offset = file_offset;
-       if (sections [SECT_DEBUG_LINE])
-               size = sections [SECT_DEBUG_LINE]->cur_offset;
-       else
-               size = 0;
-       secth [SECT_DEBUG_LINE].sh_size = size;
-       file_offset += size;
-
-       secth [SECT_DEBUG_LOC].sh_offset = file_offset;
-       if (sections [SECT_DEBUG_LOC])
-               size = sections [SECT_DEBUG_LOC]->cur_offset;
-       else
-               size = 0;
-       secth [SECT_DEBUG_LOC].sh_size = size;
-       file_offset += size;
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_SHSTRTAB].sh_addralign);
-       secth [SECT_SHSTRTAB].sh_offset = file_offset;
-       size = sh_str_table.data->len;
-       secth [SECT_SHSTRTAB].sh_size = size;
-       file_offset += size;
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_SYMTAB].sh_addralign);
-       secth [SECT_SYMTAB].sh_offset = file_offset;
-       size = sizeof (ElfSymbol) * num_local_syms;
-       secth [SECT_SYMTAB].sh_size = size;
-       file_offset += size;
-
-       file_offset = ALIGN_TO (file_offset, secth [SECT_STRTAB].sh_addralign);
-       secth [SECT_STRTAB].sh_offset = file_offset;
-       size = str_table.data->len;
-       secth [SECT_STRTAB].sh_size = size;
-       file_offset += size;
-
-       for (i = 1; i < SECT_NUM; ++i) {
-               if (section_info [i].esize != 0)
-                       g_assert (secth [i].sh_size % section_info [i].esize == 0);
-       }
-
-       file_offset += 4-1;
-       file_offset &= ~(4-1);
-
-       header.e_ident [EI_MAG0] = ELFMAG0;
-       header.e_ident [EI_MAG1] = ELFMAG1;
-       header.e_ident [EI_MAG2] = ELFMAG2;
-       header.e_ident [EI_MAG3] = ELFMAG3;
-       header.e_ident [EI_CLASS] = TARGET_SIZEOF_VOID_P == 4 ? ELFCLASS32 : ELFCLASS64;
-       header.e_ident [EI_DATA] = ELFDATA2LSB;
-       header.e_ident [EI_VERSION] = EV_CURRENT;
-       header.e_ident [EI_OSABI] = ELFOSABI_NONE;
-       header.e_ident [EI_ABIVERSION] = 0;
-       for (i = EI_PAD; i < EI_NIDENT; ++i)
-               header.e_ident [i] = 0;
-
-       header.e_type = ET_DYN;
-#if defined(TARGET_X86)
-       header.e_machine = EM_386;
-#elif defined(TARGET_AMD64)
-       header.e_machine = EM_X86_64;
-#elif defined(TARGET_ARM)
-       header.e_machine = EM_ARM;
-#else
-       g_assert_not_reached ();
-#endif
-       header.e_version = 1;
-
-       header.e_phoff = sizeof (header);
-       header.e_ehsize = sizeof (header);
-       header.e_phentsize = sizeof (ElfProgHeader);
-       header.e_phnum = 4;
-       header.e_entry = secth [SECT_TEXT].sh_addr;
-       header.e_shstrndx = SECT_SHSTRTAB;
-       header.e_shentsize = sizeof (ElfSectHeader);
-       header.e_shnum = SECT_NUM;
-       header.e_shoff = file_offset;
-
-       /* dynamic data */
-       i = 0;
-       dynamic [i].d_tag = DT_HASH;
-       dynamic [i].d_un.d_val = secth [SECT_HASH].sh_offset;
-       ++i;
-       dynamic [i].d_tag = DT_STRTAB;
-       dynamic [i].d_un.d_val = secth [SECT_DYNSTR].sh_offset;
-       ++i;
-       dynamic [i].d_tag = DT_SYMTAB;
-       dynamic [i].d_un.d_val = secth [SECT_DYNSYM].sh_offset;
-       ++i;
-       dynamic [i].d_tag = DT_STRSZ;
-       dynamic [i].d_un.d_val = dyn_str_table.data->len;
-       ++i;
-       dynamic [i].d_tag = DT_SYMENT;
-       dynamic [i].d_un.d_val = sizeof (ElfSymbol);
-       ++i;
-#ifdef USE_ELF_RELA
-       dynamic [i].d_tag = DT_RELA;
-       dynamic [i].d_un.d_val = secth [SECT_RELA_DYN].sh_offset;
-       ++i;
-       dynamic [i].d_tag = DT_RELASZ;
-       dynamic [i].d_un.d_val = secth [SECT_RELA_DYN].sh_size;
-       ++i;
-       dynamic [i].d_tag = DT_RELAENT;
-       dynamic [i].d_un.d_val = sizeof (ElfRelocA);
-       ++i;
-#else
-       dynamic [i].d_tag = DT_REL;
-       dynamic [i].d_un.d_val = secth [SECT_REL_DYN].sh_offset;
-       ++i;
-       dynamic [i].d_tag = DT_RELSZ;
-       dynamic [i].d_un.d_val = secth [SECT_REL_DYN].sh_size;
-       ++i;
-       dynamic [i].d_tag = DT_RELENT;
-       dynamic [i].d_un.d_val = sizeof (ElfReloc);
-       ++i;
-#endif
-       dynamic [i].d_tag = DT_RELCOUNT;
-       dynamic [i].d_un.d_val = acfg->num_relocs;
-       ++i;
-
-       /* Program header */
-       memset (&progh, 0, sizeof (progh));
-       progh [0].p_type = PT_LOAD;
-       progh [0].p_filesz = progh [0].p_memsz = secth [SECT_DYNAMIC].sh_offset;
-       progh [0].p_align = 4096;
-       progh [0].p_flags = 5;
-
-       progh [1].p_type = PT_LOAD;
-       progh [1].p_offset = secth [SECT_DYNAMIC].sh_offset;
-       progh [1].p_vaddr = progh [1].p_paddr = secth [SECT_DYNAMIC].sh_addr;
-       progh [1].p_filesz = secth [SECT_BSS].sh_offset  - secth [SECT_DYNAMIC].sh_offset;
-       progh [1].p_memsz = secth [SECT_BSS].sh_addr + secth [SECT_BSS].sh_size - secth [SECT_DYNAMIC].sh_addr;
-       progh [1].p_align = 4096;
-       progh [1].p_flags = 6;
-
-       progh [2].p_type = PT_DYNAMIC;
-       progh [2].p_offset = secth [SECT_DYNAMIC].sh_offset;
-       progh [2].p_vaddr = progh [2].p_paddr = secth [SECT_DYNAMIC].sh_addr;
-       progh [2].p_filesz = progh [2].p_memsz = secth [SECT_DYNAMIC].sh_size;
-       progh [2].p_align = TARGET_SIZEOF_VOID_P;
-       progh [2].p_flags = 6;
-
-       progh [3].p_type = PT_GNU_STACK;
-       progh [3].p_offset = secth [SECT_DYNAMIC].sh_offset;
-       progh [3].p_vaddr = progh [3].p_paddr = secth [SECT_DYNAMIC].sh_addr;
-       progh [3].p_filesz = progh [3].p_memsz = secth [SECT_DYNAMIC].sh_size;
-       progh [3].p_align = TARGET_SIZEOF_VOID_P;
-       progh [3].p_flags = 6;
-
-       /* Compute the addresses of the bin sections, so relocation can be done */
-       for (i = 0; i < SECT_NUM; ++i) {
-               if (sections [i]) {
-                       sections [i]->file_offset = secth [i].sh_offset;
-                       sections [i]->virt_offset = secth [i].sh_addr;
-               }
-       }
-
-       reloc_symbols (acfg, dynsym, secth, &dyn_str_table, TRUE);
-       reloc_symbols (acfg, symtab, secth, &str_table, FALSE);
-       relocs = resolve_relocations (acfg);
-
-       if (!acfg->fp) {
-               acfg->out_buf_size = file_offset + sizeof (secth);
-               acfg->out_buf = (guint8 *)g_malloc (acfg->out_buf_size);
-       }
-
-       bin_writer_fwrite (acfg, &header, sizeof (header), 1);
-       bin_writer_fwrite (acfg, &progh, sizeof (progh), 1);
-       bin_writer_fwrite (acfg, hash, sizeof (int) * (hash [0] + hash [1] + 2), 1);
-       bin_writer_fwrite (acfg, dynsym, sizeof (ElfSymbol) * hash [1], 1);
-       bin_writer_fwrite (acfg, dyn_str_table.data->str, dyn_str_table.data->len, 1);
-       /* .rel.dyn */
-       bin_writer_fseek (acfg, secth [SECT_REL_DYN].sh_offset);
-       bin_writer_fwrite (acfg, relocs, sizeof (ElfReloc), acfg->num_relocs);
-
-       /* .rela.dyn */
-       bin_writer_fseek (acfg, secth [SECT_RELA_DYN].sh_offset);
-       bin_writer_fwrite (acfg, relocs, secth [SECT_RELA_DYN].sh_size, 1);
-
-       /* .text */
-       if (sections [SECT_TEXT]) {
-               bin_writer_fseek (acfg, secth [SECT_TEXT].sh_offset);
-               bin_writer_fwrite (acfg, sections [SECT_TEXT]->data, sections [SECT_TEXT]->cur_offset, 1);
-       }
-       /* .rodata */
-       if (sections [SECT_RODATA]) {
-               bin_writer_fseek (acfg, secth [SECT_RODATA].sh_offset);
-               bin_writer_fwrite (acfg, sections [SECT_RODATA]->data, sections [SECT_RODATA]->cur_offset, 1);
-       }
-       /* .dynamic */
-       bin_writer_fseek (acfg, secth [SECT_DYNAMIC].sh_offset);
-       bin_writer_fwrite (acfg, dynamic, sizeof (dynamic), 1);
-
-       /* .got.plt */
-       size = secth [SECT_DYNAMIC].sh_addr;
-       bin_writer_fseek (acfg, secth [SECT_GOT_PLT].sh_offset);
-       bin_writer_fwrite (acfg, &size, sizeof (size), 1);
-
-       /* normal sections */
-       for (i = 0; i < sizeof (normal_sections) / sizeof (normal_sections [0]); ++i) {
-               int sect = normal_sections [i];
-
-               if (sections [sect]) {
-                       bin_writer_fseek (acfg, secth [sect].sh_offset);
-                       bin_writer_fwrite (acfg, sections [sect]->data, sections [sect]->cur_offset, 1);
-               }
-       }
-
-       bin_writer_fseek (acfg, secth [SECT_SHSTRTAB].sh_offset);
-       bin_writer_fwrite (acfg, sh_str_table.data->str, sh_str_table.data->len, 1);
-       bin_writer_fseek (acfg, secth [SECT_SYMTAB].sh_offset);
-       bin_writer_fwrite (acfg, symtab, sizeof (ElfSymbol) * num_local_syms, 1);
-       bin_writer_fseek (acfg, secth [SECT_STRTAB].sh_offset);
-       bin_writer_fwrite (acfg, str_table.data->str, str_table.data->len, 1);
-       /*g_print ("file_offset %d vs %d\n", file_offset, ftell (file));*/
-       /*g_assert (file_offset >= ftell (file));*/
-       bin_writer_fseek (acfg, file_offset);
-       bin_writer_fwrite (acfg, &secth, sizeof (secth), 1);
-
-       if (acfg->fp)
-               fclose (acfg->fp);
-
-       return 0;
-}
-
-#endif /* USE_ELF_WRITER */
-
-#endif /* USE_BIN_WRITER */
-
 /* ASM WRITER */
 
 static void
@@ -1852,7 +336,6 @@ asm_writer_emit_alignment (MonoImageWriter *acfg, int size)
 #endif
 }
 
-#ifndef USE_BIN_WRITER
 static void 
 asm_writer_emit_alignment_fill (MonoImageWriter *acfg, int size, int fill)
 {
@@ -1863,7 +346,6 @@ asm_writer_emit_alignment_fill (MonoImageWriter *acfg, int size, int fill)
        asm_writer_emit_alignment (acfg, size);
 #endif
 }
-#endif
 
 static void
 asm_writer_emit_pointer_unaligned (MonoImageWriter *acfg, const char *target)
@@ -2019,27 +501,13 @@ asm_writer_emit_zero_bytes (MonoImageWriter *acfg, int num)
 void
 mono_img_writer_emit_start (MonoImageWriter *acfg)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_start (acfg);
-       else
-               asm_writer_emit_start (acfg);
-#else
        asm_writer_emit_start (acfg);
-#endif
 }
 
 void
 mono_img_writer_emit_section_change (MonoImageWriter *acfg, const char *section_name, int subsection_index)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_section_change (acfg, section_name, subsection_index);
-       else
-               asm_writer_emit_section_change (acfg, section_name, subsection_index);
-#else
        asm_writer_emit_section_change (acfg, section_name, subsection_index);
-#endif
 
        acfg->current_section = section_name;
        acfg->current_subsection = subsection_index;
@@ -2067,229 +535,109 @@ mono_img_writer_emit_pop_section (MonoImageWriter *acfg)
 void
 mono_img_writer_set_section_addr (MonoImageWriter *acfg, guint64 addr)
 {
-#ifdef USE_BIN_WRITER
-       if (!acfg->use_bin_writer)
-               NOT_IMPLEMENTED;
-       else
-               bin_writer_set_section_addr (acfg, addr);
-#else
        NOT_IMPLEMENTED;
-#endif
 }
 
 void
 mono_img_writer_emit_global (MonoImageWriter *acfg, const char *name, gboolean func)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_global (acfg, name, func);
-       else
-               asm_writer_emit_global (acfg, name, func);
-#else
        asm_writer_emit_global (acfg, name, func);
-#endif
 }
 
 void
 mono_img_writer_emit_local_symbol (MonoImageWriter *acfg, const char *name, const char *end_label, gboolean func)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_local_symbol (acfg, name, end_label, func);
-       else
-               asm_writer_emit_local_symbol (acfg, name, end_label, func);
-#else
        asm_writer_emit_local_symbol (acfg, name, end_label, func);
-#endif
 }
 
 void
 mono_img_writer_emit_symbol_size (MonoImageWriter *acfg, const char *name, const char *end_label)
 {
-       if (!acfg->use_bin_writer)
-               asm_writer_emit_symbol_size (acfg, name, end_label);
+       asm_writer_emit_symbol_size (acfg, name, end_label);
 }
 
 void
 mono_img_writer_emit_label (MonoImageWriter *acfg, const char *name)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_label (acfg, name);
-       else
-               asm_writer_emit_label (acfg, name);
-#else
        asm_writer_emit_label (acfg, name);
-#endif
 }
 
 void
 mono_img_writer_emit_bytes (MonoImageWriter *acfg, const guint8* buf, int size)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_bytes (acfg, buf, size);
-       else
-               asm_writer_emit_bytes (acfg, buf, size);
-#else
        asm_writer_emit_bytes (acfg, buf, size);
-#endif
 }
 
 void
 mono_img_writer_emit_string (MonoImageWriter *acfg, const char *value)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_string (acfg, value);
-       else
-               asm_writer_emit_string (acfg, value);
-#else
        asm_writer_emit_string (acfg, value);
-#endif
 }
 
 void
 mono_img_writer_emit_line (MonoImageWriter *acfg)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_line (acfg);
-       else
-               asm_writer_emit_line (acfg);
-#else
-               asm_writer_emit_line (acfg);
-#endif
+       asm_writer_emit_line (acfg);
 }
 
 void
 mono_img_writer_emit_alignment (MonoImageWriter *acfg, int size)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_alignment (acfg, size);
-       else
-               asm_writer_emit_alignment (acfg, size);
-#else
        asm_writer_emit_alignment (acfg, size);
-#endif
 }
 
 void
 mono_img_writer_emit_alignment_fill (MonoImageWriter *acfg, int size, int fill)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_alignment (acfg, size);
-       else
-               asm_writer_emit_alignment (acfg, size);
-#else
        asm_writer_emit_alignment_fill (acfg, size, fill);
-#endif
 }
 
 void
 mono_img_writer_emit_pointer_unaligned (MonoImageWriter *acfg, const char *target)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_pointer_unaligned (acfg, target);
-       else
-               asm_writer_emit_pointer_unaligned (acfg, target);
-#else
        asm_writer_emit_pointer_unaligned (acfg, target);
-#endif
 }
 
 void
 mono_img_writer_emit_pointer (MonoImageWriter *acfg, const char *target)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_pointer (acfg, target);
-       else
-               asm_writer_emit_pointer (acfg, target);
-#else
        asm_writer_emit_pointer (acfg, target);
-#endif
 }
 
 void
 mono_img_writer_emit_int16 (MonoImageWriter *acfg, int value)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_int16 (acfg, value);
-       else
-               asm_writer_emit_int16 (acfg, value);
-#else
        asm_writer_emit_int16 (acfg, value);
-#endif
 }
 
 void
 mono_img_writer_emit_int32 (MonoImageWriter *acfg, int value)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_int32 (acfg, value);
-       else
-               asm_writer_emit_int32 (acfg, value);
-#else
        asm_writer_emit_int32 (acfg, value);
-#endif
 }
 
 void
 mono_img_writer_emit_symbol (MonoImageWriter *acfg, const char *symbol)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_symbol (acfg, symbol);
-       else
-               asm_writer_emit_symbol (acfg, symbol);
-#else
        asm_writer_emit_symbol (acfg, symbol);
-#endif
 }
 
 void
 mono_img_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_symbol_diff (acfg, end, start, offset);
-       else
-               asm_writer_emit_symbol_diff (acfg, end, start, offset);
-#else
        asm_writer_emit_symbol_diff (acfg, end, start, offset);
-#endif
 }
 
 void
 mono_img_writer_emit_zero_bytes (MonoImageWriter *acfg, int num)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_zero_bytes (acfg, num);
-       else
-               asm_writer_emit_zero_bytes (acfg, num);
-#else
        asm_writer_emit_zero_bytes (acfg, num);
-#endif
 }
 
 int
 mono_img_writer_emit_writeout (MonoImageWriter *acfg)
 {
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               return bin_writer_emit_writeout (acfg);
-       else
-               return asm_writer_emit_writeout (acfg);
-#else
-               return asm_writer_emit_writeout (acfg);
-#endif
+       return asm_writer_emit_writeout (acfg);
 }
 
 void
@@ -2305,15 +653,7 @@ mono_img_writer_emit_byte (MonoImageWriter *acfg, guint8 val)
 void
 mono_img_writer_emit_reloc (MonoImageWriter *acfg, int reloc_type, const char *symbol, int addend)
 {
-       /* This is only supported by the bin writer */
-#ifdef USE_BIN_WRITER
-       if (acfg->use_bin_writer)
-               bin_writer_emit_reloc (acfg, reloc_type, symbol, addend);
-       else
-               g_assert_not_reached ();
-#else
-               g_assert_not_reached ();
-#endif
+       g_assert_not_reached ();
 }
 
 /*
@@ -2325,8 +665,7 @@ mono_img_writer_emit_reloc (MonoImageWriter *acfg, int reloc_type, const char *s
 void
 mono_img_writer_emit_unset_mode (MonoImageWriter *acfg)
 {
-       if (!acfg->use_bin_writer)
-               asm_writer_emit_unset_mode (acfg);
+       asm_writer_emit_unset_mode (acfg);
 }
 
 /*
@@ -2338,55 +677,23 @@ mono_img_writer_emit_unset_mode (MonoImageWriter *acfg)
 guint8*
 mono_img_writer_get_output (MonoImageWriter *acfg, guint32 *size)
 {
-#ifdef USE_BIN_WRITER
-       guint8 *buf;
-
-       g_assert (acfg->use_bin_writer);
-
-       buf = acfg->out_buf;
-       *size = acfg->out_buf_size;
-       acfg->out_buf = NULL;
-       return buf;
-#else
        g_assert_not_reached ();
        return NULL;
-#endif
-}
-
-/*
- * Return whenever the binary writer is supported on this platform.
- */
-gboolean
-mono_bin_writer_supported (void)
-{
-#ifdef USE_BIN_WRITER
-       return TRUE;
-#else
-       return FALSE;
-#endif
 }
 
 /*
  * mono_img_writer_create:
  *
- *   Create an image writer writing to FP. If USE_BIN_WRITER is TRUE, FP can be NULL,
- * in this case the image writer will write to a memory buffer obtainable by calling
- * mono_img_writer_get_output ().
+ *   Create an image writer writing to FP.
  */
 MonoImageWriter*
-mono_img_writer_create (FILE *fp, gboolean use_bin_writer)
+mono_img_writer_create (FILE *fp)
 {
        MonoImageWriter *w = g_new0 (MonoImageWriter, 1);
-       
-#ifndef USE_BIN_WRITER
-       g_assert (!use_bin_writer);
-#endif
 
-       if (!use_bin_writer)
-               g_assert (fp);
+       g_assert (fp);
 
        w->fp = fp;
-       w->use_bin_writer = use_bin_writer;
        w->mempool = mono_mempool_new ();
 
        return w;
@@ -2404,7 +711,7 @@ gboolean
 mono_img_writer_subsections_supported (MonoImageWriter *acfg)
 {
 #ifdef TARGET_ASM_APPLE
-       return acfg->use_bin_writer;
+       return FALSE;
 #else
        return TRUE;
 #endif
index 309ec37..c6d855f 100644 (file)
 
 typedef struct _MonoImageWriter MonoImageWriter;
 
-#if defined(TARGET_AMD64) && !defined(HOST_WIN32) && !defined(__APPLE__)
-#define USE_ELF_WRITER 1
-#define USE_ELF_RELA 1
-#endif
-
-#if defined(TARGET_X86) && !defined(HOST_WIN32) && !defined(__APPLE__)
-#define USE_ELF_WRITER 1
-#endif
-
-#if defined(TARGET_ARM) && !defined(TARGET_MACH) && !defined(HOST_WIN32)
-//#define USE_ELF_WRITER 1
-#endif
-
-#if defined(__mips__)
-#define USE_ELF_WRITER 1
-#endif
-
-#if defined(TARGET_X86) && defined(__APPLE__)
-//#define USE_MACH_WRITER
-#endif
-
-#if defined(USE_ELF_WRITER) || defined(USE_MACH_WRITER)
-#define USE_BIN_WRITER 1
-#endif
-
-/* Relocation types */
-#define R_ARM_CALL 28
-#define R_ARM_JUMP24 29
-#define R_ARM_ALU_PC_G0_NC 59
-
-gboolean mono_bin_writer_supported (void);
-
-MonoImageWriter* mono_img_writer_create (FILE *fp, gboolean use_bin_writer);
+MonoImageWriter* mono_img_writer_create (FILE *fp);
 
 void mono_img_writer_destroy (MonoImageWriter *w);
 
index 36400c7..bea43f2 100644 (file)
@@ -523,7 +523,6 @@ mono_tramp_info_register_internal (MonoTrampInfo *info, MonoMemoryManager *mem_m
                copy->uw_info_len = info->uw_info_len;
        }
 
-       mono_save_trampoline_xdebug_info (info);
        mono_lldb_save_trampoline_info (info);
 
 #ifdef MONO_ARCH_HAVE_UNWIND_TABLE
@@ -3934,7 +3933,7 @@ mini_parse_debug_option (const char *option)
        else if (!strcmp (option, "dyn-runtime-invoke"))
                mini_debug_options.dyn_runtime_invoke = TRUE;
        else if (!strcmp (option, "gdb"))
-               mini_debug_options.gdb = TRUE;
+               fprintf (stderr, "MONO_DEBUG=gdb is deprecated.");
        else if (!strcmp (option, "lldb"))
                mini_debug_options.lldb = TRUE;
        else if (!strcmp (option, "llvm-disable-inlining"))
@@ -4431,21 +4430,6 @@ mini_init (const char *filename, const char *runtime_version)
                mono_dont_free_domains = TRUE;
        }
 
-#ifdef XDEBUG_ENABLED
-       char *mono_xdebug = g_getenv ("MONO_XDEBUG");
-       if (mono_xdebug) {
-               mono_xdebug_init (mono_xdebug);
-               g_free (mono_xdebug);
-               /* So methods for multiple domains don't have the same address */
-               mono_dont_free_domains = TRUE;
-               mono_using_xdebug = TRUE;
-       } else if (mini_debug_options.gdb) {
-               mono_xdebug_init ((char*)"gdb");
-               mono_dont_free_domains = TRUE;
-               mono_using_xdebug = TRUE;
-       }
-#endif
-
 #ifdef ENABLE_LLVM
        if (mono_use_llvm)
                mono_llvm_init (!mono_compile_aot);
index 2e349a3..562d98e 100644 (file)
@@ -245,7 +245,6 @@ typedef struct MonoDebugOptions {
        gboolean suspend_on_exception;
        gboolean suspend_on_unhandled;
        gboolean dyn_runtime_invoke;
-       gboolean gdb;
        gboolean lldb;
 
        /*
@@ -572,10 +571,6 @@ MONO_API int mono_ee_api_version (void);
 gboolean  mono_debug_count                  (void);
 
 #ifdef __linux__
-#define XDEBUG_ENABLED 1
-#endif
-
-#ifdef __linux__
 /* maybe enable also for other systems? */
 #define ENABLE_JIT_MAP 1
 void mono_enable_jit_map (void);
index 28ce38a..f3cfa38 100644 (file)
@@ -83,7 +83,6 @@ int mono_inject_async_exc_pos;
 MonoMethodDesc *mono_break_at_bb_method;
 int mono_break_at_bb_bb_num;
 gboolean mono_do_x86_stack_align = TRUE;
-gboolean mono_using_xdebug;
 
 /* Counters */
 static guint32 discarded_code;
@@ -2046,19 +2045,9 @@ mono_codegen (MonoCompile *cfg)
        MonoBasicBlock *bb;
        int max_epilog_size;
        guint8 *code;
-       MonoMemoryManager *code_mem_manager;
+       MonoMemoryManager *code_mem_manager = cfg->mem_manager;
        guint unwindlen = 0;
 
-       if (mono_using_xdebug)
-               /*
-                * Recent gdb versions have trouble processing symbol files containing
-                * overlapping address ranges, so allocate all code from the code manager
-                * of the root domain. (#666152).
-                */
-               code_mem_manager = get_default_mem_manager ();
-       else
-               code_mem_manager = cfg->mem_manager;
-
        for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
                cfg->spill_count = 0;
                /* we reuse dfn here */
@@ -2133,11 +2122,7 @@ mono_codegen (MonoCompile *cfg)
                g_hash_table_insert (jit_mm->dynamic_code_hash, cfg->method, cfg->dynamic_info);
                jit_mm_unlock (jit_mm);
 
-               if (mono_using_xdebug)
-                       /* See the comment for cfg->code_domain */
-                       code = (guint8 *)mono_mem_manager_code_reserve (code_mem_manager, cfg->code_size + cfg->thunk_area + unwindlen);
-               else
-                       code = (guint8 *)mono_code_manager_reserve (cfg->dynamic_info->code_mp, cfg->code_size + cfg->thunk_area + unwindlen);
+               code = (guint8 *)mono_code_manager_reserve (cfg->dynamic_info->code_mp, cfg->code_size + cfg->thunk_area + unwindlen);
        } else {
                code = (guint8 *)mono_mem_manager_code_reserve (code_mem_manager, cfg->code_size + cfg->thunk_area + unwindlen);
        }
@@ -2220,10 +2205,7 @@ mono_codegen (MonoCompile *cfg)
        }
 
        if (cfg->method->dynamic) {
-               if (mono_using_xdebug)
-                       mono_mem_manager_code_commit (code_mem_manager, cfg->native_code, cfg->code_size, cfg->code_len);
-               else
-                       mono_code_manager_commit (cfg->dynamic_info->code_mp, cfg->native_code, cfg->code_size, cfg->code_len);
+               mono_code_manager_commit (cfg->dynamic_info->code_mp, cfg->native_code, cfg->code_size, cfg->code_len);
        } else {
                mono_mem_manager_code_commit (code_mem_manager, cfg->native_code, cfg->code_size, cfg->code_len);
        }
@@ -3381,18 +3363,6 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts
                cfg->disable_out_of_line_bblocks = TRUE;
        }
 
-       if (mono_using_xdebug) {
-               /* 
-                * Make each variable use its own register/stack slot and extend 
-                * their liveness to cover the whole method, making them displayable
-                * in gdb even after they are dead.
-                */
-               cfg->disable_reuse_registers = TRUE;
-               cfg->disable_reuse_stack_slots = TRUE;
-               cfg->extend_live_ranges = TRUE;
-               cfg->compute_precise_live_ranges = TRUE;
-       }
-
        mini_gc_init_cfg (cfg);
 
        if (method->wrapper_type == MONO_WRAPPER_OTHER) {
@@ -3932,10 +3902,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, JitFlags flags, int parts
        MONO_TIME_TRACK (mono_jit_stats.jit_gc_create_gc_map, mini_gc_create_gc_map (cfg));
        MONO_TIME_TRACK (mono_jit_stats.jit_save_seq_point_info, mono_save_seq_point_info (cfg, cfg->jit_info));
 
-       if (!cfg->compile_aot) {
-               mono_save_xdebug_info (cfg);
+       if (!cfg->compile_aot)
                mono_lldb_save_method_info (cfg);
-       }
 
        if (cfg->verbose_level >= 2) {
                char *id =  mono_method_full_name (cfg->method, TRUE);
index e454d89..5001ee3 100644 (file)
@@ -365,7 +365,6 @@ extern int mono_inject_async_exc_pos;
 extern MonoMethodDesc *mono_break_at_bb_method;
 extern int mono_break_at_bb_bb_num;
 extern gboolean mono_do_x86_stack_align;
-extern gboolean        mono_using_xdebug;
 extern int mini_verbose;
 extern int valgrind_register;
 
@@ -2206,12 +2205,6 @@ void      mono_liveness_handle_exception_clauses (MonoCompile *cfg);
 
 gpointer mono_realloc_native_code (MonoCompile *cfg);
 
-void     mono_xdebug_init                   (const char *xdebug_opts);
-void     mono_save_xdebug_info              (MonoCompile *cfg);
-void     mono_save_trampoline_xdebug_info   (MonoTrampInfo *info);
-/* This is an exported function */
-void     mono_xdebug_flush                  (void);
-
 void      mono_register_opcode_emulation    (int opcode, const char* name, MonoMethodSignature *sig, gpointer func, gboolean no_throw);
 void      mono_draw_graph                   (MonoCompile *cfg, MonoGraphOptions draw_options);
 void      mono_add_ins_to_end               (MonoBasicBlock *bb, MonoInst *inst);
diff --git a/src/mono/mono/mini/xdebug.c b/src/mono/mono/mini/xdebug.c
deleted file mode 100644 (file)
index 868acaa..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/**
- * \file
- * Support for emitting gdb debug info for JITted code.
- *
- * Author:
- *   Zoltan Varga (vargaz@gmail.com)
- *
- * (C) 2010 Novell, Inc.
- */
-
-/*
- * This works as follows:
- * - the runtime writes out an xdb.s file containing DWARF debug info.
- * - the user calls a gdb macro
- * - the macro compiles and loads this shared library using add-symbol-file.
- *
- * This is based on the xdebug functionality in the Kaffe Java VM.
- * 
- * We emit assembly code instead of using the ELF writer, so we can emit debug info
- * incrementally as each method is JITted, and the debugger doesn't have to call
- * into the runtime to emit the shared library, which would cause all kinds of
- * complications, like threading issues, and the fact that the ELF writer's
- * emit_writeout () function cannot be called more than once.
- * GDB 7.0 and later has a JIT interface.
- */
-
-#include "config.h"
-#include <glib.h>
-#include "mini.h"
-#include "mini-runtime.h"
-
-#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#include <fcntl.h>
-#include <ctype.h>
-#include <string.h>
-#ifndef HOST_WIN32
-#include <sys/time.h>
-#else
-#include <winsock2.h>
-#include <windows.h>
-#endif
-
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "image-writer.h"
-
-#if !defined(DISABLE_AOT) && !defined(DISABLE_JIT) && USE_BIN_WRITER
-
-#include "dwarfwriter.h"
-
-#include "mono/utils/mono-compiler.h"
-
-#define USE_GDB_JIT_INTERFACE
-
-/* The recommended gdb macro is: */
-/*
-  define xdb
-  shell rm -f xdb.so && as --64 -o xdb.o xdb.s && ld -shared -o xdb.so xdb.o
-  add-symbol-file xdb.so 0
-  end
-*/
-
-/*
- * GDB JIT interface definitions.
- *
- *     http://sources.redhat.com/gdb/onlinedocs/gdb_30.html
- */
-typedef enum
-{
-  JIT_NOACTION = 0,
-  JIT_REGISTER_FN,
-  JIT_UNREGISTER_FN
-} jit_actions_t;
-
-struct jit_code_entry;
-typedef struct jit_code_entry jit_code_entry;
-
-struct jit_code_entry
-{
-       jit_code_entry *next_entry;
-       jit_code_entry *prev_entry;
-       const char *symfile_addr;
-       /*
-        * The gdb code in gdb/jit.c which reads this structure ignores alignment
-        * requirements, so use two 32 bit fields.
-        */
-       guint32 symfile_size1, symfile_size2;
-};
-
-typedef struct jit_descriptor
-{
-       guint32 version;
-       /* This type should be jit_actions_t, but we use guint32
-          to be explicit about the bitwidth.  */
-       guint32 action_flag;
-       jit_code_entry *relevant_entry;
-       jit_code_entry *first_entry;
-} jit_descriptor;
-
-G_BEGIN_DECLS
-
-/* GDB puts a breakpoint in this function.  */
-void MONO_NEVER_INLINE __jit_debug_register_code(void);
-
-#if defined(ENABLE_LLVM) && !defined(MONO_CROSS_COMPILE)
-
-/* LLVM already defines these */
-
-extern jit_descriptor __jit_debug_descriptor;
-
-#else
-
-/* gcc seems to inline/eliminate calls to noinline functions, thus the asm () */
-void MONO_NEVER_INLINE __jit_debug_register_code(void) {
-#if defined(__GNUC__)
-       asm ("");
-#endif
-}
-
-/* Make sure to specify the version statically, because the
-   debugger may check the version before we can set it.  */
-jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
-
-#endif
-
-G_END_DECLS
-
-static MonoImageWriter *xdebug_w;
-static MonoDwarfWriter *xdebug_writer;
-static FILE *xdebug_fp, *il_file;
-static gboolean use_gdb_interface, save_symfiles;
-static int il_file_line_index;
-static GHashTable *xdebug_syms;
-
-void
-mono_xdebug_init (const char *options)
-{
-       MonoImageWriter *w;
-       char **args, **ptr;
-
-       args = g_strsplit (options, ",", -1);
-       for (ptr = args; ptr && *ptr; ptr ++) {
-               char *arg = *ptr;
-
-               if (!strcmp (arg, "gdb"))
-                       use_gdb_interface = TRUE;
-               if (!strcmp (arg, "save-symfiles"))
-                       save_symfiles = TRUE;
-       }
-
-       /* This file will contain the IL code for methods which don't have debug info */
-       il_file = fopen ("xdb.il", "w");
-       if (il_file == NULL) {
-               use_gdb_interface = FALSE;
-               g_warning ("** Unable to create xdb.il. Managed symbol names won't be available.");
-               return;
-       }
-
-       if (use_gdb_interface)
-               return;
-
-       unlink ("xdb.s");
-       xdebug_fp = fopen ("xdb.s", "w");
-       
-       w = mono_img_writer_create (xdebug_fp, FALSE);
-
-       mono_img_writer_emit_start (w);
-
-       xdebug_writer = mono_dwarf_writer_create (w, il_file, 0, TRUE);
-
-       /* Emit something so the file has a text segment */
-       mono_img_writer_emit_section_change (w, ".text", 0);
-       mono_img_writer_emit_string (w, "");
-
-       mono_dwarf_writer_emit_base_info (xdebug_writer, "JITted code", mono_unwind_get_cie_program ());
-}
-
-static void
-xdebug_begin_emit (MonoImageWriter **out_w, MonoDwarfWriter **out_dw)
-{
-       MonoImageWriter *w;
-       MonoDwarfWriter *dw;
-
-       w = mono_img_writer_create (NULL, TRUE);
-
-       mono_img_writer_emit_start (w);
-
-       /* This file will contain the IL code for methods which don't have debug info */
-       if (!il_file)
-               il_file = fopen ("xdb.il", "w");
-
-       dw = mono_dwarf_writer_create (w, il_file, il_file_line_index, TRUE);
-
-       mono_dwarf_writer_emit_base_info (dw, "JITted code", mono_unwind_get_cie_program ());
-
-       *out_w = w;
-       *out_dw = dw;
-}
-
-static void
-xdebug_end_emit (MonoImageWriter *w, MonoDwarfWriter *dw, MonoMethod *method)
-{
-       guint8 *img;
-       guint32 img_size;
-       jit_code_entry *entry;
-       guint64 *psize;
-
-       il_file_line_index = mono_dwarf_writer_get_il_file_line_index (dw);
-       mono_dwarf_writer_close (dw);
-
-       mono_img_writer_emit_writeout (w);
-
-       img = mono_img_writer_get_output (w, &img_size);
-
-       mono_img_writer_destroy (w);
-
-       if (FALSE) {
-               /* Save the symbol files to help debugging */
-               FILE *fp;
-               char *file_name;
-               static int file_counter;
-
-               file_counter ++;
-               file_name = g_strdup_printf ("xdb-%d.o", file_counter);
-               printf ("%s %p %d\n", file_name, img, img_size);
-
-               fp = fopen (file_name, "w");
-               fwrite (img, img_size, 1, fp);
-               fclose (fp);
-               g_free (file_name);
-       }
-
-       /* Register the image with GDB */
-
-       entry = g_malloc0 (sizeof (jit_code_entry));
-
-       entry->symfile_addr = (const char*)img;
-       psize = (guint64*)&entry->symfile_size1;
-       *psize = img_size;
-
-       entry->next_entry = __jit_debug_descriptor.first_entry;
-       if (__jit_debug_descriptor.first_entry)
-               __jit_debug_descriptor.first_entry->prev_entry = entry;
-       __jit_debug_descriptor.first_entry = entry;
-       
-       __jit_debug_descriptor.relevant_entry = entry;
-       __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
-
-       __jit_debug_register_code ();
-}
-
-/*
- * mono_xdebug_flush:
- *
- *   This could be called from inside gdb to flush the debugging information not yet
- * registered with gdb.
- */
-void
-mono_xdebug_flush (void)
-{
-       if (xdebug_w)
-               xdebug_end_emit (xdebug_w, xdebug_writer, NULL);
-
-       xdebug_begin_emit (&xdebug_w, &xdebug_writer);
-}
-
-static int xdebug_method_count;
-
-/*
- * mono_save_xdebug_info:
- *
- *   Emit debugging info for METHOD into an assembly file which can be assembled
- * and loaded into gdb to provide debugging info for JITted code.
- * LOCKING: Acquires the loader lock.
- */
-void
-mono_save_xdebug_info (MonoCompile *cfg)
-{
-       MonoDebugMethodJitInfo *dmji;
-
-       if (use_gdb_interface) {
-               mono_loader_lock ();
-
-               if (!xdebug_syms)
-                       xdebug_syms = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-               /*
-                * gdb is not designed to handle 1000s of symbol files (one per method). So we
-                * group them into groups of 100.
-                */
-               if ((xdebug_method_count % 100) == 0)
-                       mono_xdebug_flush ();
-
-               xdebug_method_count ++;
-
-               dmji = mono_debug_find_method (jinfo_get_method (cfg->jit_info), mono_domain_get ());
-               mono_dwarf_writer_emit_method (xdebug_writer, cfg, jinfo_get_method (cfg->jit_info), NULL, NULL, NULL,
-                                                                          (guint8*)cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, dmji);
-               mono_debug_free_method_jit_info (dmji);
-
-#if 0
-               /* 
-                * Emit a symbol for the code by emitting it at the beginning of the text 
-                * segment, and setting the text segment to have an absolute address.
-                * This symbol can be used to set breakpoints in gdb.
-                * FIXME: This doesn't work when multiple methods are emitted into the same file.
-                */
-               sym = get_debug_sym (cfg->jit_info->method, "", xdebug_syms);
-               mono_img_writer_emit_section_change (w, ".text", 0);
-               if (!xdebug_text_addr) {
-                       xdebug_text_addr = cfg->jit_info->code_start;
-                       mono_img_writer_set_section_addr (w, (gssize)xdebug_text_addr);
-               }
-               mono_img_writer_emit_global_with_size (w, sym, cfg->jit_info->code_size, TRUE);
-               mono_img_writer_emit_label (w, sym);
-               mono_img_writer_emit_bytes (w, cfg->jit_info->code_start, cfg->jit_info->code_size);
-               g_free (sym);
-#endif
-               
-               mono_loader_unlock ();
-       } else {
-               if (!xdebug_writer)
-                       return;
-
-               mono_loader_lock ();
-               dmji = mono_debug_find_method (jinfo_get_method (cfg->jit_info), mono_domain_get ());
-               mono_dwarf_writer_emit_method (xdebug_writer, cfg, jinfo_get_method (cfg->jit_info), NULL, NULL, NULL,
-                                                                          (guint8*)cfg->jit_info->code_start, cfg->jit_info->code_size, cfg->args, cfg->locals, cfg->unwind_ops, dmji);
-               mono_debug_free_method_jit_info (dmji);
-               fflush (xdebug_fp);
-               mono_loader_unlock ();
-       }
-
-}
-
-/*
- * mono_save_trampoline_xdebug_info:
- *
- *   Same as mono_save_xdebug_info, but for trampolines.
- * LOCKING: Acquires the loader lock.
- */
-void
-mono_save_trampoline_xdebug_info (MonoTrampInfo *info)
-{
-       const char *info_name = info->name;
-       if (info_name == NULL)
-               info_name = "";
-
-       if (use_gdb_interface) {
-               MonoImageWriter *w;
-               MonoDwarfWriter *dw;
-
-               /* This can be called before the loader lock is initialized */
-               mono_loader_lock_if_inited ();
-
-               xdebug_begin_emit (&w, &dw);
-
-               mono_dwarf_writer_emit_trampoline (dw, info_name, NULL, NULL, info->code, info->code_size, info->unwind_ops);
-
-               xdebug_end_emit (w, dw, NULL);
-               
-               mono_loader_unlock_if_inited ();
-       } else {
-               if (!xdebug_writer)
-                       return;
-
-               mono_loader_lock_if_inited ();
-               mono_dwarf_writer_emit_trampoline (xdebug_writer, info_name, NULL, NULL, info->code, info->code_size, info->unwind_ops);
-               fflush (xdebug_fp);
-               mono_loader_unlock_if_inited ();
-       }
-}
-
-#else /* !defined(DISABLE_AOT) && !defined(DISABLE_JIT) */
-
-void
-mono_xdebug_init (const char *options)
-{
-}
-
-void
-mono_save_xdebug_info (MonoCompile *cfg)
-{
-}
-
-void
-mono_save_trampoline_xdebug_info (MonoTrampInfo *info)
-{
-}
-
-#endif