Skip to content

Commit 1dc74c6

Browse files
authored
Merge pull request #1585 from Shaikh-Ubaid/x64_data_section
WASM_X64: Support Data Segment
2 parents 5a6e2d2 + 1b62e6b commit 1dc74c6

File tree

4 files changed

+80
-49
lines changed

4 files changed

+80
-49
lines changed

src/libasr/codegen/wasm_to_x64.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ class X64Visitor : public WASMDecoder<X64Visitor>,
579579
void visit_F32Sqrt() { visit_F64Sqrt(); }
580580

581581
void gen_x64_bytes() {
582-
emit_elf64_header(m_a, 7U);
582+
emit_elf64_header(m_a);
583583

584584
// declare compile-time strings
585585
std::string base_memory = " "; /* in wasm backend, memory starts after 4 bytes*/
@@ -589,6 +589,9 @@ class X64Visitor : public WASMDecoder<X64Visitor>,
589589
label_to_str["base_memory"] = base_memory;
590590

591591
NO_OF_IMPORTS = imports.size();
592+
593+
m_a.align_by_byte(0x1000);
594+
m_a.add_label("text_segment_start");
592595
for (uint32_t idx = 0; idx < type_indices.size(); idx++) {
593596
m_a.add_label(exports[idx + 1].name);
594597
{
@@ -607,14 +610,18 @@ class X64Visitor : public WASMDecoder<X64Visitor>,
607610

608611
}
609612

610-
for (auto &s : label_to_str) {
611-
emit_data_string(m_a, s.first, s.second);
612-
}
613-
614613
for (auto &d : double_consts) {
615614
emit_double_const(m_a, d.first, d.second);
616615
}
617616

617+
m_a.add_label("text_segment_end");
618+
619+
m_a.align_by_byte(0x1000);
620+
m_a.add_label("data_segment_start");
621+
for (auto &s : label_to_str) {
622+
emit_data_string(m_a, s.first, s.second);
623+
}
624+
618625
for (size_t i = 0; i < globals.size(); i++) {
619626
uint32_t tmp_offset = globals[i].insts_start_idx;
620627
wasm::read_b8(wasm_bytes, tmp_offset); // read byte for i32/i64/f32/f64.const
@@ -644,6 +651,7 @@ class X64Visitor : public WASMDecoder<X64Visitor>,
644651
default: throw CodeGenError("decode_global_section: Unsupport global type"); break;
645652
}
646653
}
654+
m_a.add_label("data_segment_end");
647655

648656
emit_elf64_footer(m_a);
649657
}

src/libasr/codegen/x86_assembler.cpp

