mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 13:59:29 +02:00
* Patch from Sergei Gorelkin (Mantis #9547). Fixed .fpc.resspare section processing in fpcres. Also remove hardcoded section name offsets (and 3 kBytes of code, too :).
git-svn-id: trunk@8367 -
This commit is contained in:
parent
d539d9c54d
commit
fa0f25c986
@ -76,11 +76,12 @@ uses
|
||||
|
||||
const fpcres2elf_version=1;
|
||||
|
||||
type
|
||||
TSectionKind = (skSymtab, skStrtab, skShstrtab, skText, skData, skBss, skFpcRessym, skFpcResstr,
|
||||
skFpcReshash, skFpcResdata, skFpcResspare);
|
||||
|
||||
// Do not change the following consts, they are dummy tables to generate an .o that makes ld happy
|
||||
const shstrtab = #0+'.symtab'+#0+'.strtab'+#0+'.shstrtab'+#0+'.text'+#0+'.data'+#0+
|
||||
'.bss'+#0+'.fpc.ressym'+#0+'.fpc.resstr'+#0+'.fpc.reshash'+#0+
|
||||
'.fpc.resdata'+#0+'.fpc.resspare'+#0+#0;
|
||||
symtab = #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00+
|
||||
const symtab = #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00+
|
||||
#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$01#$00+
|
||||
#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$02#$00+
|
||||
#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$03#$00+
|
||||
@ -91,7 +92,6 @@ const shstrtab = #0+'.symtab'+#0+'.strtab'+#0+'.shstrtab'+#0+'.text'+#0+'.data'+
|
||||
#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$03#$00#$08#$00;
|
||||
strtab = #$00#$00; // this actually is just one byte long
|
||||
zeros = #$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00#$00;
|
||||
fake = 'fakefakefakefakefakefakefakefake';
|
||||
|
||||
// header of a windows 32 bit .res file (16 bytes)
|
||||
reshdr = #$00#$00#$00#$00#$20#$00#$00#$00#$FF#$FF#$00#$00#$FF#$FF#$00#$00+
|
||||
@ -112,6 +112,8 @@ Type
|
||||
FOverwrite: Boolean;
|
||||
FVerbose: Boolean;
|
||||
FVersion: Integer;
|
||||
FShStrTab: string;
|
||||
FShStrOffsets: array[TSectionKind] of Longint;
|
||||
Protected
|
||||
FSectionStream: TMemoryStream;
|
||||
FDataStream: TMemoryStream;
|
||||
@ -146,6 +148,7 @@ Type
|
||||
Protected
|
||||
Procedure AllocateData; override;
|
||||
Procedure FreeData; override;
|
||||
procedure AddSection(aKind: TSectionKind; atype, aflags, aaddr, aoffset, asize, alink, ainfo, aaddralign, aentsize: longint);
|
||||
public
|
||||
procedure LoadBinaryDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
|
||||
procedure LoadTextDFMEntry(const rs:TStream; const DataStream:TMemoryStream; const SymStream:TMemoryStream; var resinfo:TELF32ResourceInfo);
|
||||
@ -198,12 +201,35 @@ end;
|
||||
|
||||
{ TElfResCreator }
|
||||
|
||||
const
|
||||
sectionNames: array[TSectionKind] of PChar = (
|
||||
'.symtab',
|
||||
'.strtab',
|
||||
'.shstrtab',
|
||||
'.text',
|
||||
'.data',
|
||||
'.bss',
|
||||
'.fpc.ressym',
|
||||
'.fpc.resstr',
|
||||
'.fpc.reshash',
|
||||
'.fpc.resdata',
|
||||
'.fpc.resspare'
|
||||
);
|
||||
|
||||
procedure TElfResCreator.AllocateData;
|
||||
var
|
||||
i: TSectionKind;
|
||||
begin
|
||||
FSectionStream:=TMemoryStream.Create;
|
||||
FDataStream:=TMemoryStream.Create;
|
||||
FSymStream:=TMemoryStream.Create;
|
||||
FHashStream:=TMemoryStream.Create;
|
||||
for i := Low(TSectionKind) to High(TSectionKind) do
|
||||
begin
|
||||
FShStrOffsets[i] := Length(FShStrTab) + 1;
|
||||
FShStrTab := FShStrTab + #0 + string(sectionNames[i]);
|
||||
end;
|
||||
FShStrTab := FShStrTab + #0#0;
|
||||
end;
|
||||
|
||||
procedure TElfResCreator.FreeData;
|
||||
@ -412,6 +438,23 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TElf32ResCreator.AddSection(aKind: TSectionKind; atype, aflags, aaddr, aoffset, asize, alink, ainfo, aaddralign, aentsize: longint);
|
||||
var
|
||||
sechdr: TElf32sechdr;
|
||||
begin
|
||||
sechdr.sh_name := FShStrOffsets[aKind];
|
||||
sechdr.sh_type := atype;
|
||||
sechdr.sh_flags := aflags;
|
||||
sechdr.sh_addr := aaddr;
|
||||
sechdr.sh_offset := aoffset;
|
||||
sechdr.sh_size := asize;
|
||||
sechdr.sh_link := alink;
|
||||
sechdr.sh_info := ainfo;
|
||||
sechdr.sh_addralign := aaddralign;
|
||||
sechdr.sh_entsize := aentsize;
|
||||
FSectionStream.Write(sechdr, sizeOf(sechdr));
|
||||
end;
|
||||
|
||||
procedure TElf32ResCreator.DoConvertStreams(Source, Dest: TStream);
|
||||
|
||||
Var
|
||||
@ -494,7 +537,7 @@ begin
|
||||
|
||||
// shstrtab - this is not aligned
|
||||
shstrtab_ofs:=FSectionStream.Position+sizeof(TElf32Header);
|
||||
FSectionStream.Write(shstrtab[1],length(shstrtab));
|
||||
FSectionStream.Write(FShStrtab[1], length(FShStrtab));
|
||||
|
||||
// Write 12 section headers. The headers itself don't need to be aligned,
|
||||
// as their size can be divided by 4. As shstrtab is uneven and not aligned,
|
||||
@ -506,149 +549,17 @@ begin
|
||||
fillchar(SectionHeader,sizeof(SectionHeader),0);
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .text
|
||||
SectionHeader.sh_name:=$1B;
|
||||
SectionHeader.sh_type:=1; // PROGBITS
|
||||
SectionHeader.sh_flags:=6; // AX
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0
|
||||
SectionHeader.sh_size:=0; // yep, pretty empty it is
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .data
|
||||
SectionHeader.sh_name:=$21;
|
||||
SectionHeader.sh_type:=1; // PROGBITS
|
||||
SectionHeader.sh_flags:=3; // WA
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0
|
||||
SectionHeader.sh_size:=0; // yep, pretty empty it is
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .bss
|
||||
SectionHeader.sh_name:=$27;
|
||||
SectionHeader.sh_type:=8; // NOBITS
|
||||
SectionHeader.sh_flags:=3; // WA
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=sizeof(TElf32Header); // after header, dummy as size is 0
|
||||
SectionHeader.sh_size:=0; // yep, pretty empty it is
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .fpc.ressym
|
||||
SectionHeader.sh_name:=$2C;
|
||||
SectionHeader.sh_type:=1; // PROGBITS
|
||||
SectionHeader.sh_flags:=2; // A
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=ressym.ptr; // directly after header
|
||||
SectionHeader.sh_size:=FSymStream.Size;
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=1; // DON'T align this, as this section will be merged by ld
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .fpc.resstr
|
||||
SectionHeader.sh_name:=$38;
|
||||
SectionHeader.sh_type:=1; // PROGBITS
|
||||
SectionHeader.sh_flags:=2; // A
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=resstr.ptr;
|
||||
SectionHeader.sh_size:=0; // currently empty
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .fpc.reshash
|
||||
SectionHeader.sh_name:=$44;
|
||||
SectionHeader.sh_type:=1; // PROGBITS
|
||||
SectionHeader.sh_flags:=2; // A
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=reshash.ptr;
|
||||
SectionHeader.sh_size:=length(ResourceEntries)*sizeof(TELF32ResourceInfo);
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .fpc.resdata
|
||||
SectionHeader.sh_name:=$51;
|
||||
SectionHeader.sh_type:=1; // PROGBITS
|
||||
SectionHeader.sh_flags:=2; // A
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=resdata.ptr;
|
||||
SectionHeader.sh_size:=FDataStream.Size;
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .fpc.resspare
|
||||
// Not used in V1
|
||||
SectionHeader.sh_name:=$5f;
|
||||
SectionHeader.sh_type:=8; // NOBITS
|
||||
SectionHeader.sh_flags:=2; // A
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=resspare.ptr; // fake, as it's empty, should be equal to shstrtab's offset
|
||||
SectionHeader.sh_size:=0; //DataStream.Size; // Leave as much room as we currently have in resdata section
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .shstrtab
|
||||
SectionHeader.sh_name:=$11;
|
||||
SectionHeader.sh_type:=3; // STRTAB
|
||||
SectionHeader.sh_flags:=0;
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=shstrtab_ofs; // $3E
|
||||
SectionHeader.sh_size:=$67;
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=1; // alignment
|
||||
SectionHeader.sh_entsize:=0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .symtab
|
||||
SectionHeader.sh_name:=$01;
|
||||
SectionHeader.sh_type:=2; // SYMTAB
|
||||
SectionHeader.sh_flags:=0;
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=FSectionStream.Position+sizeof(TElf32Header)+sizeOf(SectionHeader)+sizeOf(SectionHeader); // will come directly after this and the next section. $0288;
|
||||
SectionHeader.sh_size:=$90;
|
||||
SectionHeader.sh_link:=$0B;
|
||||
SectionHeader.sh_info:=$09;
|
||||
SectionHeader.sh_addralign:=4; // alignment
|
||||
SectionHeader.sh_entsize:=$10;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
|
||||
// .strtab
|
||||
SectionHeader.sh_name:=$09;
|
||||
SectionHeader.sh_type:=3; // STRTAB
|
||||
SectionHeader.sh_flags:=0;
|
||||
SectionHeader.sh_addr:=0;
|
||||
SectionHeader.sh_offset:=FSectionStream.Position+sizeof(TElf32Header)+sizeOf(SectionHeader)+$90; // will come after this sectionheader and the $90 bytes symtab - $0318; end of file
|
||||
SectionHeader.sh_size:=1;
|
||||
SectionHeader.sh_link:=0;
|
||||
SectionHeader.sh_info:=0;
|
||||
SectionHeader.sh_addralign:=1; // alignment
|
||||
SectionHeader.sh_entsize:=$0;
|
||||
FSectionStream.Write(SectionHeader,sizeOf(SectionHeader));
|
||||
AddSection(skText, SHT_PROGBITS, 6 {AX}, 0, sizeof(TElf32Header), 0, 0, 0, 4, 0);
|
||||
AddSection(skData, SHT_PROGBITS, 3 {WA}, 0, sizeof(TElf32Header), 0, 0, 0, 4, 0);
|
||||
AddSection(skBss, SHT_NOBITS, 3 {WA}, 0, sizeof(TElf32Header), 0, 0, 0, 4, 0);
|
||||
AddSection(skFpcRessym, SHT_PROGBITS, 2 {A}, 0, ressym.ptr, FSymStream.Size, 0, 0, 1, 0);
|
||||
AddSection(skFpcResstr, SHT_PROGBITS, 2 {A}, 0, resstr.ptr, 0, 0, 0, 4, 0);
|
||||
AddSection(skFpcReshash, SHT_PROGBITS, 2 {A}, 0, reshash.ptr, length(ResourceEntries)*sizeof(TELF32ResourceInfo), 0, 0, 4, 0);
|
||||
AddSection(skFpcResdata, SHT_PROGBITS, 2 {A}, 0, resdata.ptr, FDataStream.Size, 0, 0, 4, 0);
|
||||
AddSection(skFpcResspare, SHT_NOBITS, 2 {A}, 0, resspare.ptr, 0, 0, 0, 4, 0);
|
||||
AddSection(skShstrtab, SHT_STRTAB, 0, 0, shstrtab_ofs, length(FShStrtab), 0, 0, 1, 0);
|
||||
AddSection(skSymtab, SHT_SYMTAB, 0, 0, FSectionStream.Position+sizeof(TElf32Header) + 2 * sizeof(SectionHeader), length(symtab), $0B, $09, 4, $10);
|
||||
AddSection(skStrtab, SHT_STRTAB, 0, 0, FSectionStream.Position+sizeof(TElf32Header) + sizeof(SectionHeader) + length(symtab), 1, 0, 0, 1, 0);
|
||||
|
||||
// now write the symbol table
|
||||
FSectionStream.Write(symtab[1],length(symtab));
|
||||
|
@ -197,7 +197,8 @@ begin
|
||||
|
||||
ResPtrsSection:=-1;
|
||||
ResHashSection:=-1;
|
||||
ResourceSectionTable.version:=66;
|
||||
FillChar(ResourceSectionTable, sizeof(ResourceSectionTable), 0);
|
||||
ResourceSectionTable.version:=1;
|
||||
|
||||
// Next cycle through all sections to gather pointers to all the resource
|
||||
// sections, and note the index of the resptrs section
|
||||
|
Loading…
Reference in New Issue
Block a user