Subversion Repositories Kolibri OS

Rev

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.