Ver código fonte

* more things for tcoffobjectinput

peter 24 anos atrás
pai
commit
bba2be8243
5 arquivos alterados com 695 adições e 158 exclusões
  1. 141 98
      compiler/ogbase.pas
  2. 359 35
      compiler/ogcoff.pas
  3. 19 14
      compiler/ogelf.pas
  4. 7 3
      compiler/owar.pas
  5. 169 8
      compiler/owbase.pas

+ 141 - 98
compiler/ogbase.pas

@@ -25,7 +25,6 @@ unit ogbase;
 {$i defines.inc}
 
 interface
-
     uses
 {$ifdef Delphi}
        sysutils,
@@ -69,36 +68,37 @@ interface
        end;
 
        tobjectsection = class
-          name      : string[32];
-          secsymidx : longint; { index for the section in symtab }
-          addralign : longint;
-          { size of the data and in the file }
-          data      : TDynamicArray;
-          datasize  : longint;
-          datapos   : longint;
-          { size and position in memory, set by setsectionsize }
-          memsize,
-          mempos    : longint;
-          { relocation }
-          nrelocs   : longint;
-          relochead : POutputReloc;
-          reloctail : ^POutputReloc;
-          constructor create(const Aname:string;Aalign:longint;alloconly:boolean);
-          destructor  destroy;override;
-          function  write(var d;l:longint):longint;
-          function  writestr(const s:string):longint;
-          procedure writealign(l:longint);
-          function  aligneddatasize:longint;
-          procedure alignsection;
-          procedure alloc(l:longint);
-          procedure addsymreloc(ofs:longint;p:pasmsymbol;relative:relative_type);
-          procedure addsectionreloc(ofs:longint;sec:tsection;relative:relative_type);
+         name      : string[32];
+         secsymidx : longint; { index for the section in symtab }
+         addralign : longint;
+         { size of the data and in the file }
+         data      : TDynamicArray;
+         datasize  : longint;
+         datapos   : longint;
+         { size and position in memory, set by setsectionsize }
+         memsize,
+         mempos    : longint;
+         { relocation }
+         nrelocs   : longint;
+         relochead : POutputReloc;
+         reloctail : ^POutputReloc;
+         constructor create(const Aname:string;Aalign:longint;alloconly:boolean);
+         destructor  destroy;override;
+         function  write(var d;l:longint):longint;
+         function  writestr(const s:string):longint;
+         procedure writealign(l:longint);
+         function  aligneddatasize:longint;
+         procedure alignsection;
+         procedure alloc(l:longint);
+         procedure addsymreloc(ofs:longint;p:pasmsymbol;relative:relative_type);
+         procedure addsectionreloc(ofs:longint;sec:tsection;relative:relative_type);
        end;
 
        tobjectdata = class
          { section }
          currsec   : tsection;
          sects     : array[TSection] of tobjectsection;
+         localsyms : pdictionary;
          constructor create;
          destructor  destroy;override;
          procedure createsection(sec:tsection);virtual;
@@ -112,6 +112,7 @@ interface
          procedure writesymbol(p:pasmsymbol);virtual;abstract;
          procedure writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc:boolean);virtual;abstract;
          procedure writesymstabs(section:tsection;offset:longint;p:pchar;ps:pasmsymbol;nidx,nother,line:longint;reloc:boolean);virtual;abstract;
+         procedure addsymbol(p:pasmsymbol);
        end;
 
        tobjectalloc = class
@@ -129,27 +130,38 @@ interface
 
        tobjectoutput = class
        protected
-         path      : pathstr;
-         ObjFile   : string;
-         { smartlinking }
-         objsmart  : boolean;
-         place     : tcutplace;
-         SmartFilesCount,
-         SmartHeaderCount : longint;
          { writer }
-         writer    : tobjectwriter;
+         FWriter    : tobjectwriter;
          { section }
-         data      : tobjectdata;
-         { Writing }
-         procedure NextSmartName;
-       protected
+         FData      : tobjectdata;
          procedure writetodisk;virtual;
        public
          constructor create(smart:boolean);
          destructor  destroy;override;
-         function  initwriting(Aplace:tcutplace):tobjectdata;virtual;
+         function  initwriting(const fn:string):boolean;virtual;
          procedure donewriting;virtual;
          procedure exportsymbol(p:pasmsymbol);
+         property Data:TObjectData read FData write FData;
+         property Writer:TObjectWriter read FWriter;
+       end;
+
+       tobjectinput = class
+       protected
+         FObjFile   : string;
+         { writer }
+         FReader    : tobjectreader;
+       protected
+         { section }
+         FData      : tobjectdata;
+         function  str2sec(const s:string):tsection;
+       public
+         constructor create(const fn:string);
+         destructor  destroy;override;
+         function  initreading:boolean;virtual;
+         procedure donereading;virtual;
+         procedure readfromdisk;virtual;
+         property Data:TObjectData read FData write FData;
+         property Reader:TObjectReader read FReader;
        end;
 
     var
