- /* the first symbol is undef, all zeroes */
- i = 1;
- if (sheaders) {
- int j;
- for (j = 1; j < SECT_NUM; ++j) {
- symbols [i].st_info = SYM_LOCAL | SYM_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 = SYM_LOCAL | SYM_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->file_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->file_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->file_offset;
- }
- ++i;
- }
- }
- for (symbol = acfg->symbols; symbol; symbol = symbol->next) {
- int offset;
- BinLabel *lab;
- if (!symbol->is_global)
- continue;
- symbols [i].st_info = (symbol->is_function? SYM_FUNC : SYM_OBJECT) | SYM_GLOBAL;
- 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 = g_hash_table_lookup (acfg->labels, symbol->name);
- offset = lab->offset;
- if (section->parent) {
- symbols [i].st_value = section->parent->file_offset + section->cur_offset + offset;
- } else {
- symbols [i].st_value = section->file_offset + offset;
- }
- ++i;
- }
- /* add special symbols */
- symbols [i].st_name = str_table_add (strtab, "__bss_start");
- symbols [i].st_shndx = 0xfff1;
- symbols [i].st_info = SYM_GLOBAL;
- ++i;
- symbols [i].st_name = str_table_add (strtab, "_edata");
- symbols [i].st_shndx = 0xfff1;
- symbols [i].st_info = SYM_GLOBAL;
- ++i;
- symbols [i].st_name = str_table_add (strtab, "_end");
- symbols [i].st_shndx = 0xfff1;
- symbols [i].st_info = SYM_GLOBAL;
- ++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 (MonoAotCompile *acfg, ElfSymbol *symbols, struct 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 = 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 ElfReloc*
-resolve_relocations (MonoAotCompile *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) {
- 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->file_offset + reloc->val2_section->cur_offset;
- else
- start_val += reloc->val2_section->file_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->file_offset;
- vaddr += reloc->section->cur_offset;
- vaddr += reloc->section_offset;
- } else {
- data = reloc->section->data;
- data += reloc->section_offset;
- vaddr = reloc->section->file_offset;
- vaddr += reloc->section_offset;
- }
- /* FIXME: little endian */
- data [0] = end_val;
- data [1] = end_val >> 8;
- data [2] = end_val >> 16;
- data [3] = end_val >> 24;
- if (start_val == 0) {
- rr [i].addr = vaddr;
- rr [i].value = 8; /* FIXME: 386_RELATIVE */
- ++i;
- g_assert (i <= acfg->num_relocs);
- }
- }
- return rr;
-}
-
-static int
-emit_writeout (MonoAotCompile *acfg)
-{
- char *outfile_name, *tmp_outfile_name;
- FILE *file;
- struct ElfHeader header;
- struct ElfProgHeader progh [3];
- struct ElfSectHeader secth [SECT_NUM];
- ElfReloc *relocs;
- ElfStrTable str_table = {NULL, NULL};
- ElfStrTable sh_str_table = {NULL, NULL};
- ElfStrTable dyn_str_table = {NULL, NULL};
- BinSection* sections [6];
- BinSection *text_section = NULL, *data_section = NULL, *bss_section = NULL;
- ElfSymbol *dynsym;
- ElfSymbol *symtab;
- ElfDynamic dynamic [14];
- int *hash;
- int i, num_sections, file_offset, virt_offset, size, num_symtab;
- int num_local_syms;
-
- g_assert (!acfg->aot_opts.asm_only);
-
- if (acfg->aot_opts.outfile)
- outfile_name = g_strdup_printf ("%s", acfg->aot_opts.outfile);
- else
- outfile_name = g_strdup_printf ("%s%s", acfg->image->name, SHARED_EXT);
-
- tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name);
-
- unlink (tmp_outfile_name);
- file = fopen (tmp_outfile_name, "w");
- g_assert (file);
-
- /* Section headers */
- memset (§h, 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_names [i]);
- secth [i].sh_type = section_type [i];
- secth [i].sh_link = section_link [i];
- secth [i].sh_addralign = section_align [i];
- secth [i].sh_flags = section_flags [i];
- secth [i].sh_entsize = section_esize [i];
- }
- secth [SECT_DYNSYM].sh_info = 4;
- secth [SECT_SYMTAB].sh_info = 20;
-
- num_sections = collect_sections (acfg, secth, sections, 6);
- hash = build_hash (acfg, num_sections, &dyn_str_table);
- num_symtab = hash [1]; /* FIXME */
- g_print ("num_sections: %d\n", num_sections);
- g_print ("dynsym: %d, dynstr size: %d\n", hash [1], dyn_str_table.data->len);
- for (i = 0; i < num_sections; ++i) {
- g_print ("section %s, size: %d, %x\n", sections [i]->name, sections [i]->cur_offset, sections [i]->cur_offset);
- }
-
- /* 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);
-
- for (i = 0; i < num_sections; ++i) {
- if (sections [i]->shidx == SECT_TEXT) {
- text_section = sections [i];
- } else if (sections [i]->shidx == SECT_DATA) {
- data_section = sections [i];
- } else if (sections [i]->shidx == SECT_BSS) {
- bss_section = sections [i];
- }
- }
-
- 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;
- size = sizeof (ElfReloc) * acfg->num_relocs;
- secth [SECT_REL_DYN].sh_size = size;
- virt_offset = (file_offset += size);
- secth [SECT_REL_DYN].sh_size = size;
- file_offset += 4096-1;
- file_offset &= ~(4096-1);
- virt_offset = file_offset;
- secth [SECT_TEXT].sh_addr = secth [SECT_TEXT].sh_offset = file_offset;
- size = text_section->cur_offset;
- secth [SECT_TEXT].sh_size = size;
- file_offset += size;
- file_offset += 4-1;
- file_offset &= ~(4-1);
- virt_offset = file_offset;
- /* .dynamic, .got.plt, .data, .bss here */
- secth [SECT_DYNAMIC].sh_addr = virt_offset;
- secth [SECT_DYNAMIC].sh_offset = file_offset;
- size = sizeof (dynamic);
- secth [SECT_DYNAMIC].sh_size = size;
- size += 4-1;
- size &= ~(4-1);
- file_offset += size;
- virt_offset += size;
- secth [SECT_GOT_PLT].sh_addr = virt_offset;
- secth [SECT_GOT_PLT].sh_offset = file_offset;
- size = 12;
- secth [SECT_GOT_PLT].sh_size = size;
- size += 8-1;
- size &= ~(8-1);
- file_offset += size;
- virt_offset += size;
- secth [SECT_DATA].sh_addr = virt_offset;
- secth [SECT_DATA].sh_offset = file_offset;
- size = data_section->cur_offset;
- secth [SECT_DATA].sh_size = size;
- size += 8-1;
- size &= ~(8-1);
- file_offset += size;
- virt_offset += size;
- secth [SECT_BSS].sh_addr = virt_offset;
- secth [SECT_BSS].sh_offset = file_offset;
- size = bss_section->cur_offset;
- secth [SECT_BSS].sh_size = size;
-
- /* virtual doesn't matter anymore */
- secth [SECT_SHSTRTAB].sh_offset = file_offset;
- size = sh_str_table.data->len;
- secth [SECT_SHSTRTAB].sh_size = size;
- size += 4-1;
- size &= ~(4-1);
- file_offset += size;
- secth [SECT_SYMTAB].sh_offset = file_offset;
- size = sizeof (ElfSymbol) * num_local_syms;
- secth [SECT_SYMTAB].sh_size = size;
- file_offset += size;
- secth [SECT_STRTAB].sh_offset = file_offset;
- size = str_table.data->len;
- secth [SECT_STRTAB].sh_size = size;
- file_offset += size;
- file_offset += 4-1;
- file_offset &= ~(4-1);
-
- text_section->file_offset = secth [SECT_TEXT].sh_offset;
- data_section->file_offset = secth [SECT_DATA].sh_offset;
- bss_section->file_offset = secth [SECT_BSS].sh_offset;
-
- header.e_ident [0] = 0x7f; header.e_ident [1] = 'E';
- header.e_ident [2] = 'L'; header.e_ident [3] = 'F';
- header.e_ident [4] = SIZEOF_VOID_P == 4? 1: 2;
- header.e_ident [5] = 1; /* FIXME: little endian, bigendian is 2 */
- header.e_ident [6] = 1; /* version */
- header.e_ident [7] = 0; /* FIXME: */
- header.e_ident [8] = 0; /* FIXME: */
- for (i = 9; i < 16; ++i)
- header.e_ident [i] = 0;
-
- header.e_type = 3; /* shared library */
- header.e_machine = 3; /* FIXME: 386 */
- header.e_version = 1; /* FIXME: */
-
- header.e_phoff = sizeof (header);
- header.e_ehsize = sizeof (header);
- header.e_phentsize = sizeof (struct ElfProgHeader);
- header.e_phnum = 3;
- header.e_entry = secth [SECT_TEXT].sh_addr;
- header.e_shstrndx = 10;
- header.e_shentsize = sizeof (struct ElfSectHeader);
- header.e_shnum = SECT_NUM;
- header.e_shoff = file_offset;
-
- /* dynamic data */
- i = 0;
- dynamic [i].d_tag = DYN_HASH;
- dynamic [i].d_val = secth [SECT_HASH].sh_offset;
- ++i;
- dynamic [i].d_tag = DYN_STRTAB;
- dynamic [i].d_val = secth [SECT_DYNSTR].sh_offset;
- ++i;
- dynamic [i].d_tag = DYN_SYMTAB;
- dynamic [i].d_val = secth [SECT_DYNSYM].sh_offset;
- ++i;
- dynamic [i].d_tag = DYN_STRSZ;
- dynamic [i].d_val = dyn_str_table.data->len;
- ++i;
- dynamic [i].d_tag = DYN_SYMENT;
- dynamic [i].d_val = sizeof (ElfSymbol);
- ++i;
- dynamic [i].d_tag = DYN_REL;
- dynamic [i].d_val = secth [SECT_REL_DYN].sh_offset;
- ++i;
- dynamic [i].d_tag = DYN_RELSZ;
- dynamic [i].d_val = secth [SECT_REL_DYN].sh_size;
- ++i;
- dynamic [i].d_tag = DYN_RELENT;
- dynamic [i].d_val = sizeof (ElfReloc);
- ++i;
- dynamic [i].d_tag = DYN_RELCOUNT;
- dynamic [i].d_val = acfg->num_relocs;
- ++i;
-
- /* Program header */
- memset (&progh, 0, sizeof (progh));
- progh [0].p_type = 1; /* 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 = 1;
- 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 = 2; /* 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 = 4;
- progh [2].p_flags = 6;
-
- reloc_symbols (acfg, dynsym, secth, &dyn_str_table, TRUE);
- reloc_symbols (acfg, symtab, secth, &str_table, FALSE);
- relocs = resolve_relocations (acfg);
-
- fwrite (&header, sizeof (header), 1, file);
- fwrite (&progh, sizeof (progh), 1, file);
- fwrite (hash, sizeof (int) * (hash [0] + hash [1] + 2), 1, file);
- fwrite (dynsym, sizeof (ElfSymbol) * hash [1], 1, file);
- fwrite (dyn_str_table.data->str, dyn_str_table.data->len, 1, file);
- /* .rel.dyn */
- fseek (file, secth [SECT_REL_DYN].sh_offset, SEEK_SET);
- fwrite (relocs, sizeof (ElfReloc), acfg->num_relocs, file);
-
- fseek (file, secth [SECT_TEXT].sh_offset, SEEK_SET);
- /* write .text, .data, .bss sections */
- fwrite (text_section->data, text_section->cur_offset, 1, file);
-
- /* .dynamic */
- fwrite (dynamic, sizeof (dynamic), 1, file);
- /* .got.plt */
- size = secth [SECT_DYNAMIC].sh_addr;
- fwrite (&size, sizeof (size), 1, file);
- fseek (file, secth [SECT_DATA].sh_offset, SEEK_SET);
- fwrite (data_section->data, data_section->cur_offset, 1, file);
-
- fseek (file, secth [SECT_SHSTRTAB].sh_offset, SEEK_SET);
- fwrite (sh_str_table.data->str, sh_str_table.data->len, 1, file);
- fseek (file, secth [SECT_SYMTAB].sh_offset, SEEK_SET);
- fwrite (symtab, sizeof (ElfSymbol) * num_local_syms, 1, file);
- fseek (file, secth [SECT_STRTAB].sh_offset, SEEK_SET);
- fwrite (str_table.data->str, str_table.data->len, 1, file);
- /*g_print ("file_offset %d vs %d\n", file_offset, ftell (file));*/
- /*g_assert (file_offset >= ftell (file));*/
- fseek (file, file_offset, SEEK_SET);
- fwrite (§h, sizeof (secth), 1, file);
- fclose (file);
- rename (tmp_outfile_name, outfile_name);
-
- g_free (tmp_outfile_name);
- g_free (outfile_name);
-
- return 0;
-}
-
-#endif /* USE_ELF_WRITER */
-
-#else
-
-static void
-emit_start (MonoAotCompile *acfg)
-{
- if (acfg->aot_opts.asm_only) {
- if (acfg->aot_opts.outfile)
- acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
- else
- acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
- acfg->fp = fopen (acfg->tmpfname, "w+");
- } else {
- int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL);
- acfg->fp = fdopen (i, "w+");
- }
- g_assert (acfg->fp);
-}
-
-static void
-emit_unset_mode (MonoAotCompile *acfg)
-{
- if (acfg->mode == EMIT_NONE)
- return;
- fprintf (acfg->fp, "\n");
- acfg->mode = EMIT_NONE;
-}
-
-static void
-emit_section_change (MonoAotCompile *acfg, const char *section_name, int subsection_index)
-{
- emit_unset_mode (acfg);
-#if defined(PLATFORM_WIN32)
- fprintf (acfg->fp, ".section %s\n", section_name);
-#elif defined(__MACH__)
- if (strcmp(section_name, ".bss") == 0)
- fprintf (acfg->fp, "%s\n", ".data");
- else
- fprintf (acfg->fp, "%s\n", section_name);
-#elif defined(sparc) || defined(__arm__)
- /* For solaris as, GNU as should accept the same */
- fprintf (acfg->fp, ".section \"%s\"\n", section_name);
-#else
- fprintf (acfg->fp, "%s %d\n", section_name, subsection_index);
-#endif
-}
-
-static void
-emit_symbol_type (MonoAotCompile *acfg, const char *name, gboolean func)
-{
- const char *stype;
-
- if (func)
- stype = "function";
- else
- stype = "object";
-
- emit_unset_mode (acfg);
-#if defined(__MACH__)
-
-#elif defined(sparc) || defined(__arm__)
- fprintf (acfg->fp, "\t.type %s,#%s\n", name, stype);
-#elif defined(PLATFORM_WIN32)
-
-#elif defined(__x86_64__) || defined(__i386__)
- fprintf (acfg->fp, "\t.type %s,@%s\n", name, stype);
-#else
- fprintf (acfg->fp, "\t.type %s,@%s\n", name, stype);
-#endif
-}
-
-static void
-emit_global_inner (MonoAotCompile *acfg, const char *name, gboolean func)
-{
- emit_unset_mode (acfg);
-#if (defined(__ppc__) && defined(__MACH__)) || defined(PLATFORM_WIN32)
- // mach-o always uses a '_' prefix.
- fprintf (acfg->fp, "\t.globl _%s\n", name);
-#else
- fprintf (acfg->fp, "\t.globl %s\n", name);
-#endif
-
- emit_symbol_type (acfg, name, func);
-}
-
-static void
-emit_label (MonoAotCompile *acfg, const char *name)
-{
- emit_unset_mode (acfg);
-#if (defined(__ppc__) && defined(__MACH__)) || defined(PLATFORM_WIN32)
- // mach-o always uses a '_' prefix.
- fprintf (acfg->fp, "_%s:\n", name);
-#else
- fprintf (acfg->fp, "%s:\n", name);
-#endif
-
-#if defined(PLATFORM_WIN32)
- /* Emit a normal label too */
- fprintf (acfg->fp, "%s:\n", name);
-#endif
-}
-
-static void
-emit_string (MonoAotCompile *acfg, const char *value)
-{
- emit_unset_mode (acfg);
- fprintf (acfg->fp, "\t%s \"%s\"\n", AS_STRING_DIRECTIVE, value);
-}
-
-static void
-emit_line (MonoAotCompile *acfg)
-{
- emit_unset_mode (acfg);
- fprintf (acfg->fp, "\n");
-}
-
-static void
-emit_string_symbol (MonoAotCompile *acfg, const char *name, const char *value)
-{
- emit_unset_mode (acfg);
- emit_section_change (acfg, ".text", 1);
- emit_global (acfg, name, FALSE);
- emit_label (acfg, name);
- emit_string (acfg, value);
-}
-
-static void
-emit_alignment (MonoAotCompile *acfg, int size)
-{
- emit_unset_mode (acfg);
-#if defined(__arm__)
- fprintf (acfg->fp, "\t.align %d\n", ilog2 (size));
-#elif defined(__ppc__) && defined(__MACH__)
- // the mach-o assembler specifies alignments as powers of 2.
- fprintf (acfg->fp, "\t.align %d\t; ilog2\n", ilog2(size));
-#elif defined(__powerpc__)
- /* ignore on linux/ppc */
-#else
- fprintf (acfg->fp, "\t.align %d\n", size);
-#endif
-}
-
-static void
-emit_pointer (MonoAotCompile *acfg, const char *target)
-{
- emit_unset_mode (acfg);
- emit_alignment (acfg, sizeof (gpointer));
-#if defined(__x86_64__)
- fprintf (acfg->fp, "\t.quad %s\n", target ? target : "0");
-#elif defined(sparc) && SIZEOF_VOID_P == 8
- fprintf (acfg->fp, "\t.xword %s\n", target ? target : "0");
-#else
- fprintf (acfg->fp, "\t.long %s\n", target ? target : "0");
-#endif
-}
-
-static void
-emit_bytes (MonoAotCompile *acfg, const guint8* buf, int size)
-{
- int i;
- if (acfg->mode != EMIT_BYTE) {
- acfg->mode = EMIT_BYTE;
- acfg->col_count = 0;
- }
- for (i = 0; i < size; ++i, ++acfg->col_count) {
- if ((acfg->col_count % 32) == 0)
- fprintf (acfg->fp, "\n\t.byte ");
- else
- fprintf (acfg->fp, ",");
- fprintf (acfg->fp, "0x%x", buf [i]);
- }
-}
-
-static inline void
-emit_int16 (MonoAotCompile *acfg, int value)
-{
- if (acfg->mode != EMIT_WORD) {
- acfg->mode = EMIT_WORD;
- acfg->col_count = 0;
- }
- if ((acfg->col_count++ % 8) == 0)
-#if defined(__MACH__)
- fprintf (acfg->fp, "\n\t.short ");
-#elif defined(__arm__)
- /* FIXME: Use .hword on other archs as well */
- fprintf (acfg->fp, "\n\t.hword ");
-#else
- fprintf (acfg->fp, "\n\t.word ");
-#endif
- else
- fprintf (acfg->fp, ", ");
- fprintf (acfg->fp, "%d", value);
-}
-
-static inline void
-emit_int32 (MonoAotCompile *acfg, int value)
-{
- if (acfg->mode != EMIT_LONG) {
- acfg->mode = EMIT_LONG;
- acfg->col_count = 0;
- }
- if ((acfg->col_count++ % 8) == 0)
- fprintf (acfg->fp, "\n\t.long ");
- else
- fprintf (acfg->fp, ",");
- fprintf (acfg->fp, "%d", value);
-}
-
-static void
-emit_symbol_diff (MonoAotCompile *acfg, const char *end, const char* start, int offset)
-{
- if (acfg->mode != EMIT_LONG) {
- acfg->mode = EMIT_LONG;
- acfg->col_count = 0;
- }
- if ((acfg->col_count++ % 8) == 0)
- fprintf (acfg->fp, "\n\t.long ");
- else
- fprintf (acfg->fp, ",");
- if (offset > 0)
- fprintf (acfg->fp, "%s - %s + %d", end, start, offset);
- else if (offset < 0)
- fprintf (acfg->fp, "%s - %s %d", end, start, offset);
- else
- fprintf (acfg->fp, "%s - %s", end, start);
-}