Skip to content

Commit ad87856

Browse files
PavelKopylakiramenai
authored andcommitted
[EraVM][AsmPrinter] Emit initialization code for global variables.
This includes: 1. Increasing the stack pointer according to the number of global variables. nop stack+=[NumCells + r0] 2. Duplication of intializers in the code section and copying them to corresponding stack items. add @glob_initializer[0], r0, stack[@glob] ... 3. Generation of default landing pads. DEFAULT_UNWIND: ret.panic.to_label @DEFAULT_UNWIND DEFAULT_FAR_RETURN: ret.ok.to_label r1, @DEFAULT_FAR_RETURN DEFAULT_FAR_REVERT: ret.revert.to_label r1, @DEFAULT_FAR_REVERT
1 parent 34a481c commit ad87856

File tree

7 files changed

+407
-15
lines changed

7 files changed

+407
-15
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
ENTRY(0)
2+
SECTIONS {
3+
.code : SUBALIGN(8) {
4+
*(.text)
5+
6+
ASSERT((32 - (31 & .)) % 8 == 0, "padding isn't multiple of 8");
7+
/* Check the code size is no more than 2^16 instructions. */
8+
ASSERT(. <= (1 << 16) * 8, "number of instructions > 2^16");
9+
/* Align the .rodata to 32 bytes. */
10+
. = (. + 31) & ~31;
11+
*(.rodata)
12+
13+
ASSERT(. % 32 == 0, "size isn't multiple of 32");
14+
15+
/* Add padding with metadata */
16+
. = ((((. + 32) >> 5) | 1 ) << 5) - 13;
17+
18+
BYTE(0x3A);
19+
BYTE(0xC2);
20+
BYTE(0x25);
21+
BYTE(0x16);
22+
BYTE(0x8D);
23+
BYTE(0xF5);
24+
BYTE(0x42);
25+
BYTE(0x12);
26+
BYTE(0xA2);
27+
BYTE(0x5C);
28+
BYTE(0x1C);
29+
BYTE(0x01);
30+
BYTE(0xFD);
31+
32+
ASSERT(. % 64 == 32, "size isn't odd number of words");
33+
34+
/* Check the total binary size is no more than (2^16 - 2) words. */
35+
ASSERT(. <= ((1 << 16) - 1) * 32, "Binary size > (2^16 - 2) words")
36+
} = 0
37+
38+
/* .data section itself that contains initializers of global variables,
39+
is not needed. */
40+
/DISCARD/ : {
41+
*(.data)
42+
}
43+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
ENTRY(0)
2+
SECTIONS {
3+
.code : SUBALIGN(8) {
4+
*(.text)
5+
6+
ASSERT((32 - (31 & .)) % 8 == 0, "padding isn't multiple of 8");
7+
8+
/* Align the .rodata to 32 bytes. */
9+
. = (. + 31) & ~31;
10+
*(.rodata)
11+
12+
ASSERT(. % 32 == 0, "size isn't multiple of 32");
13+
14+
/* Add padding such that the size be odd number of words */
15+
. = ((. >> 5) | 1) << 5;
16+
17+
ASSERT(. % 64 == 32, "size isn't odd number of words");
18+
} = 0
19+
20+
/* .data section itself that contains initializers of global variables,
21+
is not needed. */
22+
/DISCARD/ : {
23+
*(.data)
24+
}
25+
}

lld/test/ELF/Inputs/eravm.lds

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* Not a real EraVM memory layout. */
2+
ENTRY(0)
23
MEMORY {
34
code (rx) : ORIGIN = 0, LENGTH = 4K
45
stack (w!x) : ORIGIN = 4K, LENGTH = 4K

lld/test/ELF/eravm-binary-layout.s

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
; REQUIRES: eravm
2+
; RUN: llvm-mc -filetype=obj -arch=eravm %s -o %t.o
3+
; RUN: ld.lld -T %S/Inputs/eravm-binary-layout.lds %t.o -o %t
4+
; RUN: llvm-objdump --no-leading-addr --disassemble-all --disassemble-zeroes --reloc --syms %t | FileCheck --check-prefix=OUTPUT %s
5+
; RUN: ld.lld -T %S/Inputs/eravm-binary-layout-hash.lds %t.o -o %t
6+
; RUN: llvm-objdump --no-leading-addr --disassemble-all --disassemble-zeroes --reloc --syms %t | FileCheck --check-prefix=OUTPUT-HASH %s
7+
8+
.text
9+
nop stack+=[2 + r0]
10+
add @glob_initializer[0], r0, stack[@glob]
11+
12+
.globl get_glob
13+
get_glob:
14+
add 3, r0, r1
15+
add stack[@glob], r1, r1
16+
ret
17+
18+
DEFAULT_UNWIND:
19+
ret.panic.to_label @DEFAULT_UNWIND
20+
DEFAULT_FAR_RETURN:
21+
ret.ok.to_label r1, @DEFAULT_FAR_RETURN
22+
DEFAULT_FAR_REVERT:
23+
ret.revert.to_label r1, @DEFAULT_FAR_REVERT
24+
25+
.data
26+
.globl glob ; @glob
27+
.p2align 5, 0x0
28+
glob:
29+
.cell 113
30+
31+
.globl glob_ptr ; @glob_ptr
32+
.p2align 5, 0x0
33+
glob_ptr:
34+
.cell 0
35+
36+
.rodata
37+
glob_initializer:
38+
.cell 113
39+
40+
; OUTPUT: SYMBOL TABLE:
41+
; OUTPUT-NEXT: 00000040 l .code 00000000 glob_initializer
42+
; OUTPUT-NEXT: 00000028 l .code 00000000 DEFAULT_UNWIND
43+
; OUTPUT-NEXT: 00000030 l .code 00000000 DEFAULT_FAR_RETURN
44+
; OUTPUT-NEXT: 00000038 l .code 00000000 DEFAULT_FAR_REVERT
45+
; OUTPUT-NEXT: 00000010 g .code 00000000 get_glob
46+
; OUTPUT-EMPTY:
47+
; OUTPUT-LABEL: <.code>:
48+
; OUTPUT-NEXT: 00 02 00 00 00 00 00 02 nop stack+=[2 + r0]
49+
; OUTPUT-NEXT: 00 00 00 02 00 00 00 47 add code[2], r0, stack[r0]
50+
; OUTPUT-EMPTY:
51+
; OUTPUT-NEXT: <get_glob>:
52+
; OUTPUT-NEXT: 00 00 00 03 01 00 00 39 add 3, r0, r1
53+
; OUTPUT-NEXT: 00 00 00 00 01 10 00 31 add stack[r0], r1, r1
54+
; OUTPUT-NEXT: 00 00 00 00 00 01 04 2d ret
55+
; OUTPUT-EMPTY:
56+
; OUTPUT-NEXT: <DEFAULT_UNWIND>:
57+
; OUTPUT-NEXT: 00 00 00 05 00 00 04 32 ret.panic.to_label 5
58+
; OUTPUT-EMPTY:
59+
; OUTPUT-NEXT: <DEFAULT_FAR_RETURN>:
60+
; OUTPUT-NEXT: 00 00 00 06 00 01 04 2e ret.ok.to_label r1, 6
61+
; OUTPUT-EMPTY:
62+
; OUTPUT-NEXT: <DEFAULT_FAR_REVERT>:
63+
; OUTPUT-NEXT: 00 00 00 07 00 01 04 30 ret.revert.to_label r1, 7
64+
; OUTPUT-EMPTY:
65+
; OUTPUT-NEXT: <glob_initializer>:
66+
; OUTPUT-NEXT: 00 00 00 00 00 00 00 00
67+
; OUTPUT-NEXT: 00 00 00 00 00 00 00 00
68+
; OUTPUT-NEXT: 00 00 00 00 00 00 00 00
69+
; OUTPUT-NEXT: 00 00 00 00 00 00 00 71
70+
71+
; OUTPUT-HASH: <glob_initializer>:
72+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
73+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
74+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
75+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 71
76+
; Next zeroed bytes are added to make the total .code size
77+
; the even number of words (32 bytes each).
78+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
79+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
80+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
81+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
82+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
83+
; OUTPUT-HASH-NEXT: 00 00 00 00 00 00 00 00
84+
; OUTPUT-HASH-NEXT: 00 00 00 3a c2 25 16 8d
85+
; OUTPUT-HASH-NEXT: f5 42 12 a2 5c 1c 01 fd
86+
; The last 13 bytes are the hash value.

0 commit comments

Comments
 (0)