Rev 7693 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7693 | Rev 7696 | ||
---|---|---|---|
1 | (* |
1 | (* |
2 | BSD 2-Clause License |
2 | BSD 2-Clause License |
3 | 3 | ||
4 | Copyright (c) 2018, 2019, Anton Krotov |
4 | Copyright (c) 2018-2019, Anton Krotov |
5 | All rights reserved. |
5 | All rights reserved. |
6 | *) |
6 | *) |
7 | 7 | ||
8 | MODULE KOS; |
8 | MODULE KOS; |
9 | 9 | ||
10 | IMPORT BIN, WR := WRITER, LISTS, CHL := CHUNKLISTS; |
10 | IMPORT BIN, WR := WRITER, LISTS, CHL := CHUNKLISTS; |
11 | 11 | ||
12 | 12 | ||
13 | CONST |
13 | CONST |
14 | 14 | ||
15 | HEADER_SIZE = 36; |
15 | HEADER_SIZE = 36; |
16 | 16 | ||
17 | SIZE_OF_DWORD = 4; |
17 | SIZE_OF_DWORD = 4; |
18 | 18 | ||
19 | 19 | ||
20 | TYPE |
20 | TYPE |
21 | 21 | ||
22 | FILE = WR.FILE; |
22 | FILE = WR.FILE; |
23 | 23 | ||
24 | HEADER = RECORD |
24 | HEADER = RECORD |
25 | 25 | ||
26 | menuet01: ARRAY 9 OF CHAR; |
26 | menuet01: ARRAY 9 OF CHAR; |
27 | ver, start, size, mem, sp, param, path: INTEGER |
27 | ver, start, size, mem, sp, param, path: INTEGER |
28 | 28 | ||
29 | END; |
29 | END; |
30 | 30 | ||
31 | 31 | ||
32 | PROCEDURE align (n, _align: INTEGER): INTEGER; |
32 | PROCEDURE align (n, _align: INTEGER): INTEGER; |
33 | BEGIN |
33 | BEGIN |
34 | IF n MOD _align # 0 THEN |
34 | IF n MOD _align # 0 THEN |
35 | n := n + _align - (n MOD _align) |
35 | n := n + _align - (n MOD _align) |
36 | END |
36 | END |
37 | 37 | ||
38 | RETURN n |
38 | RETURN n |
39 | END align; |
39 | END align; |
40 | 40 | ||
41 | 41 | ||
42 | PROCEDURE Import* (program: BIN.PROGRAM; idata: INTEGER; VAR ImportTable: CHL.INTLIST; VAR len, libcount, size: INTEGER); |
42 | PROCEDURE Import* (program: BIN.PROGRAM; idata: INTEGER; VAR ImportTable: CHL.INTLIST; VAR len, libcount, size: INTEGER); |
43 | VAR |
43 | VAR |
44 | i: INTEGER; |
44 | i: INTEGER; |
45 | import: BIN.IMPRT; |
45 | import: BIN.IMPRT; |
46 | 46 | ||
47 | BEGIN |
47 | BEGIN |
48 | libcount := 0; |
48 | libcount := 0; |
49 | import := program.imp_list.first(BIN.IMPRT); |
49 | import := program.imp_list.first(BIN.IMPRT); |
50 | WHILE import # NIL DO |
50 | WHILE import # NIL DO |
51 | IF import.label = 0 THEN |
51 | IF import.label = 0 THEN |
52 | INC(libcount) |
52 | INC(libcount) |
53 | END; |
53 | END; |
54 | import := import.next(BIN.IMPRT) |
54 | import := import.next(BIN.IMPRT) |
55 | END; |
55 | END; |
56 | 56 | ||
57 | len := libcount * 2 + 2; |
57 | len := libcount * 2 + 2; |
58 | size := (LISTS.count(program.imp_list) + len + 1) * SIZE_OF_DWORD; |
58 | size := (LISTS.count(program.imp_list) + len + 1) * SIZE_OF_DWORD; |
59 | 59 | ||
60 | ImportTable := CHL.CreateIntList(); |
60 | ImportTable := CHL.CreateIntList(); |
61 | FOR i := 0 TO size DIV SIZE_OF_DWORD - 1 DO |
61 | FOR i := 0 TO size DIV SIZE_OF_DWORD - 1 DO |
62 | CHL.PushInt(ImportTable, 0) |
62 | CHL.PushInt(ImportTable, 0) |
63 | END; |
63 | END; |
64 | 64 | ||
65 | i := 0; |
65 | i := 0; |
66 | import := program.imp_list.first(BIN.IMPRT); |
66 | import := program.imp_list.first(BIN.IMPRT); |
67 | WHILE import # NIL DO |
67 | WHILE import # NIL DO |
68 | 68 | ||
69 | IF import.label = 0 THEN |
69 | IF import.label = 0 THEN |
70 | CHL.SetInt(ImportTable, len, 0); |
70 | CHL.SetInt(ImportTable, len, 0); |
71 | INC(len); |
71 | INC(len); |
72 | CHL.SetInt(ImportTable, i, idata + len * SIZE_OF_DWORD); |
72 | CHL.SetInt(ImportTable, i, idata + len * SIZE_OF_DWORD); |
73 | INC(i); |
73 | INC(i); |
74 | CHL.SetInt(ImportTable, i, import.nameoffs + size + idata); |
74 | CHL.SetInt(ImportTable, i, import.nameoffs + size + idata); |
75 | INC(i) |
75 | INC(i) |
76 | ELSE |
76 | ELSE |
77 | CHL.SetInt(ImportTable, len, import.nameoffs + size + idata); |
77 | CHL.SetInt(ImportTable, len, import.nameoffs + size + idata); |
78 | import.label := len * SIZE_OF_DWORD; |
78 | import.label := len * SIZE_OF_DWORD; |
79 | INC(len) |
79 | INC(len) |
80 | END; |
80 | END; |
81 | 81 | ||
82 | import := import.next(BIN.IMPRT) |
82 | import := import.next(BIN.IMPRT) |
83 | END; |
83 | END; |
84 | CHL.SetInt(ImportTable, len, 0); |
84 | CHL.SetInt(ImportTable, len, 0); |
85 | CHL.SetInt(ImportTable, i, 0); |
85 | CHL.SetInt(ImportTable, i, 0); |
86 | CHL.SetInt(ImportTable, i + 1, 0); |
86 | CHL.SetInt(ImportTable, i + 1, 0); |
87 | INC(len); |
87 | INC(len); |
88 | size := size + CHL.Length(program.import) |
88 | size := size + CHL.Length(program.import) |
89 | END Import; |
89 | END Import; |
90 | 90 | ||
91 | 91 | ||
92 | PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR); |
92 | PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR); |
93 | 93 | ||
94 | CONST |
94 | CONST |
95 | 95 | ||
96 | PARAM_SIZE = 2048; |
96 | PARAM_SIZE = 2048; |
97 | FileAlignment = 16; |
97 | FileAlignment = 16; |
98 | 98 | ||
99 | 99 | ||
100 | VAR |
100 | VAR |
101 | header: HEADER; |
101 | header: HEADER; |
102 | 102 | ||
103 | base, text, data, idata, bss: INTEGER; |
103 | base, text, data, idata, bss: INTEGER; |
104 | 104 | ||
105 | reloc: BIN.RELOC; |
105 | reloc: BIN.RELOC; |
106 | iproc: BIN.IMPRT; |
106 | iproc: BIN.IMPRT; |
107 | L: INTEGER; |
107 | L: INTEGER; |
108 | delta: INTEGER; |
108 | delta: INTEGER; |
109 | 109 | ||
110 | i: INTEGER; |
110 | i: INTEGER; |
111 | 111 | ||
112 | File: FILE; |
112 | File: FILE; |
113 | 113 | ||
114 | ImportTable: CHL.INTLIST; |
114 | ImportTable: CHL.INTLIST; |
115 | ILen, libcount, isize: INTEGER; |
115 | ILen, libcount, isize: INTEGER; |
116 | 116 | ||
117 | icount, dcount, ccount: INTEGER; |
117 | icount, dcount, ccount: INTEGER; |
118 | 118 | ||
119 | 119 | ||
120 | BEGIN |
120 | BEGIN |
121 | base := 0; |
121 | base := 0; |
122 | 122 | ||
123 | icount := CHL.Length(program.import); |
123 | icount := CHL.Length(program.import); |
124 | dcount := CHL.Length(program.data); |
124 | dcount := CHL.Length(program.data); |
125 | ccount := CHL.Length(program.code); |
125 | ccount := CHL.Length(program.code); |
126 | 126 | ||
127 | text := base + HEADER_SIZE; |
127 | text := base + HEADER_SIZE; |
128 | data := align(text + ccount, FileAlignment); |
128 | data := align(text + ccount, FileAlignment); |
129 | idata := align(data + dcount, FileAlignment); |
129 | idata := align(data + dcount, FileAlignment); |
130 | 130 | ||
131 | Import(program, idata, ImportTable, ILen, libcount, isize); |
131 | Import(program, idata, ImportTable, ILen, libcount, isize); |
132 | 132 | ||
133 | bss := align(idata + isize, FileAlignment); |
133 | bss := align(idata + isize, FileAlignment); |
134 | 134 | ||
135 | header.menuet01 := "MENUET01"; |
135 | header.menuet01 := "MENUET01"; |
136 | header.ver := 1; |
136 | header.ver := 1; |
137 | header.start := text; |
137 | header.start := text; |
138 | header.size := idata + isize - base; |
138 | header.size := idata + isize - base; |
139 | header.mem := align(header.size + program.stack + program.bss + PARAM_SIZE * 2 + 4096, FileAlignment); |
139 | header.mem := align(header.size + program.stack + program.bss + PARAM_SIZE * 2 + 4096, FileAlignment); |
140 | header.sp := base + header.mem - PARAM_SIZE * 2; |
140 | header.sp := base + header.mem - PARAM_SIZE * 2; |
141 | header.param := header.sp; |
141 | header.param := header.sp; |
142 | header.path := header.param + PARAM_SIZE; |
142 | header.path := header.param + PARAM_SIZE; |
143 | 143 | ||
144 | 144 | ||
145 | reloc := program.rel_list.first(BIN.RELOC); |
145 | reloc := program.rel_list.first(BIN.RELOC); |
146 | WHILE reloc # NIL DO |
146 | WHILE reloc # NIL DO |
147 | 147 | ||
148 | L := BIN.get32le(program.code, reloc.offset); |
148 | L := BIN.get32le(program.code, reloc.offset); |
149 | delta := 3 - reloc.offset - text; |
149 | delta := 3 - reloc.offset - text; |
150 | 150 | ||
151 | CASE reloc.opcode OF |
151 | CASE reloc.opcode OF |
152 | 152 | ||
153 | |BIN.RIMP: |
153 | |BIN.RIMP: |
154 | iproc := BIN.GetIProc(program, L); |
154 | iproc := BIN.GetIProc(program, L); |
155 | BIN.put32le(program.code, reloc.offset, idata + iproc.label) |
155 | BIN.put32le(program.code, reloc.offset, idata + iproc.label) |
156 | 156 | ||
157 | |BIN.RBSS: |
157 | |BIN.RBSS: |
158 | BIN.put32le(program.code, reloc.offset, L + bss) |
158 | BIN.put32le(program.code, reloc.offset, L + bss) |
159 | 159 | ||
160 | |BIN.RDATA: |
160 | |BIN.RDATA: |
161 | BIN.put32le(program.code, reloc.offset, L + data) |
161 | BIN.put32le(program.code, reloc.offset, L + data) |
162 | 162 | ||
163 | |BIN.RCODE: |
163 | |BIN.RCODE: |
164 | BIN.put32le(program.code, reloc.offset, BIN.GetLabel(program, L) + text) |
164 | BIN.put32le(program.code, reloc.offset, BIN.GetLabel(program, L) + text) |
165 | 165 | ||
166 | |BIN.PICDATA: |
166 | |BIN.PICDATA: |
167 | BIN.put32le(program.code, reloc.offset, L + data + delta) |
167 | BIN.put32le(program.code, reloc.offset, L + data + delta) |
168 | 168 | ||
169 | |BIN.PICCODE: |
169 | |BIN.PICCODE: |
170 | BIN.put32le(program.code, reloc.offset, BIN.GetLabel(program, L) + text + delta) |
170 | BIN.put32le(program.code, reloc.offset, BIN.GetLabel(program, L) + text + delta) |
171 | 171 | ||
172 | |BIN.PICBSS: |
172 | |BIN.PICBSS: |
173 | BIN.put32le(program.code, reloc.offset, L + bss + delta) |
173 | BIN.put32le(program.code, reloc.offset, L + bss + delta) |
174 | 174 | ||
175 | |BIN.PICIMP: |
175 | |BIN.PICIMP: |
176 | iproc := BIN.GetIProc(program, L); |
176 | iproc := BIN.GetIProc(program, L); |
177 | BIN.put32le(program.code, reloc.offset, idata + iproc.label + delta) |
177 | BIN.put32le(program.code, reloc.offset, idata + iproc.label + delta) |
178 | 178 | ||
179 | |BIN.IMPTAB: |
179 | |BIN.IMPTAB: |
180 | BIN.put32le(program.code, reloc.offset, idata + delta) |
180 | BIN.put32le(program.code, reloc.offset, idata + delta) |
181 | 181 | ||
182 | END; |
182 | END; |
183 | 183 | ||
184 | reloc := reloc.next(BIN.RELOC) |
184 | reloc := reloc.next(BIN.RELOC) |
185 | END; |
185 | END; |
186 | 186 | ||
187 | File := WR.Create(FileName); |
187 | File := WR.Create(FileName); |
188 | 188 | ||
189 | FOR i := 0 TO 7 DO |
189 | FOR i := 0 TO 7 DO |
190 | WR.WriteByte(File, ORD(header.menuet01[i])) |
190 | WR.WriteByte(File, ORD(header.menuet01[i])) |
191 | END; |
191 | END; |
192 | 192 | ||
193 | WR.Write32LE(File, header.ver); |
193 | WR.Write32LE(File, header.ver); |
194 | WR.Write32LE(File, header.start); |
194 | WR.Write32LE(File, header.start); |
195 | WR.Write32LE(File, header.size); |
195 | WR.Write32LE(File, header.size); |
196 | WR.Write32LE(File, header.mem); |
196 | WR.Write32LE(File, header.mem); |
197 | WR.Write32LE(File, header.sp); |
197 | WR.Write32LE(File, header.sp); |
198 | WR.Write32LE(File, header.param); |
198 | WR.Write32LE(File, header.param); |
199 | WR.Write32LE(File, header.path); |
199 | WR.Write32LE(File, header.path); |
200 | 200 | ||
201 | CHL.WriteToFile(File, program.code); |
201 | CHL.WriteToFile(File, program.code); |
202 | WR.Padding(File, FileAlignment); |
202 | WR.Padding(File, FileAlignment); |
203 | 203 | ||
204 | CHL.WriteToFile(File, program.data); |
204 | CHL.WriteToFile(File, program.data); |
205 | WR.Padding(File, FileAlignment); |
205 | WR.Padding(File, FileAlignment); |
206 | 206 | ||
207 | FOR i := 0 TO ILen - 1 DO |
207 | FOR i := 0 TO ILen - 1 DO |
208 | WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
208 | WR.Write32LE(File, CHL.GetInt(ImportTable, i)) |
209 | END; |
209 | END; |
210 | 210 | ||
211 | CHL.WriteToFile(File, program.import); |
211 | CHL.WriteToFile(File, program.import); |
212 | 212 | ||
213 | WR.Close(File) |
213 | WR.Close(File) |
214 | 214 | ||
215 | END write; |
215 | END write; |
216 | 216 | ||
217 | 217 | ||
218 | END KOS. |
218 | END KOS. |