Browse Source

added a segment table containing segments for symbols defined by linker script (needed for relocs)

git-svn-id: trunk@17268 -
armin 14 years ago
parent
commit
672d76e636
2 changed files with 100 additions and 24 deletions
  1. 39 7
      compiler/ognlm.pas
  2. 61 17
      compiler/systems/t_nwm.pas

+ 39 - 7
compiler/ognlm.pas

@@ -289,7 +289,12 @@ const NLM_MAX_DESCRIPTION_LENGTH = 127;
          procedure ParseScript (linkscript:TCmdStrList); override;
        end;
 
-
+    var
+      {for symbols defined in linker script. To generate a fixup we
+       need to know the segment (.text,.bss or .code) of the symbol
+       Pointer in list is used as TsecType
+       Filled by TInternalLinkerNetware.DefaultLinkScript }
+      nlmSpecialSymbols_Segments : TFPHashList;
 
     type
 
@@ -346,10 +351,19 @@ type
 
 function SectionType (aName : string) : TSecType;
 var s : string;
+    seg: ptruint;
 begin
   s := copy(aName,1,5);
   if s = '.text' then result := Section_text else
     if (s = '.data') or (copy(s,1,4)='.bss') then result := Section_data else
+      if s[1] <> '.' then
+        begin
+          seg := ptruint(nlmSpecialSymbols_Segments.Find(aName));
+          if seg <> 0 then
+            result := TSecType(seg)
+          else
+            result := Section_other;
+        end else
       result := Section_other;
 end;
 
@@ -514,7 +528,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
     procedure TNLMexeoutput.ExeSectionList_write_Data(p:TObject;arg:pointer);
       var
         objsec : TObjSection;
-        i      : longint;
+        i,j    : longint;
+        b      : byte;
       begin
 
         with texesection(p) do
@@ -535,7 +550,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
                     if oso_data in objsec.secoptions then
                       begin
                         if assigned(exemap) then
-                          exemap.Add(' nlm file offset $'+hexstr(objsec.DataPos,8)+': '+objsec.name);
+                          if objsec.data.size > 0 then
+                            exemap.Add('  0x'+hexstr(objsec.DataPos,8)+': '+objsec.name);
                         //writeln ('   ',objsec.name,'  size:',objsec.size,'  relocs:',objsec.ObjRelocations.count,'  DataPos:',objsec.DataPos,' MemPos:',objsec.MemPos);
                         {for j := 0 to objsec.ObjRelocations.count-1 do
                           begin
@@ -550,7 +566,14 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
                           end;}
                         if not assigned(objsec.data) then
                           internalerror(200603042);
-                        FWriter.writezeros(objsec.dataalignbytes);
+                        if copy (objsec.Name,1,5) = '.text' then
+                          begin        // write NOP's instead of zero's for .text, makes disassemble possible
+                            b := $90;  // NOP
+                            if objsec.DataAlignBytes > 0 then
+                              for j := 1 to objsec.DataAlignBytes do
+                                FWriter.write(b,1);
+                          end else
+                            FWriter.writezeros(objsec.dataalignbytes);
                         //if objsec.dataalignbytes>0 then
                         //  writeln ('  ',name,'  alignbytes: ',objsec.dataalignbytes);
                         if objsec.DataPos<>FWriter.Size then
@@ -874,6 +897,11 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
         if FWriter.Size<>totalheadersize+ExeSecsListSize+headerAlignBytes then
           internalerror(201103062);
         { Section data }
+        if assigned(exemap) then
+          begin
+            exemap.Add('');
+            exemap.Add('NLM file offsets:');
+          end;
         ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
 
         if hassymbols then
@@ -1046,7 +1074,8 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
 
                       k := objsec.MemPos + objreloc.DataOffset;
                       k := k or $40000000;
-                      // TODO: data|code
+                      // TODO: data|code if we support importing data symbols
+                      //       i do not know if this is possible with netware
                       internalobjdata.writebytes(k,sizeof(k));    // address
 
                       // the netware loader requires an offset at the import address
@@ -1169,8 +1198,11 @@ function SecOpts(SecOptions:TObjSectionOptions):string;
                     targetSectionName := '';
                     if objreloc.symbol <> nil then
                     begin
