소스 검색

* 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 -
yury 18 년 전
부모
커밋
fa0f25c986
2개의 변경된 파일62개의 추가작업 그리고 150개의 파일을 삭제
  1. 60 149
      utils/fpcres/elfres.pas
  2. 2 1
      utils/fpcres/elfresfix.pas

+ 60 - 149
utils/fpcres/elfres.pas

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

+ 2 - 1
utils/fpcres/elfresfix.pas

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