forked from KolibriOS/kolibrios
2f54c7de00
git-svn-id: svn://kolibrios.org@8097 a494cfbc-eb01-0410-851d-a64ba20cac60
206 lines
4.7 KiB
Plaintext
206 lines
4.7 KiB
Plaintext
(*
|
|
BSD 2-Clause License
|
|
|
|
Copyright (c) 2018-2020, Anton Krotov
|
|
All rights reserved.
|
|
*)
|
|
|
|
MODULE KOS;
|
|
|
|
IMPORT BIN, WR := WRITER, LISTS, CHL := CHUNKLISTS;
|
|
|
|
|
|
CONST
|
|
|
|
HEADER_SIZE = 36;
|
|
|
|
SIZE_OF_DWORD = 4;
|
|
|
|
|
|
TYPE
|
|
|
|
HEADER = RECORD
|
|
|
|
menuet01: ARRAY 9 OF CHAR;
|
|
ver, start, size, mem, sp, param, path: INTEGER
|
|
|
|
END;
|
|
|
|
|
|
PROCEDURE Import* (program: BIN.PROGRAM; idata: INTEGER; VAR ImportTable: CHL.INTLIST; VAR len, libcount, size: INTEGER);
|
|
VAR
|
|
i: INTEGER;
|
|
imp: BIN.IMPRT;
|
|
|
|
BEGIN
|
|
libcount := 0;
|
|
imp := program.imp_list.first(BIN.IMPRT);
|
|
WHILE imp # NIL DO
|
|
IF imp.label = 0 THEN
|
|
INC(libcount)
|
|
END;
|
|
imp := imp.next(BIN.IMPRT)
|
|
END;
|
|
|
|
len := libcount * 2 + 2;
|
|
size := (LISTS.count(program.imp_list) + len + 1) * SIZE_OF_DWORD;
|
|
|
|
ImportTable := CHL.CreateIntList();
|
|
FOR i := 0 TO size DIV SIZE_OF_DWORD - 1 DO
|
|
CHL.PushInt(ImportTable, 0)
|
|
END;
|
|
|
|
i := 0;
|
|
imp := program.imp_list.first(BIN.IMPRT);
|
|
WHILE imp # NIL DO
|
|
|
|
IF imp.label = 0 THEN
|
|
CHL.SetInt(ImportTable, len, 0);
|
|
INC(len);
|
|
CHL.SetInt(ImportTable, i, idata + len * SIZE_OF_DWORD);
|
|
INC(i);
|
|
CHL.SetInt(ImportTable, i, imp.nameoffs + size + idata);
|
|
INC(i)
|
|
ELSE
|
|
CHL.SetInt(ImportTable, len, imp.nameoffs + size + idata);
|
|
imp.label := len * SIZE_OF_DWORD;
|
|
INC(len)
|
|
END;
|
|
|
|
imp := imp.next(BIN.IMPRT)
|
|
END;
|
|
CHL.SetInt(ImportTable, len, 0);
|
|
CHL.SetInt(ImportTable, i, 0);
|
|
CHL.SetInt(ImportTable, i + 1, 0);
|
|
INC(len);
|
|
INC(size, CHL.Length(program._import))
|
|
END Import;
|
|
|
|
|
|
PROCEDURE write* (program: BIN.PROGRAM; FileName: ARRAY OF CHAR);
|
|
|
|
CONST
|
|
|
|
PARAM_SIZE = 2048;
|
|
FileAlignment = 16;
|
|
|
|
|
|
VAR
|
|
header: HEADER;
|
|
|
|
base, text, data, idata, bss, offset: INTEGER;
|
|
|
|
reloc: BIN.RELOC;
|
|
iproc: BIN.IMPRT;
|
|
L: INTEGER;
|
|
delta: INTEGER;
|
|
|
|
i: INTEGER;
|
|
|
|
ImportTable: CHL.INTLIST;
|
|
ILen, libcount, isize: INTEGER;
|
|
|
|
icount, dcount, ccount: INTEGER;
|
|
|
|
code: CHL.BYTELIST;
|
|
|
|
BEGIN
|
|
base := 0;
|
|
|
|
icount := CHL.Length(program._import);
|
|
dcount := CHL.Length(program.data);
|
|
ccount := CHL.Length(program.code);
|
|
|
|
text := base + HEADER_SIZE;
|
|
data := WR.align(text + ccount, FileAlignment);
|
|
idata := WR.align(data + dcount, FileAlignment);
|
|
|
|
Import(program, idata, ImportTable, ILen, libcount, isize);
|
|
|
|
bss := WR.align(idata + isize, FileAlignment);
|
|
|
|
header.menuet01 := "MENUET01";
|
|
header.ver := 1;
|
|
header.start := text;
|
|
header.size := idata + isize - base;
|
|
header.mem := WR.align(header.size + program.stack + program.bss + PARAM_SIZE * 2 + 4096, FileAlignment);
|
|
header.sp := base + header.mem - PARAM_SIZE * 2;
|
|
header.param := header.sp;
|
|
header.path := header.param + PARAM_SIZE;
|
|
|
|
code := program.code;
|
|
reloc := program.rel_list.first(BIN.RELOC);
|
|
WHILE reloc # NIL DO
|
|
|
|
offset := reloc.offset;
|
|
L := BIN.get32le(code, offset);
|
|
delta := 3 - offset - text;
|
|
|
|
CASE reloc.opcode OF
|
|
|
|
|BIN.RIMP:
|
|
iproc := BIN.GetIProc(program, L);
|
|
delta := idata + iproc.label
|
|
|
|
|BIN.RBSS:
|
|
delta := L + bss
|
|
|
|
|BIN.RDATA:
|
|
delta := L + data
|
|
|
|
|BIN.RCODE:
|
|
delta := BIN.GetLabel(program, L) + text
|
|
|
|
|BIN.PICDATA:
|
|
INC(delta, L + data)
|
|
|
|
|BIN.PICCODE:
|
|
INC(delta, BIN.GetLabel(program, L) + text)
|
|
|
|
|BIN.PICBSS:
|
|
INC(delta, L + bss)
|
|
|
|
|BIN.PICIMP:
|
|
iproc := BIN.GetIProc(program, L);
|
|
INC(delta, idata + iproc.label)
|
|
|
|
|BIN.IMPTAB:
|
|
INC(delta, idata)
|
|
|
|
END;
|
|
BIN.put32le(code, offset, delta);
|
|
|
|
reloc := reloc.next(BIN.RELOC)
|
|
END;
|
|
|
|
WR.Create(FileName);
|
|
|
|
FOR i := 0 TO 7 DO
|
|
WR.WriteByte(ORD(header.menuet01[i]))
|
|
END;
|
|
|
|
WR.Write32LE(header.ver);
|
|
WR.Write32LE(header.start);
|
|
WR.Write32LE(header.size);
|
|
WR.Write32LE(header.mem);
|
|
WR.Write32LE(header.sp);
|
|
WR.Write32LE(header.param);
|
|
WR.Write32LE(header.path);
|
|
|
|
CHL.WriteToFile(code);
|
|
WR.Padding(FileAlignment);
|
|
|
|
CHL.WriteToFile(program.data);
|
|
WR.Padding(FileAlignment);
|
|
|
|
FOR i := 0 TO ILen - 1 DO
|
|
WR.Write32LE(CHL.GetInt(ImportTable, i))
|
|
END;
|
|
|
|
CHL.WriteToFile(program._import);
|
|
|
|
WR.Close
|
|
END write;
|
|
|
|
|
|
END KOS. |