@@ -160,6 +172,9 @@ interface
       { current object writer used }
       objectoutput : tobjectoutput;
 
+      { globals }
+      globalsyms : pdictionary;
+
 
 implementation
 
@@ -355,6 +370,8 @@ implementation
       begin
         { reset }
         FillChar(Sects,sizeof(Sects),0);
+        localsyms:=new(pdictionary,init);
+        localsyms^.usehash;
       end;
 
 
@@ -366,6 +383,7 @@ implementation
         for sec:=low(tsection) to high(tsection) do
          if assigned(sects[sec]) then
           sects[sec].free;
+        dispose(localsyms,done);
       end;
 
 
@@ -423,67 +441,33 @@ implementation
       end;
 
 
+    procedure tobjectdata.addsymbol(p:pasmsymbol);
+      begin
+        if (p^.bind=AB_LOCAL) then
+         localsyms^.insert(p)
+        else
+         globalsyms^.insert(p);
+      end;
+
+
 {****************************************************************************
                                 tobjectoutput
 ****************************************************************************}
 
     constructor tobjectoutput.create(smart:boolean);
       begin
-        SmartFilesCount:=0;
-        SmartHeaderCount:=0;
-        objsmart:=smart;
-        objfile:=current_module.objfilename^;
-      { Which path will be used ? }
-        if objsmart and
-           (cs_asm_leave in aktglobalswitches) then
-         begin
-           path:=current_module.path^+FixFileName(current_module.modulename^)+target_info.smartext;
-           {$I-}
-            mkdir(path);
-           {$I+}
-           if ioresult<>0 then;
-           path:=FixPath(path,false);
-         end
-        else
-         path:=current_module.path^;
       { init writer }
-        if objsmart and
+        if smart and
            not(cs_asm_leave in aktglobalswitches) then
-          writer:=tarobjectwriter.create(current_module.staticlibfilename^)
+          FWriter:=tarobjectwriter.create(current_module.staticlibfilename^)
         else
-          writer:=tobjectwriter.create;
+          FWriter:=tobjectwriter.create;
       end;
 
 
     destructor tobjectoutput.destroy;
       begin
-        writer.free;
-      end;
-
-
-    procedure tobjectoutput.NextSmartName;
-      var
-        s : string;
-      begin
-        inc(SmartFilesCount);
-        if SmartFilesCount>999999 then
-         Message(asmw_f_too_many_asm_files);
-        if (cs_asm_leave in aktglobalswitches) then
-         s:=current_module.asmprefix^
-        else
-         s:=current_module.modulename^;
-        case place of
-          cut_begin :
-            begin
-              inc(SmartHeaderCount);
-              s:=s+tostr(SmartHeaderCount)+'h';
-            end;
-          cut_normal :
-            s:=s+tostr(SmartHeaderCount)+'s';
-          cut_end :
-            s:=s+tostr(SmartHeaderCount)+'t';
-        end;
-        ObjFile:=FixFileName(s+tostr(SmartFilesCount)+target_info.objext);
+        FWriter.free;
       end;
 
 
@@ -492,16 +476,11 @@ implementation
       end;
 
 
-    function tobjectoutput.initwriting(Aplace:tcutplace):tobjectdata;
+    function tobjectoutput.initwriting(const fn:string):boolean;
       begin
-        place:=Aplace;
         { the data should be set by the real output like coffoutput }
-        data:=nil;
-        initwriting:=nil;
-        { open the writer }
-        if objsmart then
-         NextSmartName;
-        writer.createfile(objfile);
+        FData:=nil;
+        initwriting:=FWriter.createfile(fn);
       end;
 
 
@@ -511,10 +490,10 @@ implementation
         if errorcount=0 then
           writetodisk;
         { close the writer }
-        writer.closefile;
+        FWriter.closefile;
         { free data }
-        data.free;
-        data:=nil;
+        FData.free;
+        FData:=nil;
       end;
 
 
@@ -523,13 +502,77 @@ implementation
         { export globals and common symbols, this is needed
           for .a files }
         if p^.bind in [AB_GLOBAL,AB_COMMON] then
-         writer.writesym(p^.name);
+         FWriter.writesym(p^.name);
       end;
 
