* 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:
yury 2007-09-03 13:35:54 +00:00
parent d539d9c54d
commit fa0f25c986
2 changed files with 62 additions and 150 deletions

View File

@ -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));

View File

@ -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