1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
#----------------------------------------------------------------------------
# Macros
#----------------------------------------------------------------------------
mask = (1 << alignment) - 1
# Output VALUE as an unaligned pointer-sized quantity.
.macro pbyte value
.if alignment == 2
.4byte \value
.else
.8byte \value
.endif
.endm
# Start a new CIE, and emit everything up to the augmentation data.
# Use LABEL to mark the start of the entry and AUG as the augmentation
# string.
.macro start_cie label,aug
.section .eh_frame,"aw",@progbits
\label:
.word 2f-1f # Length
1:
.word 0 # Identifier
.byte 1 # Version
.string "\aug" # Augmentation
.byte 1 # Code alignment
.byte 4 # Data alignment
.byte 31 # Return address column
.endm
# Create a dummy function of SIZE bytes in SECTION and emit the
# first four entries of an FDE for it.
.macro start_fde cie,section,size
.section \section,"ax",@progbits
3:
.rept \size / 4
nop
.endr
4:
.section .eh_frame,"aw",@progbits
.word 2f-1f # Length
1:
.word .-\cie # CIE offset
pbyte 3b # Initial PC
pbyte 4b-3b # Size of code
.endm
# Finish a CIE or FDE entry.
.macro end_entry
.p2align alignment,fill
2:
.endm
# Start the augmentation data for a CIE that has a 'P' entry
# followed by EXTRA bytes. AUGLEN is the length of augmentation
# string (including zero terminator), ENCODING is the encoding to
# use for the personality routine and VALUE is the value it
# should have.
.macro persaug auglen,extra,encoding,value
.if (\encoding & 0xf0) == 0x50
.byte (-(9 + \auglen + 3 + 2) & mask) + 2 + mask + \extra
.byte \encoding
.fill -(9 + \auglen + 3 + 2) & mask,1,0
.else
.byte 2 + mask + \extra
.byte \encoding
.endif
pbyte \value
.endm
.macro cie_basic label
start_cie \label,""
end_entry
.endm
.macro fde_basic cie,section,size
start_fde \cie,\section,\size
end_entry
.endm
.macro cie_zP label,encoding,value
start_cie \label,"zP"
persaug 3,0,\encoding,\value
end_entry
.endm
.macro fde_zP cie,section,size
start_fde \cie,\section,\size
.byte 0 # Augmentation length
end_entry
.endm
.macro cie_zPR label,encoding,value
start_cie \label,"zPR"
persaug 4,1,\encoding,\value
.byte 0 # FDE enconding
end_entry
.endm
.macro fde_zPR cie,section,size
start_fde \cie,\section,\size
.byte 0 # Augmentation length
end_entry
.endm
#----------------------------------------------------------------------------
# Test code
#----------------------------------------------------------------------------
cie_basic basic1
fde_basic basic1,.text,0x10
fde_basic basic1,.text,0x20
cie_basic basic2
fde_basic basic2,.text,0x30
cie_basic basic3
fde_basic basic3,.text,0x40
cie_basic basic4
fde_basic basic4,.text,0x50
cie_zP zP_unalign1,0x00,foo
fde_zP zP_unalign1,.text,0x10
fde_zP zP_unalign1,.text,0x20
cie_zP zP_align1,0x50,foo
fde_zP zP_align1,.text,0x10
fde_zP zP_align1,.text,0x20
cie_zPR zPR1,0x00,foo
fde_zPR zPR1,.text,0x10
fde_zPR zPR1,.discard,0x20
cie_zPR zPR2,0x00,foo
fde_zPR zPR2,.text,0x30
fde_zPR zPR2,.text,0x40
cie_basic basic5
fde_basic basic5,.text,0x10
.if alignment == 2
.section .gcc_compiled_long32
.endif
|