* TARGET_ASM_GAS == GNU assembler
*/
#if !defined(TARGET_ASM_APPLE) && !defined(TARGET_ASM_GAS)
-#ifdef __MACH__
+#if defined(TARGET_MACH) && !defined(__native_client_codegen__)
#define TARGET_ASM_APPLE
#else
#define TARGET_ASM_GAS
/*
* Defines for the directives used by different assemblers
*/
-#if defined(TARGET_POWERPC) || defined(__MACH__)
+#if defined(TARGET_POWERPC) || defined(TARGET_MACH)
#define AS_STRING_DIRECTIVE ".asciz"
#else
#define AS_STRING_DIRECTIVE ".string"
#define USE_ELF_RELA 1
#endif
-#if defined(TARGET_X86) && !defined(TARGET_WIN32)
+#if defined(TARGET_X86) && !defined(TARGET_WIN32) && !defined(__APPLE__)
#define USE_ELF_WRITER 1
#endif
-#if defined(TARGET_ARM) && !defined(__MACH__)
+#if defined(TARGET_ARM) && !defined(TARGET_MACH)
#define USE_ELF_WRITER 1
#endif
while (new_size <= new_offset)
new_size *= 2;
data = g_malloc0 (new_size);
+#ifdef __native_client_codegen__
+ /* for Native Client, fill empty space with HLT instruction */
+ /* instead of 00. */
+ memset(data, 0xf4, new_size);
+#endif
memcpy (data, section->data, section->data_len);
g_free (section->data);
section->data = data;
}
}
+#ifdef __native_client_codegen__
+static void
+bin_writer_emit_nacl_call_alignment (MonoImageWriter *acfg) {
+ int offset = acfg->cur_section->cur_offset;
+ int padding = kNaClAlignment - (offset & kNaClAlignmentMask) - kNaClLengthOfCallImm;
+ guint8 padc = '\x90';
+
+ if (padding < 0) padding += kNaClAlignment;
+
+ while (padding > 0) {
+ bin_writer_emit_bytes(acfg, &padc, 1);
+ padding -= 1;
+ }
+}
+#endif /* __native_client_codegen__ */
+
static void
bin_writer_emit_pointer_unaligned (MonoImageWriter *acfg, const char *target)
{
BinReloc *reloc;
- if (!target)
- // FIXME:
- g_assert_not_reached ();
+ 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;
SECT_REL_DYN,
SECT_RELA_DYN,
SECT_TEXT,
+ SECT_RODATA,
SECT_DYNAMIC,
SECT_GOT_PLT,
SECT_DATA,
{".rel.dyn", SHT_REL, sizeof (ElfReloc), 2, SIZEOF_VOID_P},
{".rela.dyn", SHT_RELA, sizeof (ElfRelocA), 2, SIZEOF_VOID_P},
{".text", SHT_PROGBITS, 0, 6, 4096},
+ {".rodata", SHT_PROGBITS, 0, SHF_ALLOC, 4096},
{".dynamic", SHT_DYNAMIC, sizeof (ElfDynamic), 3, SIZEOF_VOID_P},
{".got.plt", SHT_PROGBITS, SIZEOF_VOID_P, 3, SIZEOF_VOID_P},
{".data", SHT_PROGBITS, 0, 3, 8},
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;
{
FILE *file;
ElfHeader header;
- ElfProgHeader progh [3];
+ ElfProgHeader progh [4];
ElfSectHeader secth [SECT_NUM];
#ifdef USE_ELF_RELA
ElfRelocA *relocs;
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;
header.e_phoff = sizeof (header);
header.e_ehsize = sizeof (header);
header.e_phentsize = sizeof (ElfProgHeader);
- header.e_phnum = 3;
+ header.e_phnum = 4;
header.e_entry = secth [SECT_TEXT].sh_addr;
header.e_shstrndx = SECT_SHSTRTAB;
header.e_shentsize = sizeof (ElfSectHeader);
progh [2].p_align = 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 = 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]) {
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);
asm_writer_emit_global (MonoImageWriter *acfg, const char *name, gboolean func)
{
asm_writer_emit_unset_mode (acfg);
-#if (defined(__ppc__) && defined(TARGET_ASM_APPLE)) || (defined(HOST_WIN32) && !defined(MONO_CROSS_COMPILE))
+#if ((defined(__ppc__) || defined(TARGET_X86)) && defined(TARGET_ASM_APPLE)) || (defined(HOST_WIN32) && !defined(MONO_CROSS_COMPILE))
// mach-o always uses a '_' prefix.
fprintf (acfg->fp, "\t.globl _%s\n", name);
#else
asm_writer_emit_label (MonoImageWriter *acfg, const char *name)
{
asm_writer_emit_unset_mode (acfg);
-#if defined(HOST_WIN32) && (defined(TARGET_X86) || defined(TARGET_AMD64))
+#if (defined(TARGET_X86) && defined(TARGET_ASM_APPLE))
+ name = get_label(name);
+ fprintf (acfg->fp, "%s:\n", name);
+ if (name[0] != 'L' && name[0] != '_')
+ fprintf (acfg->fp, "_%s:\n", name);
+
+#elif (defined(HOST_WIN32) && (defined(TARGET_X86) || defined(TARGET_AMD64))) || (defined(TARGET_X86) && defined(TARGET_ASM_APPLE))
fprintf (acfg->fp, "_%s:\n", name);
#if defined(HOST_WIN32)
/* Emit a normal label too */
fprintf (acfg->fp, "\t.align %d\t; ilog2\n", ilog2(size));
#elif defined(TARGET_ASM_GAS)
fprintf (acfg->fp, "\t.balign %d\n", size);
+#elif defined(TARGET_ASM_APPLE)
+ fprintf (acfg->fp, "\t.align %d\n", ilog2 (size));
#else
fprintf (acfg->fp, "\t.align %d\n", size);
#endif
}
+#ifdef __native_client_codegen__
+static void
+asm_writer_emit_nacl_call_alignment (MonoImageWriter *acfg) {
+ int padding = kNaClAlignment - kNaClLengthOfCallImm;
+ guint8 padc = '\x90';
+
+ fprintf (acfg->fp, "\n\t.align %d", kNaClAlignment);
+ while (padding > 0) {
+ fprintf (acfg->fp, "\n\t.byte %d", padc);
+ padding -= 1;
+ }
+}
+#endif /* __native_client_codegen__ */
+
static void
asm_writer_emit_pointer_unaligned (MonoImageWriter *acfg, const char *target)
{
asm_writer_emit_symbol_diff (MonoImageWriter *acfg, const char *end, const char* start, int offset)
{
#ifdef TARGET_ASM_APPLE
- char symbol [128];
+ //char symbol [128];
#endif
if (acfg->mode != EMIT_LONG) {
#else
start = get_label (start);
end = get_label (end);
+
+ if (offset == 0 && strcmp (start, ".") != 0) {
+ char symbol [128];
+ sprintf (symbol, "%sDIFF_SYM%d", AS_TEMP_LABEL_PREFIX, acfg->label_gen);
+ acfg->label_gen ++;
+ fprintf (acfg->fp, "\n%s=%s - %s", symbol, end, start);
+ fprintf (acfg->fp, "\n\t%s ", AS_INT32_DIRECTIVE);
+ fprintf (acfg->fp, "%s", symbol);
+ return;
+ }
+
if ((acfg->col_count++ % 8) == 0)
fprintf (acfg->fp, "\n\t%s ", AS_INT32_DIRECTIVE);
else
#endif
}
+#ifdef __native_client_codegen__
+void
+img_writer_emit_nacl_call_alignment (MonoImageWriter *acfg) {
+#ifdef USE_BIN_WRITER
+ if (acfg->use_bin_writer)
+ bin_writer_emit_nacl_call_alignment (acfg);
+ else
+ asm_writer_emit_nacl_call_alignment (acfg);
+#else
+ g_assert_not_reached();
+#endif
+}
+#endif /* __native_client_codegen__ */
+
void
img_writer_emit_pointer_unaligned (MonoImageWriter *acfg, const char *target)
{