Browse Source

* fixed creating shared libraries under Darwin/Mac OS X

git-svn-id: trunk@727 -
Jonas Maebe 20 năm trước cách đây
mục cha
commit
6171499d15

+ 24 - 12
compiler/aggas.pas

@@ -290,9 +290,6 @@ var
           '.debug_frame'
         );
       begin
-        if (target_info.system = system_powerpc_darwin) and
-           (atype = sec_bss) then
-          atype := sec_code;
         if use_smartlink_section and
            (atype<>sec_bss) and
            (aname<>'') then
@@ -516,16 +513,31 @@ var
 
            ait_datablock :
              begin
-               if tai_datablock(hp).is_global then
-                AsmWrite(#9'.comm'#9)
+               if (target_info.system <> system_powerpc_darwin) or
+                  not tai_datablock(hp).is_global then
+                 begin
+                   if tai_datablock(hp).is_global then
+                    AsmWrite(#9'.comm'#9)
+                   else
+                    AsmWrite(#9'.lcomm'#9);
+                   AsmWrite(tai_datablock(hp).sym.name);
+                   AsmWrite(','+tostr(tai_datablock(hp).size));
+                   if (target_info.system = system_powerpc_darwin) { and
+                      not(tai_datablock(hp).is_global)} then
+                     AsmWrite(','+tostr(last_align));
+                   AsmWriteln('');
+                 end
                else
-                AsmWrite(#9'.lcomm'#9);
-               AsmWrite(tai_datablock(hp).sym.name);
-               AsmWrite(','+tostr(tai_datablock(hp).size));
-               if (target_info.system = system_powerpc_darwin) and
-                  not(tai_datablock(hp).is_global) then
-                 AsmWrite(','+tostr(last_align));
-               AsmWriteln('');
+                 begin
+                   AsmWrite('.globl ');
+                   AsmWriteln(tai_datablock(hp).sym.name);
+                   AsmWriteln('.data');
+                   AsmWrite('.zerofill __DATA, __common, ');
+                   AsmWrite(tai_datablock(hp).sym.name);
+                   AsmWriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
+                   if not(lasTSectype in [sec_data,sec_none]) then
+                     WriteSection(lasTSectype,'');
+                 end;
              end;
 
 {$ifndef cpu64bit}

+ 12 - 14
compiler/ncgld.pas

@@ -126,22 +126,20 @@ implementation
                begin
                   symtabletype:=symtable.symtabletype;
                   hregister:=NR_NO;
+                  if (target_info.system=system_powerpc_darwin) and
+                     ([vo_is_dll_var,vo_is_external] * tabstractvarsym(symtableentry).varoptions <> []) then
+                    begin
+                      if not(pi_needs_got in current_procinfo.flags) then
+                        internalerror(200403022);
+                      generate_picvaraccess;
+                    end
+                  else if (vo_is_dll_var in tabstractvarsym(symtableentry).varoptions) then
                   { DLL variable }
-                  if (vo_is_dll_var in tabstractvarsym(symtableentry).varoptions) then
                     begin
-                      if target_info.system=system_powerpc_darwin then
-                        begin
-                          generate_picvaraccess;
-                          if not(pi_needs_got in current_procinfo.flags) then
-                            internalerror(200403022);
-                        end
-                      else
-                        begin
-                          hregister:=cg.getaddressregister(exprasmlist);
-                          location.reference.symbol:=objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
-                          cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,location.reference,hregister);
-                          reference_reset_base(location.reference,hregister,0);
-                        end;
+                      hregister:=cg.getaddressregister(exprasmlist);
+                      location.reference.symbol:=objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA);
+                      cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,location.reference,hregister);
+                      reference_reset_base(location.reference,hregister,0);
                     end
                   { Thread variable }
                   else if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then

+ 2 - 1
compiler/nld.pas

@@ -391,7 +391,8 @@ implementation
                   registersint:=1;
                 if ([vo_is_thread_var,vo_is_dll_var]*tabstractvarsym(symtableentry).varoptions)<>[] then
                   registersint:=1;
-                if (target_info.system=system_powerpc_darwin) and (vo_is_dll_var in tabstractvarsym(symtableentry).varoptions) then
+                if (target_info.system=system_powerpc_darwin) and
+                   ([vo_is_dll_var,vo_is_external] * tabstractvarsym(symtableentry).varoptions <> []) then
                   include(current_procinfo.flags,pi_needs_got);
                 { call to get address of threadvar }
                 if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then

+ 13 - 1
compiler/powerpc/agppcgas.pas

@@ -29,6 +29,7 @@ unit agppcgas;
   interface
 
     uses
+       aasmbase,
        aasmtai,
        aggas,
        cpubase;
@@ -36,6 +37,7 @@ unit agppcgas;
     type
       PPPCGNUAssembler=^TPPCGNUAssembler;
       TPPCGNUAssembler=class(TGNUassembler)
+        function sectionname(atype:tasmsectiontype;const aname:string):string;override;
         procedure WriteExtraHeader;override;
         procedure WriteInstruction(hp : tai);override;
       end;
@@ -44,7 +46,7 @@ unit agppcgas;
   implementation
 
     uses
-       cutils,globals,verbose,
+       cutils,globals,verbose,globtype,
        cgbase,cgutils,systems,
        assemble,
        itcpugas,
@@ -96,6 +98,16 @@ unit agppcgas;
        refaddr2str_darwin: array[trefaddr] of string[4] = ('','','ha16','lo16','');
 
 
+
+    function TPPCGNUAssembler.sectionname(atype:tasmsectiontype;const aname:string):string;
+      begin
+        if (target_info.system = system_powerpc_darwin) and
+           (atype = sec_bss) then
+          atype := sec_code;
+        result := inherited sectionname(atype,aname);
+      end;
+
+
     function getreferencestring(var ref : treference) : string;
     var
       s : string;

+ 1 - 1
compiler/powerpc/nppcld.pas

@@ -91,7 +91,7 @@ unit nppcld;
         case target_info.system of
           system_powerpc_darwin:
             begin
-              if (vo_is_dll_var in tglobalvarsym(symtableentry).varoptions) or
+              if ([vo_is_dll_var,vo_is_external] * tglobalvarsym(symtableentry).varoptions <> []) or
                  ((tglobalvarsym(symtableentry).owner.symtabletype in [staticsymtable,globalsymtable]) and
                   not(tglobalvarsym(symtableentry).owner.iscurrentunit)) then
                 begin

+ 39 - 11
compiler/systems/t_bsd.pas

@@ -167,7 +167,7 @@ begin
   { first test the index value }
   if (hp.options and eo_index)<>0 then
    begin
-     Message1(parser_e_no_export_with_index_for_target,'freebsd');
+     Message1(parser_e_no_export_with_index_for_target,'*bsd/darwin');
      exit;
    end;
   { now place in correct order }
@@ -225,10 +225,16 @@ begin
            codeSegment.concat(Taicpu.Op_sym(A_JMP,S_NO,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
            codeSegment.concat(Tai_symbol_end.Createname(hp2.name^));
 {$endif i386}
+{$ifdef powerpc}
+           codesegment.concat(Tai_align.create(16));
+           codesegment.concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+           codeSegment.concat(Taicpu.Op_sym(A_B,objectlibrary.newasmsymbol(tprocsym(hp2.sym).first_procdef.mangledname,AB_EXTERNAL,AT_FUNCTION)));
+           codeSegment.concat(Tai_symbol_end.Createname(hp2.name^));
+{$endif powerpc}
          end;
       end
      else
-      Message1(parser_e_no_export_of_variables_for_target,'freebsd');
+      Message1(parser_e_no_export_of_variables_for_target,'*bsd/darwin');
      hp2:=texported_item(hp2.next);
    end;
 end;
@@ -261,12 +267,26 @@ begin
    begin
      if LdSupportsNoResponseFile then
        begin
-         ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE `cat $RES`';
+         if (target_info.system <> system_powerpc_darwin) then
+           begin
+             ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE `cat $RES`';
+             DllCmd[1]:='ld $OPT -shared -L. -o $EXE `cat $RES`'
+           end
+         else
+           begin
+             ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE `cat $RES`';
+             DllCmd[1]:='libtool $OPT -dynamic -init PASCALMAIN -multiply_defined suppress  -L. -o $EXE `cat $RES`'
+           end
        end
      else
-       ExeCmd[1]:='ld $OPT $DYNLINK $STATIC  $GCSECTIONS $STRIP -L. -o $EXE $RES';
-     DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
-     DllCmd[2]:='strip --strip-unneeded $EXE';
+       begin
+         ExeCmd[1]:='ld $OPT $DYNLINK $STATIC  $GCSECTIONS $STRIP -L. -o $EXE $RES';
+         DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
+       end;
+     if (target_info.system <> system_powerpc_darwin) then
+       DllCmd[2]:='strip --strip-unneeded $EXE'
+     else
+       DllCmd[2]:='strip -x $EXE';
      { first try glibc2 }
 {$ifdef GLIBC2} {Keep linux code in place. FBSD might go to a different
                                 glibc too once}
@@ -338,12 +358,15 @@ begin
     end
   else
     begin
-      { for darwin: always link dynamically against libc }
+      { for darwin: always link dynamically against libc }
       linklibc := true;
-      if not(cs_profile in aktmoduleswitches) then
-        prtobj:='/usr/lib/crt1.o'
+      if not(isdll) then
+        if not(cs_profile in aktmoduleswitches) then
+          prtobj:='/usr/lib/crt1.o'
+        else
+          prtobj:='/usr/lib/gcrt1.o'
       else
-        prtobj:='/usr/lib/gcrt1.o';
+        prtobj:='';
     end;
 
 
@@ -464,6 +487,11 @@ begin
         LinkRes.Add(')');
       end;
    end;
+  { ignore the fact that our relocations are in non-writable sections, }
+  { will be fixed once we have pic support                             }
+  if isdll and
+     (target_info.system = system_powerpc_darwin) then
+    LinkRes.Add('-read_only_relocs suppress');
 { Write and Close response }
   linkres.writetodisk;
   linkres.Free;
@@ -566,7 +594,7 @@ begin
   Replace(cmdstr,'$FINI',FiniStr);
   Replace(cmdstr,'$SONAME',SoNameStr);
 
-  success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+  success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,LdSupportsNoResponseFile);
 
 { Strip the library ? }
   if success and (cs_link_strip in aktglobalswitches) then