-                      //writeln ('  MemPos',objsec.MemPos,' dataOfs:',objreloc.dataoffset,' ',objsec.name,'   objreloc.symbol: ',objreloc.symbol.name,'  objreloc.symbol.objsection.name: ',objreloc.symbol.objsection.name,' ',objreloc.symbol.Typ,' ',objreloc.symbol.bind,' ',objreloc.Typ);
-                      targetSectionName := copy(objreloc.symbol.objsection.name,1,5);
+                      // writeln ('  MemPos',objsec.MemPos,' dataOfs:',objreloc.dataoffset,' ',objsec.name,'   objreloc.symbol: ',objreloc.symbol.name,'  objreloc.symbol.objsection.name: ',objreloc.symbol.objsection.name,' ',objreloc.symbol.Typ,' ',objreloc.symbol.bind,' ',objreloc.Typ);
+                      if objreloc.symbol.objsection.name[1] <> '.' then
+                        targetSectionName := objreloc.symbol.name                       // specials like __bss_start__
+                      else                                                              // dont use objsection.name because it begins with *
+                        targetSectionName := copy(objreloc.symbol.objsection.name,1,5); // all others begin with .segment, we only have to check for .text, .data or .bss
                     end else
                       internalerror(2011030603);
 

+ 61 - 17
compiler/systems/t_nwm.pas

@@ -97,7 +97,7 @@ implementation
     verbose,systems,globtype,globals,
     symconst,script,
     fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,
-    import,export,link,i_nwm,ogbase, ogcoff, ognlm
+    import,export,link,i_nwm,ogbase, ogcoff, ognlm, cclasses
     {$ifdef netware} ,dos {$endif}
     ;
 
@@ -126,6 +126,7 @@ implementation
     TInternalLinkerNetware = class(TInternalLinker)
         prelude : string;
         constructor create;override;
+        destructor destroy;override;
         procedure DefaultLinkScript;override;
         procedure InitSysInitUnitName;override;
         procedure ConcatEntryName; virtual;
@@ -339,10 +340,26 @@ begin
 
   { add objectfiles, start with nwpre always }
   LinkRes.Add ('INPUT(');
