Jelajahi Sumber

+ completed the internal debug ELF writer in TMZExeOutput.writeDebugElf (not
enabled yet)

git-svn-id: trunk@39216 -

nickysn 7 tahun lalu
induk
melakukan
daa47f4b7f
2 mengubah file dengan 104 tambahan dan 6 penghapusan
  1. 3 3
      compiler/ogbase.pas
  2. 101 3
      compiler/ogomf.pas

+ 3 - 3
compiler/ogbase.pas

@@ -699,6 +699,9 @@ interface
       end;
       TExeOutputClass=class of TExeOutput;
 
+    const
+      SectionDataMaxGrow = 4096;
+
     var
       exeoutput : TExeOutput;
 
@@ -712,9 +715,6 @@ implementation
       SysUtils,
       globals,verbose,ogmap;
 
-    const
-      SectionDataMaxGrow = 4096;
-
 {$ifdef MEMDEBUG}
     var
       memobjsymbols,

+ 101 - 3
compiler/ogomf.pas

@@ -2589,9 +2589,80 @@ implementation
       end;
 
     function TMZExeOutput.writeDebugElf: boolean;
+      label
+        cleanup;
       var
+        debugsections: array of TMZExeSection;
+        debugsections_count: Word;
+        elfsections_count: Word;
+        elfsechdrs: array of TElf32sechdr;
+        shstrndx: Word;
+        next_section_ofs: LongWord;
         ElfHeader: TElf32header;
+        shstrtabsect_data: TDynamicArray=Nil;
+        I, elfsecidx, J: Integer;
+        ObjSec: TOmfObjSection;
       begin
+        { count the debug sections }
+        debugsections_count:=0;
+        for I:=0 to ExeSectionList.Count-1 do
+          if oso_debug in TMZExeSection(ExeSectionList[I]).SecOptions then
+            Inc(debugsections_count);
+
+        { extract them into the debugsections array }
+        SetLength(debugsections,debugsections_count);
+        debugsections_count:=0;
+        for I:=0 to ExeSectionList.Count-1 do
+          if oso_debug in TMZExeSection(ExeSectionList[I]).SecOptions then
+            begin
+              debugsections[debugsections_count]:=TMZExeSection(ExeSectionList[I]);
+              Inc(debugsections_count);
+            end;
+
+        { prepare/allocate elf section headers }
+        elfsections_count:=debugsections_count+2;
+        SetLength(elfsechdrs,elfsections_count);
+        for I:=0 to elfsections_count-1 do
+          FillChar(elfsechdrs[I],SizeOf(elfsechdrs[I]),0);
+        shstrndx:=elfsections_count-1;
+        shstrtabsect_data:=tdynamicarray.Create(SectionDataMaxGrow);
+        shstrtabsect_data.writestr(#0);
+        next_section_ofs:=SizeOf(ElfHeader)+elfsections_count*SizeOf(TElf32sechdr);
+        for I:=0 to debugsections_count-1 do
+          begin
+            elfsecidx:=I+1;
+            with elfsechdrs[elfsecidx] do
+              begin
+                sh_name:=shstrtabsect_data.Pos;
+                sh_type:=SHT_PROGBITS;
+                sh_flags:=0;
+                sh_addr:=0;
+                sh_offset:=next_section_ofs;
+                sh_size:=debugsections[I].Size;
+                sh_link:=0;
+                sh_info:=0;
+                sh_addralign:=0;
+                sh_entsize:=0;
+              end;
+            Inc(next_section_ofs,debugsections[I].Size);
+            shstrtabsect_data.writestr(debugsections[I].Name+#0);
+          end;
+        with elfsechdrs[shstrndx] do
+          begin
+            sh_name:=shstrtabsect_data.Pos;
+            shstrtabsect_data.writestr('.shstrtab'#0);
+            sh_type:=SHT_STRTAB;
+            sh_flags:=0;
+            sh_addr:=0;
+            sh_offset:=next_section_ofs;
+            sh_size:=shstrtabsect_data.Size;
+            sh_link:=0;
+            sh_info:=0;
+            sh_addralign:=0;
+            sh_entsize:=0;
+          end;
+
+        { write header }
         FillChar(ElfHeader,SizeOf(ElfHeader),0);
         ElfHeader.e_ident[EI_MAG0]:=ELFMAG0; { = #127'ELF' }
         ElfHeader.e_ident[EI_MAG1]:=ELFMAG1;
@@ -2613,12 +2684,39 @@ implementation
         ElfHeader.e_phentsize:=SizeOf(TElf32proghdr);
         ElfHeader.e_phnum:=0;
         ElfHeader.e_shentsize:=SizeOf(TElf32sechdr);
-        ElfHeader.e_shnum:=6;
-        ElfHeader.e_shstrndx:=5;
+        ElfHeader.e_shnum:=elfsections_count;
+        ElfHeader.e_shstrndx:=shstrndx;
+        {todo: MaybeSwapHeader(ElfHeader);}
+        Writer.write(ElfHeader,sizeof(ElfHeader));
 
-        {todo: implement}
+        { write section headers }
+        for I:=0 to elfsections_count-1 do
+          begin
+            {todo: MaybeSwapSecHeader(elfsechdrs[I]);}
+            Writer.write(elfsechdrs[I],SizeOf(elfsechdrs[I]));
+          end;
+
+        { write section data }
+        for J:=0 to debugsections_count-1 do
+          begin
+            debugsections[J].DataPos:=Writer.Size;
+            for i:=0 to debugsections[J].ObjSectionList.Count-1 do
+              begin
+                ObjSec:=TOmfObjSection(debugsections[J].ObjSectionList[i]);
+                if ObjSec.MemPos<Header.LoadableImageSize then
+                  begin
+                    FWriter.WriteZeros(max(0,ObjSec.MemPos-FWriter.Size+debugsections[J].DataPos));
+                    if assigned(ObjSec.Data) then
+                      FWriter.writearray(ObjSec.Data);
+                  end;
+              end;
+          end;
+        { write .shstrtab section data }
+        Writer.writearray(shstrtabsect_data);
 
         Result:=True;
+cleanup:
+        shstrtabsect_data.Free;
       end;
 
     procedure TMZExeOutput.Load_Symbol(const aname: string);