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 const
DefaultOrigin = $0; DefaultOrigin = $0;
ProgramHeaderName = 'main';
constructor TLinkerSinclairQL.Create; constructor TLinkerSinclairQL.Create;
@ -172,21 +173,27 @@ begin
with LinkRes do with LinkRes do
begin 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('');
Add('PHDRS {');
Add(' '+ProgramHeaderName+' PT_LOAD;');
Add('}');
Add('SECTIONS'); Add('SECTIONS');
Add('{'); Add('{');
Add(' . = 0x'+hexstr(Origin,8)+';'); Add(' . = 0x'+hexstr(Origin,8)+';');
Add(' .text : {'); Add(' .text : {');
Add(' _stext = .;'); Add(' _stext = .;');
Add(' *(.text .text.* _CODE _CODE.* ) '); Add(' *(.text .text.* )');
Add(' *(.data .data.* .rodata .rodata.* .fpc.* ) '); Add(' *(.data .data.* .rodata .rodata.* .fpc.* )');
Add(' *(_BSS _BSS.*) *(.bss .bss.*) *(_BSSEND _BSSEND.*) *(_HEAP _HEAP.*) *(.stack .stack.*) *(_STACK _STACK.*) '); Add(' *(.stack .stack.*)');
{ force the end of section to be word aligned }
Add(' . = ALIGN(2); SHORT(0x514C);');
Add(' _etext = .;'); Add(' _etext = .;');
Add(' }'); Add(' } :'+ProgramHeaderName);
Add(' .bss (NOLOAD): {');
Add(' _sbss = .;');
Add(' *(.bss .bss.*)');
Add(' _ebss = .;');
Add(' } :'+ProgramHeaderName);
Add('}'); Add('}');
end; end;
@ -208,8 +215,13 @@ var
FlagsStr : string; FlagsStr : string;
ExeName: string; ExeName: string;
fd,fs: file; fd,fs: file;
fhdr: text;
buf: pointer; buf: pointer;
bufread,bufsize: longint; bufread,bufsize: longint;
HdrName: string;
HeaderLine: string;
HeaderSize: longint;
code: word;
begin begin
StripStr:=''; StripStr:='';
GCSectionsStr:=''; GCSectionsStr:='';
@ -227,6 +239,7 @@ begin
end; end;
ExeName:=current_module.exefilename; ExeName:=current_module.exefilename;
HdrName:=ExeName+'.hdr';
{ Call linker } { Call linker }
SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr); SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr);
@ -242,22 +255,29 @@ begin
MakeSinclairQLExe:=DoExec(BinStr,CmdStr,true,false); MakeSinclairQLExe:=DoExec(BinStr,CmdStr,true,false);
{ Kludge: { Kludge:
With the above linker script, vlink will produce two files, With the above linker script, vlink will produce two files. The main binary
"exename. text" and "exename. text.rel text". The former is the and the relocation info. Here we copy the two together. (KB) }
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) }
if MakeSinclairQLExe then if MakeSinclairQLExe then
begin begin
ExeLength:=0; ExeLength:=0;
bufsize:=16384; bufsize:=16384;
{$push} {$push}
{$i-} {$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); buf:=GetMem(bufsize);
assign(fd,exename); assign(fd,ExeName);
rewrite(fd,1); rewrite(fd,1);
assign(fs,exename+'. text'); assign(fs,ExeName+'.'+ProgramHeaderName);
reset(fs,1); reset(fs,1);
repeat repeat
blockread(fs,buf^,bufsize,bufread); blockread(fs,buf^,bufsize,bufread);
@ -266,7 +286,7 @@ begin
close(fs); close(fs);
// erase(fs); // erase(fs);
assign(fs,exename+'. text.rel text'); assign(fs,ExeName+'.'+ProgramHeaderName+'.rel'+ProgramHeaderName);
reset(fs,1); reset(fs,1);
repeat repeat
blockread(fs,buf^,bufsize,bufread); blockread(fs,buf^,bufsize,bufread);
@ -278,7 +298,10 @@ begin
ExeLength:=FileSize(fd); ExeLength:=FileSize(fd);
close(fd); close(fd);
{$pop} {$pop}
MakeSinclairQLExe:=not (ExeLength = 0); FreeMem(buf);
if HeaderSize > ExeLength then
ExeLength:=HeaderSize;
MakeSinclairQLExe:=(code = 0) and not (ExeLength = 0);
end; end;
end; end;
@ -309,7 +332,7 @@ begin
ExeName:=current_module.exefilename; ExeName:=current_module.exefilename;
BootStr:=DefaultBootString; BootStr:=DefaultBootString;
Replace(BootStr,'$BINSIZE',tostr(ExeLength)); { FIX ME } Replace(BootStr,'$BINSIZE',tostr(ExeLength));
Replace(BootStr,'$EXENAME',ExeName); Replace(BootStr,'$EXENAME',ExeName);
Replace(ExeName,target_info.exeext,''); Replace(ExeName,target_info.exeext,'');