Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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