+43-17
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ void emit_elf32_header(X86Assembler &a, uint32_t p_flags) {
6262
a.asm_dw_imm16(0); // e_shnum
6363
a.asm_dw_imm16(0); // e_shstrndx
6464

65-
a.add_var("ehdrsize", a.pos()-a.get_defined_symbol("ehdr").value);
6665

6766
/* Elf32_Phdr */
6867
a.add_label("phdr");
@@ -74,13 +73,16 @@ void emit_elf32_header(X86Assembler &a, uint32_t p_flags) {
7473
a.asm_dd_label("filesize"); // p_memsz
7574
a.asm_dd_imm32(p_flags); // p_flags
7675
a.asm_dd_imm32(0x1000); // p_align
76+
a.add_label("phdr_end");
7777

78-
a.add_var("phdrsize", a.pos()-a.get_defined_symbol("phdr").value);
79-
a.add_var("e_phoff", a.get_defined_symbol("phdr").value-a.origin());
78+
a.add_var("ehdrsize", "ehdr", "phdr");
79+
a.add_var("phdrsize", "phdr", "phdr_end");
80+
a.add_var("e_phoff", "ehdr", "phdr");
8081
}
8182

8283
void emit_elf32_footer(X86Assembler &a) {
83-
a.add_var_size("filesize");
84+
a.add_label("footer");
85+
a.add_var("filesize", "ehdr", "footer");
8486
}
8587

8688
void emit_exit(X86Assembler &a, const std::string &name,
@@ -281,8 +283,8 @@ void emit_print_float(X86Assembler &a, const std::string &name) {
281283

282284
/************************* 64-bit functions **************************/
283285

284-
void emit_elf64_header(X86Assembler &a, uint32_t p_flags) {
285-
/* Elf32_Ehdr */
286+
void emit_elf64_header(X86Assembler &a) {
287+
/* Elf64_Ehdr */
286288
a.add_label("ehdr");
287289
// e_ident
288290
a.asm_db_imm8(0x7F);
@@ -313,30 +315,54 @@ void emit_elf64_header(X86Assembler &a, uint32_t p_flags) {
313315
a.asm_dd_imm32(0); // e_flags
314316
a.asm_dw_label("ehdrsize"); // e_ehsize
315317
a.asm_dw_label("phdrsize"); // e_phentsize
316-
a.asm_dw_imm16(1); // e_phnum
318+
a.asm_dw_imm16(3); // e_phnum
317319
a.asm_dw_imm16(0); // e_shentsize
318320
a.asm_dw_imm16(0); // e_shnum
319321
a.asm_dw_imm16(0); // e_shstrndx
320322

321-
a.add_var("ehdrsize", a.pos()-a.get_defined_symbol("ehdr").value);
322-
323-
/* Elf32_Phdr */
323+
/* Elf64_Phdr */
324324
a.add_label("phdr");
325-
a.asm_dd_imm32(1); // p_type
326-
a.asm_dd_imm32(p_flags); // p_flags
325+
a.asm_dd_imm32(1); // p_type
326+
a.asm_dd_imm32(4); // p_flags (permission to read only)
327327
a.asm_dq_imm64(0); // p_offset
328328
a.asm_dq_imm64(a.origin()); // p_vaddr
329329
a.asm_dq_imm64(a.origin()); // p_paddr
330-
a.asm_dq_label("filesize"); // p_filesz
331-
a.asm_dq_label("filesize"); // p_memsz
330+
a.asm_dq_label("phdr_size"); // p_filesz
331+
a.asm_dq_label("phdr_size"); // p_memsz
332332
a.asm_dq_imm64(0x1000); // p_align
333333

334-
a.add_var("phdrsize", a.pos()-a.get_defined_symbol("phdr").value);
335-
a.add_var64("e_phoff", a.get_defined_symbol("phdr").value-a.origin());
334+
/* text_segment_phdr */
335+
a.add_label("text_phdr");
336+
a.asm_dd_imm32(1); // p_type
337+
a.asm_dd_imm32(5); // p_flags (permission to read and execute)
338+
a.asm_dq_label("text_segment_offset"); // p_offset
339+
a.asm_dq_label("text_segment_start"); // p_vaddr
340+
a.asm_dq_label("text_segment_start"); // p_paddr
341+
a.asm_dq_label("text_segment_size"); // p_filesz
342+
a.asm_dq_label("text_segment_size"); // p_memsz
343+
a.asm_dq_imm64(0x1000); // p_align
344+
345+
/* data_segment_phdr */
346+
a.add_label("data_phdr");
347+
a.asm_dd_imm32(1); // p_type
348+
a.asm_dd_imm32(6); // p_flags (permission to read and write)
349+
a.asm_dq_label("data_segment_offset"); // p_offset
350+
a.asm_dq_label("data_segment_start"); // p_vaddr
351+
a.asm_dq_label("data_segment_start"); // p_paddr
352+
a.asm_dq_label("data_segment_size"); // p_filesz
353+
a.asm_dq_label("data_segment_size"); // p_memsz
354+
a.asm_dq_imm64(0x1000); // p_align
336355
}
337356

338357
void emit_elf64_footer(X86Assembler &a) {
339-
a.add_var_size("filesize");
358+
a.add_var("ehdrsize", "ehdr", "phdr");
359+
a.add_var("phdrsize", "phdr", "text_phdr");
360+
a.add_var64("e_phoff", "ehdr", "phdr");
361+
a.add_var64("phdr_size", "ehdr", "text_segment_start");
362+
a.add_var64("text_segment_offset", "ehdr", "text_segment_start");
363+
a.add_var64("text_segment_size", "text_segment_start", "text_segment_end");
364+
a.add_var64("data_segment_offset", "ehdr", "data_segment_start");
365+
a.add_var64("data_segment_size", "data_segment_start", "data_segment_end");
340366
}
341367

342368
void emit_exit_64(X86Assembler &a, std::string name, int exit_code) {

src/libasr/codegen/x86_assembler.h

+18-15
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Old Link: https://www.systutorials.com/go/intel-x86-64-reference-manual/
3030
#include <sstream>
3131
#include <fstream>
3232
#include <map>
33+
#include <cmath>
3334

3435
#include <libasr/alloc.h>
3536
#include <libasr/containers.h>
@@ -40,13 +41,11 @@ Old Link: https://www.systutorials.com/go/intel-x86-64-reference-manual/
4041
#ifdef LFORTRAN_ASM_PRINT
4142
# define EMIT(s) emit(" ", s)
4243
# define EMIT_LABEL(s) emit("", s)
43-
# define EMIT_VAR(a, b) emit("\n", a + " equ " + i2s(b) + "\n")
44-
# define EMIT_VAR_SIZE(a) emit("\n", a + " equ $ - $$\n") // $ is current addr, $$ is start addr
44+
# define EMIT_VAR(a, b, c) emit(" ", a + " equ " + c + " - " + b)
4545
#else
4646
# define EMIT(s)
4747
# define EMIT_LABEL(s)
4848
# define EMIT_VAR(a, b)
49-
# define EMIT_VAR_SIZE(a)
5049
#endif
5150

5251
namespace LCompilers {
@@ -465,6 +464,15 @@ class X86Assembler {
465464
return m_code;
466465
}
467466

467+
void align_by_byte(uint64_t alignment) {
468+
uint64_t code_size = m_code.size() ;
469+
uint64_t padding_size = (alignment * ceil(code_size / (double)alignment)) - code_size;
470+
for (size_t i = 0; i < padding_size; i++) {
471+
m_code.push_back(m_al, 0);
472+
}
473+
EMIT("\n\talign " + std::to_string(alignment) + ", db 0");
474+
}
475+
468476
void define_symbol(const std::string &name, uint32_t value) {
469477
if (m_symbols.find(name) == m_symbols.end()) {
470478
Symbol s;
@@ -548,22 +556,17 @@ class X86Assembler {
548556
EMIT_LABEL(label + ":");
549557
}
550558

551-
void add_var_size(const std::string &var) {
552-
uint64_t val = pos() - origin();
553-
// TODO: Support 64-bit or 8 byte parameter val in define_symbol()
554-
define_symbol(var, val);
555-
EMIT_VAR_SIZE(var);
556-
}
557-
558-
void add_var64(const std::string &var, uint64_t val) {
559+
void add_var64(const std::string &var, const std::string &start, const std::string &end) {
559560
// TODO: Support 64-bit or 8 byte parameter val in define_symbol()
561+
uint64_t val = get_defined_symbol(end).value - get_defined_symbol(start).value;
560562
define_symbol(var, val);
561-
EMIT_VAR(var, val);
563+
EMIT_VAR(var, start, end);
562564
}
563565

564-
void add_var(const std::string &var, uint32_t val) {
566+
void add_var(const std::string &var, const std::string &start, const std::string &end) {
567+
uint32_t val = get_defined_symbol(end).value - get_defined_symbol(start).value;
565568
define_symbol(var, val);
566-
EMIT_VAR(var, val);
569+
EMIT_VAR(var, start, end);
567570
}
568571

569572
uint32_t pos() {
@@ -1539,7 +1542,7 @@ void emit_print_float(X86Assembler &a, const std::string &name);
15391542
// Generate an ELF 64 bit header and footer
15401543
// With these two functions, one only must generate a `_start` assembly
15411544
// function to have a working binary on Linux.
1542-
void emit_elf64_header(X86Assembler &a, uint32_t p_flags=5);
1545+
void emit_elf64_header(X86Assembler &a);
15431546
void emit_elf64_footer(X86Assembler &a);
15441547

15451548
void emit_exit_64(X86Assembler &a, std::string label, int exit_code);

src/lpython/tests/test_asm.cpp

+6-12
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,6 @@ BITS 32
403403
dw 0x0000
404404
dw 0x0000
405405
dw 0x0000
406-
407-
ehdrsize equ 0x00000034
408-
409406
phdr:
410407
dd 0x00000001
411408
dd 0x00000000
@@ -415,12 +412,10 @@ ehdrsize equ 0x00000034
415412
dd filesize
416413
dd 0x00000005
417414
dd 0x00001000
418-
419-
phdrsize equ 0x00000020
420-
421-
422-
e_phoff equ 0x00000034
423-
415+
phdr_end:
416+
ehdrsize equ phdr - ehdr
417+
phdrsize equ phdr_end - phdr
418+
e_phoff equ phdr - ehdr
424419
msg:
425420
db 0x48
426421
db 0x65
@@ -446,9 +441,8 @@ e_phoff equ 0x00000034
446441
mov eax, 0x00000001
447442
mov ebx, 0x00000000
448443
int 0x80
449-
450-
filesize equ $ - $$
451-
444+
footer:
445+
filesize equ footer - ehdr
452446
)""");
453447
CHECK(asm_code == ref);
454448
#endif

0 commit comments

Comments
 (0)