sinclairql: following Frank Wille's advices, reworked the linker script to omit .bss section from the binary. this reduces a simple 'hello, world' size by ~5K. needs matching startup code.

git-svn-id: trunk@47428 -
This commit is contained in:
Károly Balogh 2020-11-15 22:56:31 +00:00
parent a0543f7f9b
commit 24226ef4af

View File

@ -56,6 +56,7 @@ implementation
const
DefaultOrigin = $0;
ProgramHeaderName = 'main';
constructor TLinkerSinclairQL.Create;
@ -172,21 +173,27 @@ begin
with LinkRes do
begin
{ Note: so of course merging the BSS section into text blows the resulting binary up by a
significant portion. But due to the relocations pointing into BSS, this is the easier way
now, until the linker situation is improved. It remains a relatively quick win for later,
when it comes to size optimizations. (KB) }
Add('');
Add('PHDRS {');
Add(' '+ProgramHeaderName+' PT_LOAD;');
Add('}');
Add('SECTIONS');
Add('{');
Add(' . = 0x'+hexstr(Origin,8)+';');
Add(' .text : {');
Add(' _stext = .;');
Add(' *(.text .text.* _CODE _CODE.* ) ');
Add(' *(.data .data.* .rodata .rodata.* .fpc.* ) ');
Add(' *(_BSS _BSS.*) *(.bss .bss.*) *(_BSSEND _BSSEND.*) *(_HEAP _HEAP.*) *(.stack .stack.*) *(_STACK _STACK.*) ');
Add(' *(.text .text.* )');
Add(' *(.data .data.* .rodata .rodata.* .fpc.* )');
Add(' *(.stack .stack.*)');
{ force the end of section to be word aligned }
Add(' . = ALIGN(2); SHORT(0x514C);');
Add(' _etext = .;');
Add(' }');
Add(' } :'+ProgramHeaderName);
Add(' .bss (NOLOAD): {');
Add(' _sbss = .;');
Add(' *(.bss .bss.*)');
Add(' _ebss = .;');
Add(' } :'+ProgramHeaderName);
Add('}');
end;
@ -208,8 +215,13 @@ var
FlagsStr : string;
ExeName: string;
fd,fs: file;
fhdr: text;
buf: pointer;
bufread,bufsize: longint;
HdrName: string;
HeaderLine: string;
HeaderSize: longint;
code: word;
begin
StripStr:='';
GCSectionsStr:='';
@ -227,6 +239,7 @@ begin
end;
ExeName:=current_module.exefilename;
HdrName:=ExeName+'.hdr';
{ Call linker }
SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr);
@ -242,22 +255,29 @@ begin
MakeSinclairQLExe:=DoExec(BinStr,CmdStr,true,false);
{ Kludge:
With the above linker script, vlink will produce two files,
"exename. text" and "exename. text.rel text". The former is the
binary itself, the second is the relocation info. Here we copy
the two together. I'll try to get vlink to do this for me in the
future. (KB) }
With the above linker script, vlink will produce two files. The main binary
and the relocation info. Here we copy the two together. (KB) }
if MakeSinclairQLExe then
begin
ExeLength:=0;
bufsize:=16384;
{$push}
{$i-}
{ Rename vlink's output file into the header file it is, then parse the
expected length from it. Later we use either this size or the final binary
size in the BASIC loader, depending on which one is bigger. (KB) }
RenameFile(ExeName,HdrName);
assign(fhdr,HdrName);
reset(fhdr);
readln(fhdr,HeaderLine);
Val(Copy(HeaderLine,RPos('0x',HeaderLine),Length(HeaderLine)),HeaderSize,code);
close(fhdr);
buf:=GetMem(bufsize);
assign(fd,exename);
assign(fd,ExeName);
rewrite(fd,1);
assign(fs,exename+'. text');
assign(fs,ExeName+'.'+ProgramHeaderName);
reset(fs,1);
repeat
blockread(fs,buf^,bufsize,bufread);
@ -266,7 +286,7 @@ begin
close(fs);
// erase(fs);
assign(fs,exename+'. text.rel text');
assign(fs,ExeName+'.'+ProgramHeaderName+'.rel'+ProgramHeaderName);
reset(fs,1);
repeat
blockread(fs,buf^,bufsize,bufread);
@ -278,7 +298,10 @@ begin
ExeLength:=FileSize(fd);
close(fd);
{$pop}
MakeSinclairQLExe:=not (ExeLength = 0);
FreeMem(buf);
if HeaderSize > ExeLength then
ExeLength:=HeaderSize;
MakeSinclairQLExe:=(code = 0) and not (ExeLength = 0);
end;
end;
@ -309,7 +332,7 @@ begin
ExeName:=current_module.exefilename;
BootStr:=DefaultBootString;
Replace(BootStr,'$BINSIZE',tostr(ExeLength)); { FIX ME }
Replace(BootStr,'$BINSIZE',tostr(ExeLength));
Replace(BootStr,'$EXENAME',ExeName);
Replace(ExeName,target_info.exeext,'');