-  s2 := FindObjectFile('nwpre','',false);
+  if target_info.system = system_i386_netwlibc then
+   begin
+     s2 := FindObjectFile('nwplibc','',false);
+     if s2 = '' then
+       s2 := FindObjectFile('libcpre.gcc','',false);
+   end else
+     s2 := FindObjectFile('nwpre','',false);
   Comment (V_Debug,'adding Object File '+s2);
   {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
 
+  if target_info.system = system_i386_netwlibc then
+   begin
+     if isDll then  {needed to provide main}
+       s2 := FindObjectFile('nwl_dlle','',false)
+     else
+       s2 := FindObjectFile('nwl_main','',false);
+     Comment (V_Debug,'adding Object File '+s2);
+     {$ifndef netware} LinkRes.Add (s2); {$else} LinkRes.Add (FExpand(s2)); {$endif}
+    end;
+
   { main objectfiles, add to linker input }
   while not ObjectFiles.Empty do
   begin
@@ -364,9 +381,20 @@ begin
   {$endif}
 
   { start and stop-procedures }
-  NLMConvLinkFile.Add ('START _Prelude');  { defined in rtl/netware/nwpre.as }
-  NLMConvLinkFile.Add ('EXIT _Stop');                             { nwpre.as }
-  NLMConvLinkFile.Add ('CHECK FPC_NW_CHECKFUNCTION');            { system.pp }
+
+  if target_info.system = system_i386_netwlibc then
+    begin
+      NLMConvLinkFile.Add ('START _LibCPrelude');
+      NLMConvLinkFile.Add ('EXIT _LibCPostlude');
+      NLMConvLinkFile.Add ('CHECK _LibCCheckUnload');
+      NLMConvLinkFile.Add ('REENTRANT');            { needed by older libc versions }
+    end else
+    begin
+      NLMConvLinkFile.Add ('START _Prelude');  { defined in rtl/netware/nwpre.as }
+      NLMConvLinkFile.Add ('EXIT _Stop');                             { nwpre.as }
+      NLMConvLinkFile.Add ('CHECK FPC_NW_CHECKFUNCTION');            { system.pp }
+    end;
+
 
   if not (cs_link_strip in current_settings.globalswitches) then
   begin
@@ -567,8 +595,18 @@ end;
         inherited Create;
         CExeoutput:=TNLMexeoutput;
         CObjInput:=TNLMCoffObjInput;
+        nlmSpecialSymbols_Segments := TFPHashList.create;
       end;
 
+    destructor TInternalLinkerNetware.destroy;
+      begin
+        if assigned(nlmSpecialSymbols_Segments) then
+          begin
+            nlmSpecialSymbols_Segments.Free;
+            nlmSpecialSymbols_Segments := nil;
+          end;
+        inherited destroy;
+      end;
 
     procedure TInternalLinkerNetware.DefaultLinkScript;
       var
@@ -704,7 +742,10 @@ end;
             end;
             option := GetToken(s,';');
           end;
-          result := 'nwpre';
+          if target_info.system = system_i386_netwlibc then
+            result := 'libcpre'
+          else
+            result := 'nwpre';
         end;
 
       begin
@@ -750,32 +791,33 @@ end;
             Concat('IMAGEBASE $' + hexStr(0, SizeOf(imagebase)*2));
             Concat('HEADER');
             Concat('EXESECTION .text');
-            Concat('  SYMBOL __text_start__');
+            Concat('  SYMBOL __text_start__');  nlmSpecialSymbols_Segments.Add('__text_start__',pointer(ptruint(Section_text)));
             Concat('  OBJSECTION .text*');
-            Concat('  SYMBOL ___CTOR_LIST__');
-            Concat('  SYMBOL __CTOR_LIST__');
+            Concat('  SYMBOL ___CTOR_LIST__');  nlmSpecialSymbols_Segments.Add('___CTOR_LIST__',pointer(ptruint(Section_text)));
+            Concat('  SYMBOL __CTOR_LIST__');   nlmSpecialSymbols_Segments.Add('__CTOR_LIST__',pointer(ptruint(Section_text)));
             Concat('  LONG -1');
             Concat('  OBJSECTION .ctor*');
             Concat('  LONG 0');
-            Concat('  SYMBOL ___DTOR_LIST__');
-            Concat('  SYMBOL __DTOR_LIST__');
+            Concat('  SYMBOL ___DTOR_LIST__');  nlmSpecialSymbols_Segments.Add('___DTOR_LIST__',pointer(ptruint(Section_text)));
+            Concat('  SYMBOL __DTOR_LIST__');   nlmSpecialSymbols_Segments.Add('__DTOR_LIST__',pointer(ptruint(Section_text)));
             Concat('  LONG -1');
             Concat('  OBJSECTION .dtor*');
             Concat('  LONG 0');
-            Concat('  SYMBOL etext');
+            Concat('  SYMBOL etext');           nlmSpecialSymbols_Segments.Add('etext',pointer(ptruint(Section_text)));
             Concat('ENDEXESECTION');
+
             Concat('EXESECTION .data');
-            Concat('  SYMBOL __data_start__');
+            Concat('  SYMBOL __data_start__');  nlmSpecialSymbols_Segments.Add('__data_start__',pointer(ptruint(Section_data)));
             Concat('  OBJSECTION .data*');
             Concat('  OBJSECTION .fpc*');
-            Concat('  SYMBOL edata');
-            Concat('  SYMBOL __data_end__');
+            Concat('  SYMBOL edata');           nlmSpecialSymbols_Segments.Add('edata',pointer(ptruint(Section_data)));
+            Concat('  SYMBOL __data_end__');    nlmSpecialSymbols_Segments.Add('__data_end__',pointer(ptruint(Section_data)));
             Concat('ENDEXESECTION');
 
             Concat('EXESECTION .bss');
-            Concat('  SYMBOL __bss_start__');
+            Concat('  SYMBOL __bss_start__');   nlmSpecialSymbols_Segments.Add('__bss_start__',pointer(ptruint(Section_data)));
             Concat('  OBJSECTION .bss*');
-            Concat('  SYMBOL __bss_end__');
+            Concat('  SYMBOL __bss_end__');     nlmSpecialSymbols_Segments.Add('__bss_end__',pointer(ptruint(Section_data)));
             Concat('ENDEXESECTION');
 
             Concat('EXESECTION .imports');
@@ -880,6 +922,8 @@ end;
                 Concat ('STACKSIZE '+tostr(stacksize));
               end else
                 Concat ('STACKSIZE '+tostr(minStackSize));
+              if target_info.system = system_i386_netwlibc then
+                Concat ('REENTRANT');            { needed by older libc versions }
           end;
 
         // add symbols needed by nwpre. We have not loaded the ppu,