+
+{****************************************************************************
+                                tobjectinput
+****************************************************************************}
+
+    constructor tobjectinput.create(const fn:string);
+      begin
+        FObjfile:=fn;
+        FData:=nil;
+      { init reader }
+        FReader:=tobjectreader.create;
+      end;
+
+
+    destructor tobjectinput.destroy;
+      begin
+        FReader.free;
+      end;
+
+
+    function tobjectinput.initreading:boolean;
+      begin
+        { the data should be set by the real output like coffoutput }
+        FData:=nil;
+        { open the reader }
+        initreading:=FReader.openfile(FObjfile);
+      end;
+
+
+    procedure tobjectinput.donereading;
+      begin
+        { close the writer }
+        FReader.closefile;
+        { free data }
+        FData.free;
+        FData:=nil;
+      end;
+
+
+    procedure tobjectinput.readfromdisk;
+      begin
+      end;
+
+
+    function tobjectinput.str2sec(const s:string):tsection;
+      var
+        t : tsection;
+      begin
+        for t:=low(tsection) to high(tsection) do
+         begin
+           if (s=target_asm.secnames[t]) then
+            begin
+              str2sec:=t;
+              exit;
+            end;
+         end;
+        str2sec:=sec_none;
+      end;
+
+
+
 end.
 {
   $Log$
-  Revision 1.5  2000-12-25 00:07:26  peter
+  Revision 1.6  2001-03-05 21:40:38  peter
+    * more things for tcoffobjectinput
+
+  Revision 1.5  2000/12/25 00:07:26  peter
     + new tlinkedlist class (merge of old tstringqueue,tcontainer and
       tlinkedlist objects)
 

+ 359 - 35
compiler/ogcoff.pas

@@ -43,9 +43,10 @@ interface
     type
        tcoffsection = class(tobjectsection)
        public
-          flags    : cardinal;
-          relocpos : longint;
-          constructor createsec(sec:TSection;AAlign,AFlags:cardinal);
+         flags    : cardinal;
+         coffrelocs,
+         coffrelocpos : longint;
+         constructor createsec(sec:TSection;AAlign,AFlags:cardinal);
        end;
 
        tcoffdata = class(tobjectdata)
@@ -63,10 +64,10 @@ interface
          procedure writestabs(section:tsection;offset:longint;p:pchar;nidx,nother,line:longint;reloc:boolean);override;
          procedure writesymstabs(section:tsection;offset:longint;p:pchar;ps:pasmsymbol;nidx,nother,line:longint;reloc:boolean);override;
          strs,
-         syms    : Tdynamicarray;
+         syms  : Tdynamicarray;
        end;
 
-       tcoffoutput = class(tobjectoutput)
+       tcoffobjectoutput = class(tobjectoutput)
        private
          win32   : boolean;
          initsym : longint;
@@ -78,7 +79,25 @@ interface
        public
          constructor createdjgpp(smart:boolean);
          constructor createwin32(smart:boolean);
-         function  initwriting(Aplace:tcutplace):tobjectdata;override;
+         function  initwriting(const fn:string):boolean;override;
+       end;
+
+       tpasmsymbolarray = array[0..high(word)] of pasmsymbol;
+
+       tcoffobjectinput = class(tobjectinput)
+       private
+         Fidx2sec  : array[0..255] of tsection;
+         FCoffsyms : tdynamicarray;
+         FSymTbl   : ^tpasmsymbolarray;
+         win32     : boolean;
+         procedure read_relocs(s:tcoffsection);
+         procedure handle_symbols;
+       public
+         constructor createdjgpp(const fn:string);
+         constructor createwin32(const fn:string);
+         function  initreading:boolean;override;
+         procedure donereading;override;
+         procedure readfromdisk;override;
        end;
 
 
@@ -94,10 +113,19 @@ implementation
        globtype,globals,fmodule;
 
     const
-       symbolresize = 200*18;
+       symbolresize = 200*sizeof(toutputsymbol);
+       coffsymbolresize = 200*18;
        strsresize   = 8192;
        DataResize   = 8192;
 
+    const
+       COFF_SYM_EXTERNAL = 2;
+       COFF_SYM_STATIC   = 3;
+       COFF_SYM_LABEL    = 6;
+       COFF_SYM_FUNCTION = 101;
+       COFF_SYM_FILE     = 103;
+       COFF_SYM_SECTION  = 104;
+
     type
        { Structures which are written directly to the output file }
        coffheader=packed record
@@ -507,36 +535,38 @@ implementation
 
 
 {****************************************************************************
-                                TCoffOutput
+                                tcoffobjectoutput
 ****************************************************************************}
 
-    constructor tcoffoutput.createdjgpp(smart:boolean);
+    constructor tcoffobjectoutput.createdjgpp(smart:boolean);
       begin
         inherited create(smart);
         win32:=false;
       end;
 
 
-    constructor tcoffoutput.createwin32(smart:boolean);
+    constructor tcoffobjectoutput.createwin32(smart:boolean);
       begin
         inherited create(smart);
         win32:=true;
       end;
 
 
-    function tcoffoutput.initwriting(Aplace:tcutplace):tobjectdata;
+    function tcoffobjectoutput.initwriting(const fn:string):boolean;
       begin
-        inherited initwriting(Aplace);
-        initsym:=0;
-        if win32 then
-         data:=tcoffdata.createwin32
-        else
-         data:=tcoffdata.createdjgpp;
-        initwriting:=data;
+        result:=inherited initwriting(fn);
+        if result then
+         begin
+           initsym:=0;
+           if win32 then
+            FData:=tcoffdata.createwin32
+           else
+            FData:=tcoffdata.createdjgpp;
+         end;
       end;
 
 
-    procedure tcoffoutput.write_relocs(s:tobjectsection);
+    procedure tcoffobjectoutput.write_relocs(s:tobjectsection);
       var
         rel  : coffreloc;
         hr,r : poutputreloc;
@@ -568,7 +598,7 @@ implementation
              relative_false : rel.relative:=$6;
              relative_rva   : rel.relative:=$7;
            end;
-           writer.write(rel,sizeof(rel));
+           FWriter.write(rel,sizeof(rel));
            { goto next and dispose this reloc }
            hr:=r;
            r:=r^.next;
@@ -577,7 +607,7 @@ implementation
       end;
 
 
-    procedure tcoffoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
+    procedure tcoffobjectoutput.write_symbol(const name:string;strpos,value,section,typ,aux:longint);
       var
         sym : coffsymbol;
       begin
@@ -590,11 +620,11 @@ implementation
         sym.section:=section;
         sym.typ:=typ;
         sym.aux:=aux;
-        writer.write(sym,sizeof(sym));
+        FWriter.write(sym,sizeof(sym));
       end;
 
 
-    procedure tcoffoutput.write_symbols;
+    procedure tcoffobjectoutput.write_symbols;
       var
         filename  : string[18];
         sec       : tsection;
@@ -610,7 +640,7 @@ implementation
            write_symbol ('.file', -1, 0, -2, $67, 1);
            fillchar(filename,sizeof(filename),0);
            filename:=SplitFileName(current_module.mainsource^);
-           writer.write(filename[1],sizeof(filename)-1);
+           FWriter.write(filename[1],sizeof(filename)-1);
            { The section records, with their auxiliaries, also store the
              symbol index }
            for sec:=low(tsection) to high(tsection) do
@@ -620,7 +650,7 @@ implementation
                fillchar(secrec,sizeof(secrec),0);
                secrec.len:=sects[sec].aligneddatasize;
                secrec.nrelocs:=sects[sec].nrelocs;
-               writer.write(secrec,sizeof(secrec));
+               FWriter.write(secrec,sizeof(secrec));
              end;
            { The real symbols }
            Syms.seek(0);
@@ -641,7 +671,7 @@ implementation
       end;
 
 
-    procedure tcoffoutput.writetodisk;
+    procedure tcoffobjectoutput.writetodisk;
       var
         datapos,
         secsymidx,
@@ -697,7 +727,7 @@ implementation
            for sec:=low(tsection) to high(tsection) do
             if assigned(sects[sec]) then
              begin
-               tcoffsection(sects[sec]).relocpos:=datapos;
+               tcoffsection(sects[sec]).coffrelocpos:=datapos;
                inc(datapos,10*sects[sec].nrelocs);
                if (not gotreloc) and (sects[sec].nrelocs>0) then
                 gotreloc:=true;
@@ -714,7 +744,7 @@ implementation
             header.flag:=$104
            else
             header.flag:=$105;
-           writer.write(header,sizeof(header));
+           FWriter.write(header,sizeof(header));
          { Section headers }
            for sec:=low(tsection) to high(tsection) do
             if assigned(sects[sec]) then
@@ -735,9 +765,9 @@ implementation
                if (sects[sec].datasize>0) and assigned(sects[sec].data) then
                  sechdr.datapos:=sects[sec].datapos;
                sechdr.nrelocs:=sects[sec].nrelocs;
-               sechdr.relocpos:=TCoffSection(sects[sec]).relocpos;
+               sechdr.relocpos:=TCoffSection(sects[sec]).coffrelocpos;
                sechdr.flags:=TCoffSection(sects[sec]).flags;
-               writer.write(sechdr,sizeof(sechdr));
+               FWriter.write(sechdr,sizeof(sechdr));
              end;
          { Sections }
            for sec:=low(tsection) to high(tsection) do
@@ -748,7 +778,7 @@ implementation
                hp:=sects[sec].data.firstblock;
                while assigned(hp) do
                 begin
-                  writer.write(hp^.data,hp^.used);
+                  FWriter.write(hp^.data,hp^.used);
                   hp:=hp^.next;
                 end;
              end;
@@ -760,25 +790,319 @@ implementation
            write_symbols;
          { Strings }
            i:=Strs.size+4;
-           writer.write(i,4);
+           FWriter.write(i,4);
            hp:=Strs.firstblock;
            while assigned(hp) do
             begin
-              writer.write(hp^.data,hp^.used);
+              FWriter.write(hp^.data,hp^.used);
               hp:=hp^.next;
             end;
          end;
       end;
 
 {****************************************************************************
-                                TCoffInput
+                                tcoffobjectinput
 ****************************************************************************}
 
+    constructor tcoffobjectinput.createdjgpp(const fn:string);
+      begin
+        inherited create(fn);
+        win32:=false;
+      end;
+
+
+    constructor tcoffobjectinput.createwin32(const fn:string);
+      begin
+        inherited create(fn);
+        win32:=true;
+      end;
+
+
+    function tcoffobjectinput.initreading:boolean;
+      begin
+        result:=inherited initreading;
+        if result then
+         begin
+           if win32 then
+            FData:=tcoffdata.createwin32
+           else
+            FData:=tcoffdata.createdjgpp;
+           FCoffSyms:=TDynamicArray.Create(symbolresize);
+         end;
+      end;
+
+
+    procedure tcoffobjectinput.donereading;
+      begin
+        FCoffSyms.Free;
+      end;
+
+
+    procedure tcoffobjectinput.read_relocs(s:tcoffsection);
+      var
+        rel  : coffreloc;
+        rel_type : relative_type;
+        i        : longint;
+        p        : pasmsymbol;
+      begin
+        for i:=1 to s.coffrelocs do
+         begin
+           FReader.read(rel,sizeof(rel));
+           case rel.relative of
+             $14 : rel_type:=relative_true;
+             $06 : rel_type:=relative_false;
+             $07 : rel_type:=relative_rva;
+           else
+             begin
+               Comment(V_Error,'Error reading coff file');
+               exit;
+             end;
+           end;
+
+           p:=FSymTbl^[rel.sym];
+           if assigned(p) then
+            begin
+              s.addsymreloc(rel.address,p,rel_type);
+            end
+           else
+            begin
+              Comment(V_Error,'Error reading coff file');
+              exit;
+            end;
+         end;
+      end;
+
+
+    procedure tcoffobjectinput.handle_symbols;
+      var
+        filename  : string[18];
+        sec       : tsection;
+        sectionval,
+        i,nsyms,
+        symidx    : longint;
+        globalval : byte;
+        secrec    : coffsectionrec;
+        sym,
+        sym2      : coffsymbol;
+        strname,
+        strname2  : string;
+        p         : pasmsymbol;
+        auxrec    : array[0..17] of byte;
+      begin
+        with tcoffdata(data) do
+         begin
+           nsyms:=FCoffSyms.Size div sizeof(CoffSymbol);
+           { Allocate memory for symidx -> pasmsymbol table }
+           GetMem(FSymTbl,nsyms*sizeof(pointer));
+           FillChar(FSymTbl^,nsyms*sizeof(pointer),0);
+           { Loop all symbols }
+           FCoffSyms.Seek(0);
+           symidx:=0;
+           while (symidx<nsyms) do
+            begin
+              FCoffSyms.Read(sym,sizeof(sym));
+              if plongint(@sym.name)^<>0 then
+               begin
+                 move(sym.name,strname[1],8);
+                 strname[9]:=#0;
+               end
+              else
+               begin
+                 Strs.Seek(sym.strpos-4);
+                 Strs.Read(strname[1],255);
+                 strname[255]:=#0;
+               end;
+              strname[0]:=chr(strlen(@strname[1]));
+              if strname='' then
+               Internalerror(341324310);
+              case sym.typ of
+                COFF_SYM_EXTERNAL :
+                  begin
+                    if sym.section=0 then
+                     begin
+                       p:=new(pasmsymbol,init(strname,AB_EXTERNAL,AT_FUNCTION));
+                     end
+                    else
+                     begin
+                       p:=new(pasmsymbol,init(strname,AB_GLOBAL,AT_FUNCTION));
+                       sec:=Fidx2sec[sym.section];
+                       if assigned(sects[sec]) then
+                        begin
+                          p^.section:=sec;
+                          if sym.value>=sects[sec].mempos then
+                           p^.address:=sym.value-sects[sec].mempos
+                          else
+                           internalerror(432432432);
+                        end
+                       else
+                        internalerror(34243214);
+                     end;
+                    AddSymbol(p);
+                    FSymTbl^[symidx]:=p
+                  end;
+                COFF_SYM_STATIC :
+                  begin
+                    p:=new(pasmsymbol,init(strname,AB_LOCAL,AT_FUNCTION));
+                    sec:=Fidx2sec[sym.section];
+                    if assigned(sects[sec]) then
+                     begin
+                       p^.section:=sec;
+                       if sym.value>=sects[sec].mempos then
+                        p^.address:=sym.value-sects[sec].mempos
+                       else
+                        begin
+                          if Str2Sec(strname)<>sec then
+                           internalerror(432432432);
+                        end;
+                     end
+                    else
+                     internalerror(34243214);
+                    AddSymbol(p);
+                    FSymTbl^[symidx]:=p;
+                  end;
+                COFF_SYM_SECTION,
+                COFF_SYM_LABEL,
+                COFF_SYM_FUNCTION,
+                COFF_SYM_FILE :
+                  ;
+                else
+                  internalerror(4342343);
+              end;
+              { read aux records }
+              for i:=1 to sym.aux do
+               begin
+                 FCoffSyms.Read(auxrec,sizeof(auxrec));
+                 inc(symidx);
+               end;
+              inc(symidx);
+            end;
+         end;
+      end;
+
+
+    procedure tcoffobjectinput.readfromdisk;
+      var
+        datapos,
+        secsymidx,
+        nsects,
+        strsize,
+        sympos,i : longint;
+        hstab    : coffstab;
+        gotreloc : boolean;
+        sec      : tsection;
+        header   : coffheader;
+        sechdr   : coffsechdr;
+        empty    : array[0..15] of byte;
+        hp       : pdynamicblock;
+      begin
+        with tcoffdata(data) do
+         begin
+           FillChar(Fidx2sec,sizeof(Fidx2sec),0);
+         { COFF header }
+           if not reader.read(header,sizeof(coffheader)) then
+            begin
+              Comment(V_Error,'Error reading coff file');
+              exit;
+            end;
+           if header.mach<>$14c then
+            begin
+              Comment(V_Error,'Not a coff file');
+              exit;
+            end;
+           if header.nsects>255 then
+            begin
+              Comment(V_Error,'To many sections');
+              exit;
+            end;
+{           header.mach:=$14c;
+           header.nsects:=nsects;
+           header.sympos:=sympos;
+           header.syms:=(Syms.size div sizeof(TOutputSymbol))+initsym;
+           if gotreloc then
+            header.flag:=$104
+           else
+            header.flag:=$105 }
+         { Section headers }
+           for i:=1 to header.nsects do
+            begin
+              if not reader.read(sechdr,sizeof(sechdr)) then
+               begin
+                 Comment(V_Error,'Error reading coff file');
+                 exit;
+               end;
+              sec:=str2sec(strpas(sechdr.name));
+              if sec<>sec_none then
+               begin
+                 Fidx2sec[i]:=sec;
+                 createsection(sec);
+                 if not win32 then
+                  sects[sec].mempos:=sechdr.rvaofs;
+                 tcoffsection(sects[sec]).coffrelocs:=sechdr.nrelocs;
+                 tcoffsection(sects[sec]).coffrelocpos:=sechdr.relocpos;
+                 sects[sec].datapos:=sechdr.datapos;
+                 sects[sec].datasize:=sechdr.datasize;
+                 tcoffsection(sects[sec]).flags:=sechdr.flags;
+               end
+              else
+               Comment(V_Warning,'skipping unsupported section '+strpas(sechdr.name));
+            end;
+         { Symbols }
+           Reader.Seek(header.sympos);
+           if not Reader.ReadArray(FCoffSyms,header.syms*sizeof(CoffSymbol)) then
+            begin
+              Comment(V_Error,'Error reading coff file');
+              exit;
+            end;
+         { Strings }
+           if not Reader.Read(strsize,4) then
+            begin
+              Comment(V_Error,'Error reading coff file');
+              exit;
+            end;
+           if strsize<4 then
+            begin
+              Comment(V_Error,'Error reading coff file');
+              exit;
+            end;
+           if not Reader.ReadArray(Strs,Strsize-4) then
+            begin
+              Comment(V_Error,'Error reading coff file');
+              exit;
+            end;
+         { Insert all symbols }
+           handle_symbols;
+         { Sections }
+           for sec:=low(tsection) to high(tsection) do
+            if assigned(sects[sec]) and
+               (sec<>sec_bss) then
+             begin
+               Reader.Seek(sects[sec].datapos);
+               if not Reader.ReadArray(sects[sec].data,sects[sec].datasize) then
+                begin
+                  Comment(V_Error,'Error reading coff file');
+                  exit;
+                end;
+             end;
+         { Relocs }
+           for sec:=low(tsection) to high(tsection) do
+            if assigned(sects[sec]) and
+               (tcoffsection(sects[sec]).coffrelocs>0) then
+             begin
+               Reader.Seek(tcoffsection(sects[sec]).coffrelocpos);
+               read_relocs(tcoffsection(sects[sec]));
+             end;
+         end;
+      end;
+
+
 
 end.
 {
   $Log$
-  Revision 1.8  2000-12-25 00:07:26  peter
+  Revision 1.9  2001-03-05 21:40:38  peter
+    * more things for tcoffobjectinput
+
+  Revision 1.8  2000/12/25 00:07:26  peter
     + new tlinkedlist class (merge of old tstringqueue,tcontainer and
       tlinkedlist objects)
 

+ 19 - 14
compiler/ogelf.pas

@@ -79,7 +79,7 @@ interface
                                  nidx,nother,line:longint;reloc:boolean);override;
        end;
 
-       telf32output = class(tobjectoutput)
+       telf32objectoutput = class(tobjectoutput)
        private
          initsym  : longint;
          procedure createrelocsection(s:telf32section);
@@ -89,7 +89,7 @@ interface
        protected
          procedure writetodisk;override;
        public
-         function  initwriting(Aplace:tcutplace):tobjectdata;override;
+         function  initwriting(const fn:string):boolean;override;
        end;
 
 
@@ -495,19 +495,21 @@ implementation
 
 
 {****************************************************************************
-                            TElf32Output
+                            telf32objectoutput
 ****************************************************************************}
 
-    function telf32output.initwriting(Aplace:tcutplace):tobjectdata;
+    function telf32objectoutput.initwriting(const fn:string):boolean;
       begin
-        inherited initwriting(Aplace);
-        initsym:=0;
-        data:=telf32data.create;
-        initwriting:=data;
+        result:=inherited initwriting(fn);
+        if result then
+         begin
+           initsym:=0;
+           Fdata:=telf32data.create;
+         end;
       end;
 
 
-    procedure telf32output.createrelocsection(s:telf32section);
+    procedure telf32objectoutput.createrelocsection(s:telf32section);
       var
         rel  : telf32reloc;
         hr,r : poutputreloc;
@@ -556,7 +558,7 @@ implementation
       end;
 
 
-    procedure telf32output.createsymtab;
+    procedure telf32objectoutput.createsymtab;
       var
         elfsym : telf32symbol;
         sym : toutputsymbol;
@@ -631,7 +633,7 @@ implementation
       end;
 
 
-    procedure telf32output.createshstrtab;
+    procedure telf32objectoutput.createshstrtab;
       var
         sec : tsection;
       begin
@@ -655,7 +657,7 @@ implementation
       end;
 
 
-    procedure telf32output.writesectionheader(s:telf32section);
+    procedure telf32objectoutput.writesectionheader(s:telf32section);
       var
         sechdr : telf32sechdr;
       begin
@@ -673,7 +675,7 @@ implementation
       end;
 
 
-    procedure telf32output.writetodisk;
+    procedure telf32objectoutput.writetodisk;
       var
         header : telf32header;
         datapos,
@@ -844,7 +846,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.5  2000-12-25 00:07:26  peter
+  Revision 1.6  2001-03-05 21:40:39  peter
+    * more things for tcoffobjectinput
+
+  Revision 1.5  2000/12/25 00:07:26  peter
     + new tlinkedlist class (merge of old tstringqueue,tcontainer and
       tlinkedlist objects)
 

+ 7 - 3
compiler/owar.pas

@@ -44,7 +44,7 @@ type
   tarobjectwriter=class(tobjectwriter)
     constructor create(const Aarfn:string);
     destructor  destroy;override;
-    procedure createfile(const fn:string);override;
+    function  createfile(const fn:string):boolean;override;
     procedure closefile;override;
     procedure writesym(const sym:string);override;
     procedure write(const b;len:longint);override;
@@ -173,11 +173,12 @@ begin
 end;
 
 
-procedure tarobjectwriter.createfile(const fn:string);
+function tarobjectwriter.createfile(const fn:string):boolean;
 begin
   objfn:=fn;
   objpos:=ardata.size;
   ardata.seek(objpos + sizeof(tarhdr));
+  createfile:=true;
 end;
 
 
@@ -280,7 +281,10 @@ end;
 end.
 {
   $Log$
-  Revision 1.7  2000-12-24 12:25:32  peter
+  Revision 1.8  2001-03-05 21:40:39  peter
+    * more things for tcoffobjectinput
+
+  Revision 1.7  2000/12/24 12:25:32  peter
     + cstreams unit
     * dynamicarray object to class
 

+ 169 - 8
compiler/owbase.pas

@@ -26,26 +26,45 @@ unit owbase;
 
 interface
 uses
-  cstreams;
+  cstreams,
+  cclasses;
 
 type
   tobjectwriter=class
+  private
+    f      : TCFileStream;
+    opened : boolean;
+    buf    : pchar;
+    bufidx : longint;
+    size   : longint;
+    procedure writebuf;
+  public
     constructor create;
     destructor  destroy;override;
-    procedure createfile(const fn:string);virtual;
+    function  createfile(const fn:string):boolean;virtual;
     procedure closefile;virtual;
     procedure writesym(const sym:string);virtual;
     procedure write(const b;len:longint);virtual;
+  end;
+
+  tobjectreader=class
   private
     f      : TCFileStream;
     opened : boolean;
     buf    : pchar;
-    bufidx : longint;
-    size   : longint;
-    procedure writebuf;
+    bufidx,
+    bufmax : longint;
+    function readbuf:boolean;
+  public
+    constructor create;
+    destructor  destroy;override;
+    function  openfile(const fn:string):boolean;virtual;
+    procedure closefile;virtual;
+    procedure seek(len:longint);
+    function  read(var b;len:longint):boolean;virtual;
+    function  readarray(a:TDynamicArray;len:longint):boolean;
   end;
 
-
 implementation
 
 uses
@@ -55,6 +74,11 @@ uses
 const
   bufsize = 32768;
 
+
+{****************************************************************************
+                              TObjectWriter
+****************************************************************************}
+
 constructor tobjectwriter.create;
 begin
   getmem(buf,bufsize);
@@ -72,8 +96,9 @@ begin
 end;
 
 
-procedure tobjectwriter.createfile(const fn:string);
+function tobjectwriter.createfile(const fn:string):boolean;
 begin
+  createfile:=false;
   f:=TCFileStream.Create(fn,fmCreate);
   if CStreamError<>0 then
     begin
@@ -83,6 +108,7 @@ begin
   bufidx:=0;
   size:=0;
   opened:=true;
+  createfile:=true;
 end;
 
 
@@ -144,10 +170,145 @@ begin
 end;
 
 
+{****************************************************************************
+                              TObjectReader
+****************************************************************************}
+
+constructor tobjectreader.create;
+begin
+  getmem(buf,bufsize);
+  bufidx:=0;
+  bufmax:=0;
+  opened:=false;
+end;
+
+
+destructor tobjectreader.destroy;
+begin
+  if opened then
+   closefile;
+  freemem(buf,bufsize);
+end;
+
+
+function tobjectreader.openfile(const fn:string):boolean;
+begin
+  openfile:=false;
+  f:=TCFileStream.Create(fn,fmOpenRead);
+  if CStreamError<>0 then
+    begin
+       Message1(exec_e_cant_create_objectfile,fn);
+       exit;
+    end;
+  bufidx:=0;
+  bufmax:=0;
+  opened:=true;
+  openfile:=true;
+end;
+
+
+procedure tobjectreader.closefile;
+begin
+  f.free;
+  opened:=false;
+  bufidx:=0;
+  bufmax:=0;
+end;
+
+
+function tobjectreader.readbuf:boolean;
+begin
+  bufmax:=f.read(buf^,bufsize);
+  bufidx:=0;
+  readbuf:=(bufmax>0);
+end;
+
+
+procedure tobjectreader.seek(len:longint);
+begin
+  f.seek(len,soFromBeginning);
+  bufidx:=0;
+  bufmax:=0;
+end;
+
+
+function tobjectreader.read(var b;len:longint):boolean;
+var
+  p   : pchar;
+  left,
+  idx : longint;
+begin
+  read:=false;
+  if bufmax=0 then
+   if not readbuf then
+    exit;
+  p:=pchar(@b);
+  idx:=0;
+  while len>0 do
+   begin
+     left:=bufmax-bufidx;
+     if len>left then
+      begin
+        move(buf[bufidx],p[idx],left);
+        dec(len,left);
+        inc(idx,left);
+        inc(bufidx,left);
+        if not readbuf then
+         exit;
+      end
+     else
+      begin
+        move(buf[bufidx],p[idx],len);
+        inc(bufidx,len);
+        inc(idx,len);
+        break;
+      end;
+   end;
+  read:=(idx=len);
+end;
+
+
+function tobjectreader.readarray(a:TDynamicArray;len:longint):boolean;
+var
+  left,
+  idx : longint;
+begin
+  readarray:=false;
+  if bufmax=0 then
+   if not readbuf then
+    exit;
+  idx:=0;
+  while len>0 do
+   begin
+     left:=bufmax-bufidx;
+     if len>left then
+      begin
+        a.Write(buf[bufidx],left);
+        dec(len,left);
+        inc(idx,left);
+        inc(bufidx,left);
+        if not readbuf then
+         exit;
+      end
+     else
+      begin
+        a.Write(buf[bufidx],len);
+        inc(bufidx,len);
+        inc(idx,len);
+        break;
+      end;
+   end;
+  readarray:=(idx=len);
+end;
+
+
 end.
 {
   $Log$
-  Revision 1.6  2000-12-24 12:25:32  peter
+  Revision 1.7  2001-03-05 21:40:39  peter
+    * more things for tcoffobjectinput
+
+  Revision 1.6  2000/12/24 12:25:32  peter
     + cstreams unit
     * dynamicarray object to class