Răsfoiți Sursa

Merged revisions 10495-10497,10551,10554,10556-10559,10663 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r10495 | jonas | 2008-03-16 00:28:09 +0100 (Sun, 16 Mar 2008) | 11 lines

* fixed shared library initialisation for FPC-compiled libraries
when linked to FPC-compiled programs under linux/i386 which
do not use libc + test (mantis #8730). Programs which do use
libc and other linux targets have to be fixed in a similar
way until we properly fix everything by not exporting
any symbols at all from shared libraries by default (and
only those appearing in the "exports" section).

Finalisation does not work yet either for FPC-compiled
programs on linux/anything.

........
r10496 | jonas | 2008-03-16 00:53:55 +0100 (Sun, 16 Mar 2008) | 3 lines

+ test for previous commit with main program linking to libc
(apparently already works after all :)

........
r10497 | jonas | 2008-03-16 10:28:26 +0100 (Sun, 16 Mar 2008) | 2 lines

* test is not for windows

........
r10551 | jonas | 2008-03-24 17:55:05 +0100 (Mon, 24 Mar 2008) | 25 lines

* factored unix exports handling from t_bsd and t_linux into expunix unit
(todo: at least solaris, maybe others)
* changed the "exports" section handling:
a) make everything private which is not exported (implemented for
darwin and linux)
b) for the exported symbols:
- functions/procedures
1) if no name or index is provided, and if the procedure has aliases
defined via the public/export directives, then export the default
mangled name and all defined aliases
2) otherwise if no name is specified (but there is an index) then
i) if the procedure is defined as cdecl/cppdecl/mwpascal, use the
appropriately mangled version of the function name
ii) otherwise export the name without any mangling(e.g. "exports
proc1" -> proc1 is the exported name)
- variables
1) if no name is provided and the variable was specified as cvar,
use the mangled name
2) otherwise if no name is provided, export the name without any
mangling
-> initialization/finalization of shared libraries under Linux works
again (mantis #7838)
-> sharing symbols between shared library and main program works
under Linux (mantis #9089)

........
r10554 | jonas | 2008-03-24 23:19:21 +0100 (Mon, 24 Mar 2008) | 7 lines

* fixed execution of finalization section of smart linked shared
libraries on linux (mantis #6822)
* fixed execution of library finalization sections on darwin
(previously only the finalization section of the library
compilation unit itself was executed, now those of the units
used by the library are also executed)

........
r10556 | jonas | 2008-03-25 13:36:10 +0100 (Tue, 25 Mar 2008) | 2 lines

* fixed test

........
r10557 | jonas | 2008-03-25 13:39:37 +0100 (Tue, 25 Mar 2008) | 2 lines

* removed initc unit (not needed, and doesn't exist on windows)

........
r10558 | jonas | 2008-03-25 13:42:28 +0100 (Tue, 25 Mar 2008) | 2 lines

* also exit with an error if the dynamic library cannot be opened

........
r10559 | jonas | 2008-03-25 16:44:30 +0100 (Tue, 25 Mar 2008) | 3 lines

+ tests from mantis #6586, already work after the previous shared
library fixes

........
r10663 | jonas | 2008-04-14 14:00:48 +0200 (Mon, 14 Apr 2008) | 3 lines

* call finalization routine of dynamic linker before exiting (forgot to
commit earlier)

........

git-svn-id: branches/fixes_2_2@10664 -

Jonas Maebe 17 ani în urmă
părinte
comite
0c047f1788

+ 20 - 0
.gitattributes

@@ -107,6 +107,7 @@ compiler/dbgstabs.pas svneol=native#text/plain
 compiler/defcmp.pas svneol=native#text/plain
 compiler/defutil.pas svneol=native#text/plain
 compiler/export.pas svneol=native#text/plain
+compiler/expunix.pp svneol=native#text/plain
 compiler/finput.pas svneol=native#text/plain
 compiler/fmodule.pas svneol=native#text/plain
 compiler/fpccrc.pas svneol=native#text/plain
@@ -8592,6 +8593,8 @@ tests/webtbs/tw6491.pp svneol=native#text/plain
 tests/webtbs/tw6493.pp svneol=native#text/plain
 tests/webtbs/tw6525.pp -text
 tests/webtbs/tw6543.pp svneol=native#text/plain
+tests/webtbs/tw6586a.pp svneol=native#text/plain
+tests/webtbs/tw6586b.pp svneol=native#text/plain
 tests/webtbs/tw6624.pp svneol=native#text/plain
 tests/webtbs/tw6641.pp svneol=native#text/plain
 tests/webtbs/tw6684.pp svneol=native#text/plain
@@ -8604,6 +8607,9 @@ tests/webtbs/tw6735.pp svneol=native#text/plain
 tests/webtbs/tw6737.pp -text
 tests/webtbs/tw6742.pp svneol=native#text/plain
 tests/webtbs/tw6767.pp svneol=native#text/plain
+tests/webtbs/tw6822a.pp svneol=native#text/plain
+tests/webtbs/tw6822b.pp svneol=native#text/plain
+tests/webtbs/tw6822c.pp svneol=native#text/plain
 tests/webtbs/tw6865.pp svneol=native#text/plain
 tests/webtbs/tw6868.pp svneol=native#text/plain
 tests/webtbs/tw6960.pp svneol=native#text/plain
@@ -8654,6 +8660,8 @@ tests/webtbs/tw7806.pp svneol=native#text/plain
 tests/webtbs/tw7808.pp svneol=native#text/plain
 tests/webtbs/tw7817a.pp svneol=native#text/plain
 tests/webtbs/tw7817b.pp svneol=native#text/plain
+tests/webtbs/tw7838a.pp svneol=native#text/plain
+tests/webtbs/tw7838b.pp svneol=native#text/plain
 tests/webtbs/tw7847.pp svneol=native#text/plain
 tests/webtbs/tw7851.pp svneol=native#text/plain
 tests/webtbs/tw7851a.pp svneol=native#text/plain
@@ -8724,6 +8732,10 @@ tests/webtbs/tw8677.pp svneol=native#text/plain
 tests/webtbs/tw8678.pp svneol=native#text/plain
 tests/webtbs/tw8678a.pp svneol=native#text/plain
 tests/webtbs/tw8685.pp svneol=native#text/plain
+tests/webtbs/tw8730a.pp svneol=native#text/plain
+tests/webtbs/tw8730b.pp svneol=native#text/plain
+tests/webtbs/tw8730c.pp svneol=native#text/plain
+tests/webtbs/tw8730d.pp svneol=native#text/plain
 tests/webtbs/tw8757.pp svneol=native#text/plain
 tests/webtbs/tw8810.pp svneol=native#text/plain
 tests/webtbs/tw8838.pp svneol=native#text/plain
@@ -8744,6 +8756,10 @@ tests/webtbs/tw9073.pp svneol=native#text/plain
 tests/webtbs/tw9076.pp svneol=native#text/plain
 tests/webtbs/tw9076a.pp svneol=native#text/plain
 tests/webtbs/tw9085.pp svneol=native#text/plain
+tests/webtbs/tw9089a.pp svneol=native#text/plain
+tests/webtbs/tw9089b.pp svneol=native#text/plain
+tests/webtbs/tw9089c.pp svneol=native#text/plain
+tests/webtbs/tw9089d.pp svneol=native#text/plain
 tests/webtbs/tw9095.pp svneol=native#text/plain
 tests/webtbs/tw9096.pp svneol=native#text/plain
 tests/webtbs/tw9098.pp svneol=native#text/plain
@@ -8837,9 +8853,13 @@ tests/webtbs/uw4352e.pp svneol=native#text/plain
 tests/webtbs/uw4541.pp svneol=native#text/plain
 tests/webtbs/uw6203.pp svneol=native#text/plain
 tests/webtbs/uw6767.pp svneol=native#text/plain
+tests/webtbs/uw6822a.pp svneol=native#text/plain
 tests/webtbs/uw7381.pp svneol=native#text/plain
+tests/webtbs/uw7838a.pp svneol=native#text/plain
 tests/webtbs/uw8180.pp svneol=native#text/plain
 tests/webtbs/uw8372.pp svneol=native#text/plain
+tests/webtbs/uw8730a.pp svneol=native#text/plain
+tests/webtbs/uw8730b.pp svneol=native#text/plain
 tests/webtbs/uw9113a.pp svneol=native#text/plain
 tests/webtbs/uw9113b.pp svneol=native#text/plain
 utils/Makefile svneol=native#text/plain

+ 85 - 2
compiler/export.pas

@@ -28,8 +28,8 @@ interface
 uses
   cutils,cclasses,
   systems,
-  symtype,
-  aasmbase;
+  symtype,symdef,symsym,
+  aasmbase,aasmdata;
 
 const
    { export options }
@@ -51,6 +51,8 @@ type
    texportlib=class
    private
       notsupmsg : boolean;
+      finitname,
+      ffininame  : string;
       procedure NotSupported;
    public
       constructor Create;virtual;
@@ -59,10 +61,23 @@ type
       procedure exportprocedure(hp : texported_item);virtual;
       procedure exportvar(hp : texported_item);virtual;
       procedure generatelib;virtual;
+      procedure setinitname(list: TAsmList; const s: string); virtual;
+      procedure setfininame(list: TAsmList; const s: string); virtual;
+      
+      property initname: string read finitname;
+      property fininame: string read ffininame;
    end;
 
    TExportLibClass=class of TExportLib;
 
+
+  procedure exportprocsym(sym: tsym; const s : string; index: longint; options: word);
+  procedure exportvarsym(sym: tsym; const s : string; index: longint; options: word);
+
+  procedure exportallprocdefnames(sym: tprocsym; pd: tprocdef; options: word);
+  procedure exportallprocsymnames(ps: tprocsym; options: word);
+
+
 var
   CExportLib : array[tsystem] of TExportLibClass;
   ExportLib  : TExportLib;
@@ -80,6 +95,63 @@ uses
                            TExported_procedure
 ****************************************************************************}
 
+procedure exportprocsym(sym: tsym; const s : string; index: longint; options: word);
+  var
+    hp : texported_item;
+  begin
+    hp:=texported_item.create;
+    hp.name:=stringdup(s);
+    hp.sym:=sym;
+    hp.options:=options or eo_name;
+    hp.index:=index;
+    exportlib.exportprocedure(hp);
+  end;
+
+
+procedure exportvarsym(sym: tsym; const s : string; index: longint; options: word);
+  var
+    hp : texported_item;
+  begin
+    hp:=texported_item.create;
+    hp.name:=stringdup(s);
+    hp.sym:=sym;
+    hp.is_var:=true;
+    hp.options:=options or eo_name;
+    hp.index:=index;
+    exportlib.exportvar(hp);
+  end;
+
+
+  procedure exportallprocdefnames(sym: tprocsym; pd: tprocdef; options: word);
+    var
+      item: TCmdStrListItem;
+    begin
+      exportprocsym(sym,pd.mangledname,0,options);
+      { walk through all aliases }
+      item:=TCmdStrListItem(pd.aliasnames.first);
+      while assigned(item) do
+        begin
+          { avoid duplicate entries, sometimes aliasnames contains the mangledname }
+          if item.str<>pd.mangledname then
+            exportprocsym(sym,item.str,0,options);
+          item:=TCmdStrListItem(item.next);
+        end;
+    end;
+    
+
+  procedure exportallprocsymnames(ps: tprocsym; options: word);
+    var
+      i: longint;
+    begin
+      for i:= 0 to ps.ProcdefList.Count-1 do
+        exportallprocdefnames(ps,tprocdef(ps.ProcdefList[i]),options);
+    end;
+
+
+{****************************************************************************
+                           TExported_procedure
+****************************************************************************}
+
 constructor texported_item.Create;
 begin
   inherited Create;
@@ -148,6 +220,17 @@ begin
 end;
 
 
+procedure texportlib.setinitname(list: TAsmList; const s: string);
+begin
+  finitname:=s;
+end;
+
+
+procedure texportlib.setfininame(list: TAsmList; const s: string);
+begin
+  ffininame:=s;
+end;
+
 {*****************************************************************************
                                  Init/Done
 *****************************************************************************}

+ 185 - 0
compiler/expunix.pp

@@ -0,0 +1,185 @@
+{
+    Copyright (c) 2008 by the Free Pascal Compiler team
+
+    This unit implements common support for import,export,link routines
+    for unix target
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit expunix;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+  cutils,cclasses,
+  systems,
+  export,
+  symtype,symdef,symsym,
+  aasmbase;
+
+type
+  texportlibunix=class(texportlib)
+   private
+     fexportedsymnames: TCmdStrList;
+   public
+    constructor Create; override;
+    destructor destroy; override;
+    procedure preparelib(const s : string);override;
+    procedure exportprocedure(hp : texported_item);override;
+    procedure exportvar(hp : texported_item);override;
+    procedure generatelib;override;
+    property exportedsymnames: TCmdStrList read fexportedsymnames;
+  end;
+
+implementation
+
+{****************************************************************************
+                              TExportLibUnix
+****************************************************************************}
+
+uses
+  symconst,
+  globtype,globals,
+  aasmdata,aasmtai,aasmcpu,
+  fmodule,
+  cgbase,cgutils,cpubase,cgobj,
+  ncgutil,
+  verbose;
+
+
+constructor texportlibunix.create;
+begin
+  inherited create;
+  fexportedsymnames:=tcmdstrlist.create_no_double;
+end;
+
+destructor texportlibunix.destroy;
+begin
+  fexportedsymnames.free;
+  inherited destroy;
+end;
+
+
+
+procedure texportlibunix.preparelib(const s:string);
+begin
+end;
+
+
+procedure texportlibunix.exportprocedure(hp : texported_item);
+var
+  hp2 : texported_item;
+begin
+  { first test the index value }
+  if (hp.options and eo_index)<>0 then
+   begin
+     Message1(parser_e_no_export_with_index_for_target,target_info.shortname);
+     exit;
+   end;
+  { now place in correct order }
+  hp2:=texported_item(current_module._exports.first);
+  while assigned(hp2) and
+     (hp.name^>hp2.name^) do
+    hp2:=texported_item(hp2.next);
+  { insert hp there !! }
+  if assigned(hp2) and (hp2.name^=hp.name^) then
+    begin
+      { this is not allowed !! }
+      Message1(parser_e_export_name_double,hp.name^);
+      exit;
+    end;
+  if hp2=texported_item(current_module._exports.first) then
+    current_module._exports.concat(hp)
+  else if assigned(hp2) then
+    begin
+       hp.next:=hp2;
+       hp.previous:=hp2.previous;
+       if assigned(hp2.previous) then
+         hp2.previous.next:=hp;
+       hp2.previous:=hp;
+    end
+  else
+    current_module._exports.concat(hp);
+end;
+
+
+procedure texportlibunix.exportvar(hp : texported_item);
+begin
+  hp.is_var:=true;
+  exportprocedure(hp);
+end;
+
+
+procedure texportlibunix.generatelib;  // straight t_linux copy for now.
+var
+  hp2 : texported_item;
+  pd  : tprocdef;
+{$ifdef x86}
+  sym : tasmsymbol;
+  r : treference;
+{$endif x86}
+begin
+  new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
+  hp2:=texported_item(current_module._exports.first);
+  while assigned(hp2) do
+   begin
+     if (not hp2.is_var) and
+        (hp2.sym.typ=procsym) then
+      begin
+        { the manglednames can already be the same when the procedure
+          is declared with cdecl }
+        pd:=tprocdef(tprocsym(hp2.sym).ProcdefList[0]);
+        if not has_alias_name(pd,hp2.name^) then
+         begin
+           { place jump in al_procedures }
+           current_asmdata.asmlists[al_procedures].concat(tai_align.create(target_info.alignment.procalign));
+           current_asmdata.asmlists[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
+           if (cs_create_pic in current_settings.moduleswitches) and
+             { other targets need to be checked how it works }
+             (target_info.system in [system_i386_freebsd,system_x86_64_linux,system_i386_linux]) then
+             begin
+{$ifdef x86}
+               sym:=current_asmdata.RefAsmSymbol(pd.mangledname);
+               reference_reset_symbol(r,sym,0);
+               if cs_create_pic in current_settings.moduleswitches then
+                 r.refaddr:=addr_pic
+               else
+                 r.refaddr:=addr_full;
+               current_asmdata.asmlists[al_procedures].concat(taicpu.op_ref(A_JMP,S_NO,r));
+{$endif x86}
+             end
+           else
+             cg.a_jmp_name(current_asmdata.asmlists[al_procedures],pd.mangledname);
+           current_asmdata.asmlists[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
+         end;
+        exportedsymnames.insert(hp2.name^);
+      end
+     else
+       begin
+         if (hp2.name^<>hp2.sym.mangledname) then
+           Message2(parser_e_cant_export_var_different_name,hp2.sym.realname,hp2.sym.mangledname)
+         else
+           exportedsymnames.insert(hp2.name^);
+       end;
+     hp2:=texported_item(hp2.next);
+   end;
+end;
+
+
+end.

+ 5 - 1
compiler/msg/errore.msg

@@ -358,7 +358,7 @@ scan_w_multiple_main_name_overrides=02086_W_Overriding name of "main" procedure
 #
 # Parser
 #
-# 03237 is the last used one
+# 03247 is the last used one
 #
 % \section{Parser messages}
 % This section lists all parser messages. The parser takes care of the
@@ -1135,6 +1135,10 @@ parser_e_no_generics_as_types=03236_E_Generics without specialization can not be
 % Generics must be always specialized before being used as variable type
 parser_w_register_list_ignored=03237_W_Register list is ignored for pure assembler routines
 % When using pure assembler routines, the list with modified registers is ignored.
+parser_e_cant_export_var_different_name=03247_E_Variables cannot be exported with a different name on this target, add the name to the declaration using the "export" directive (variable name: $1, declared export name: $2)
+% On most targets it is not possible to change the name under which a variable is exported inside the \var{exports} statement of a library.
+% In that case, you have to specify the export name at the point where the variable is declared, using the \var{export} and \var{alias} directives.
+
 % \end{description}
 #
 # Type Checking

+ 3 - 2
compiler/msgidx.inc

@@ -325,6 +325,7 @@ const
   parser_e_no_common_type=03235;
   parser_e_no_generics_as_types=03236;
   parser_w_register_list_ignored=03237;
+  parser_e_cant_export_var_different_name=03247;
   type_e_mismatch=04000;
   type_e_incompatible_types=04001;
   type_e_not_equal_types=04002;
@@ -735,9 +736,9 @@ const
   option_info=11024;
   option_help_pages=11025;
 
-  MsgTxtSize = 45652;
+  MsgTxtSize = 45834;
 
   MsgIdxMax : array[1..20] of longint=(
-    24,87,238,84,63,50,108,22,135,60,
+    24,87,248,84,63,50,108,22,135,60,
     42,1,1,1,1,1,1,1,1,1
   );

+ 270 - 269
compiler/msgtxt.inc

@@ -370,455 +370,456 @@ const msgtxt : array[0..000190,1..240] of char=(
   '03236_E_Generics without specialization can not be used as a type for '+
   'a variable'#000+
   '03237_W_Register list is ignored for pure assembler routines'#000+
-  '04000_E_Type mismatch'#000,
+  '03247_E_Variables cann','ot be exported with a different name on this t'+
+  'arget, add the name to the declaration using the "export" directive (v'+
+  'ariable name: $1, declared export name: $2)'#000+
+  '04000_E_Type mismatch'#000+
   '04001_E_Incompatible types: got "$1" expected "$2"'#000+
-  '04002_E_Type mismatch between "$1" and "$2"'#000+
+  '04002_E','_Type mismatch between "$1" and "$2"'#000+
   '04003_E_Type identifier expected'#000+
   '04004_E_Variable identifier expected'#000+
   '04005_E_Integer expression expected, but got "$1"'#000+
-  '04006_E_Boolean expressio','n expected, but got "$1"'#000+
-  '04007_E_Ordinal expression expected'#000+
+  '04006_E_Boolean expression expected, but got "$1"'#000+
+  '04007_E_Ordinal expression expect','ed'#000+
   '04008_E_pointer type expected, but got "$1"'#000+
   '04009_E_class type expected, but got "$1"'#000+
   '04011_E_Can'#039't evaluate constant expression'#000+
   '04012_E_Set elements are not compatible'#000+
-  '04013_E_Op','eration not implemented for sets'#000+
-  '04014_W_Automatic type conversion from floating type to COMP which is '+
-  'an integer type'#000+
+  '04013_E_Operation not implemented for sets'#000+
+  '04014_W_Automatic type co','nversion from floating type to COMP which i'+
+  's an integer type'#000+
   '04015_H_use DIV instead to get an integer result'#000+
   '04016_E_string types doesn'#039't match, because of $V+ mode'#000+
-  '04017_E_succ or ','pred on enums with assignments not possible'#000+
-  '04018_E_Can'#039't read or write variables of this type'#000+
+  '04017_E_succ or pred on enums with assignments not possible'#000+
+  '04018_E_Can'#039't ','read or write variables of this type'#000+
   '04019_E_Can'#039't use readln or writeln on typed file'#000+
   '04020_E_Can'#039't use read or write on untyped file.'#000+
   '04021_E_Type conflict between set elements'#000+
-  '040','22_W_lo/hi(dword/qword) returns the upper/lower word/dword'#000+
+  '04022_W_lo/hi(dword/qword) returns the upper/lower word/dword',#000+
   '04023_E_Integer or real expression expected'#000+
   '04024_E_Wrong type "$1" in array constructor'#000+
   '04025_E_Incompatible type for arg no. $1: Got "$2", expected "$3"'#000+
-  '04026_E_Method (variable) ','and Procedure (variable) are not compatibl'+
-  'e'#000+
-  '04027_E_Illegal constant passed to internal math function'#000+
+  '04026_E_Method (variable) and Procedure (variable) are not compatible'#000+
+  '04027_E_Illega','l constant passed to internal math function'#000+
   '04028_E_Can'#039't get the address of constants'#000+
   '04029_E_Argument can'#039't be assigned to'#000+
-  '04030_E_Can'#039't assign local procedure/function to procedur','e varia'+
-  'ble'#000+
+  '04030_E_Can'#039't assign local procedure/function to procedure variabl'+
+  'e'#000+
   '04031_E_Can'#039't assign values to an address'#000+
-  '04032_E_Can'#039't assign values to const variable'#000+
+  '04032','_E_Can'#039't assign values to const variable'#000+
   '04033_E_Array type required'#000+
   '04034_E_interface type expected, but got "$1"'#000+
-  '04035_W_Mixing signed expressions and longwords gives a 64bit resul','t'+
-  #000+
-  '04036_W_Mixing signed expressions and cardinals here may cause a range'+
-  ' check error'#000+
+  '04035_W_Mixing signed expressions and longwords gives a 64bit result'#000+
+  '04036_W_Mixing signed expressions and cardinals here may',' cause a ran'+
+  'ge check error'#000+
   '04037_E_Typecast has different size ($1 -> $2) in assignment'#000+
   '04038_E_enums with assignments can'#039't be used as array index'#000+
-  '04039_E_Class or Object types "$1"',' and "$2" are not related'#000+
-  '04040_W_Class types "$1" and "$2" are not related'#000+
+  '04039_E_Class or Object types "$1" and "$2" are not related'#000+
+  '04040_W_Class types "$1" and "$2','" are not related'#000+
   '04041_E_Class or interface type expected, but got "$1"'#000+
   '04042_E_Type "$1" is not completely defined'#000+
-  '04043_W_String literal has more characters than short string leng','th'#000+
-  '04044_W_Comparison is always false due to range of values'#000+
+  '04043_W_String literal has more characters than short string length'#000+
+  '04044_W_Comparison is always false due to range of valu','es'#000+
   '04045_W_Comparison is always true due to range of values'#000+
   '04046_W_Constructing a class "$1" with abstract methods'#000+
   '04047_H_The left operand of the IN operator should be byte sized'#000+
-  '0','4048_W_Type size mismatch, possible loss of data / range check erro'+
+  '04048_W_Type size mismatch, possible loss of data / range c','heck erro'+
   'r'#000+
   '04049_H_Type size mismatch, possible loss of data / range check error'#000+
   '04050_E_The address of an abstract method can'#039't be taken'#000+
-  '04051_E_Assignments to formal parameters and',' open arrays are not pos'+
-  'sible'#000+
-  '04052_E_Constant Expression expected'#000+
+  '04051_E_Assignments to formal parameters and open arrays are not possi'+
+  'ble'#000+
+  '04052_E_Constant Expression ','expected'#000+
   '04053_E_Operation "$1" not supported for types "$2" and "$3"'#000+
   '04054_E_Illegal type conversion: "$1" to "$2"'#000+
   '04055_H_Conversion between ordinals and pointers is not portable'#000+
-  '0','4056_W_Conversion between ordinals and pointers is not portable'#000+
+  '04056_W_Conversion between ordinals and pointers is not por','table'#000+
   '04057_E_Can'#039't determine which overloaded function to call'#000+
   '04058_E_Illegal counter variable'#000+
   '04059_W_Converting constant real value to double for C variable argume'+
-  'nt, add explici','t typecast to prevent this.'#000+
-  '04060_E_Class or COM interface type expected, but got "$1"'#000+
+  'nt, add explicit typecast to prevent this.'#000+
+  '04060_E_Class or COM interface',' type expected, but got "$1"'#000+
   '04061_E_Constant packed arrays are not yet supported'#000+
   '04062_E_Incompatible type for arg no. $1: Got "$2" expected "(Bit)Pack'+
   'ed Array"'#000+
-  '04063_E_Incompatible',' type for arg no. $1: Got "$2" expected "(not pa'+
-  'cked) Array"'#000+
+  '04063_E_Incompatible type for arg no. $1: Got "$2" expected "(not pack'+
+  'ed) Arra','y"'#000+
   '04064_E_Elements of packed arrays cannot be of a type which need to be'+
   ' initialised'#000+
   '04065_E_Constant packed records and objects are not yet supported'#000+
-  '04066_W_Arithmetic "$1" on unt','yped pointer is unportable to {$T+}, s'+
-  'uggest typecast'#000+
-  '04076_E_Can'#039't take address of a subroutine marked as local'#000+
+  '04066_W_Arithmetic "$1" on untyped pointer is unportable to {$T+}, sug'+
+  'gest typecast'#000+
+  '0407','6_E_Can'#039't take address of a subroutine marked as local'#000+
   '04077_E_Can'#039't export subroutine marked as local from a unit'#000+
   '04078_E_Type is not automatable: "$1"'#000+
-  '04079_H_Converting the operan','ds to "$1" before doing the add could p'+
-  'revent overflow errors.'#000+
+  '04079_H_Converting the operands to "$1" before doing the add could pre'+
+  'vent overflow err','ors.'#000+
   '04080_H_Converting the operands to "$1" before doing the subtract coul'+
   'd prevent overflow errors.'#000+
   '04081_H_Converting the operands to "$1" before doing the multiply coul'+
-  'd prevent ','overflow errors.'#000+
-  '04082_W_Converting pointers to signed integers may result in wrong com'+
-  'parison results and range errors, use an unsigned type instead.'#000+
+  'd prevent overflow errors.'#000+
+  '04082_W_Converting pointers to signed int','egers may result in wrong c'+
+  'omparison results and range errors, use an unsigned type instead.'#000+
   '04083_E_Interface type $1 has no valid GUID'#000+
   '05000_E_Identifier not found "$1"'#000+
-  '05001_F_Int','ernal Error in SymTableStack()'#000+
-  '05002_E_Duplicate identifier "$1"'#000+
+  '05001_F_Internal Error in SymTableStack()'#000+
+  '05002_E_Duplicate identifie','r "$1"'#000+
   '05003_H_Identifier already defined in $1 at line $2'#000+
   '05004_E_Unknown identifier "$1"'#000+
   '05005_E_Forward declaration not solved "$1"'#000+
   '05007_E_Error in type definition'#000+
-  '05009_E_Forwar','d type not resolved "$1"'#000+
-  '05010_E_Only static variables can be used in static methods or outside'+
-  ' methods'#000+
+  '05009_E_Forward type not resolved "$1"'#000+
+  '05010_E_Only static variables can',' be used in static methods or outsi'+
+  'de methods'#000+
   '05012_F_record or class type expected'#000+
   '05013_E_Instances of classes or objects with an abstract method are no'+
   't allowed'#000+
-  '05014_W_Label not ','defined "$1"'#000+
+  '05014_W_Label not defined "$1"'#000+
   '05015_E_Label used but not defined "$1"'#000+
-  '05016_E_Illegal label declaration'#000+
+  '05016','_E_Illegal label declaration'#000+
   '05017_E_GOTO and LABEL are not supported (use switch -Sg)'#000+
   '05018_E_Label not found'#000+
   '05019_E_identifier isn'#039't a label'#000+
   '05020_E_label already defined'#000+
-  '05021_E_','illegal type declaration of set elements'#000+
-  '05022_E_Forward class definition not resolved "$1"'#000+
+  '05021_E_illegal type declaration of set elements'#000+
+  '05022_E_Forward c','lass definition not resolved "$1"'#000+
   '05023_H_Unit "$1" not used in $2'#000+
   '05024_H_Parameter "$1" not used'#000+
   '05025_N_Local variable "$1" not used'#000+
-  '05026_H_Value parameter "$1" is assigned but n','ever used'#000+
-  '05027_N_Local variable "$1" is assigned but never used'#000+
+  '05026_H_Value parameter "$1" is assigned but never used'#000+
+  '05027_N_Local variable "$1" is assigned but neve','r used'#000+
   '05028_H_Local $1 "$2" is not used'#000+
   '05029_N_Private field "$1.$2" is never used'#000+
   '05030_N_Private field "$1.$2" is assigned but never used'#000+
-  '05031_N_Private method "$1.$2" never use','d'#000+
+  '05031_N_Private method "$1.$2" never used'#000+
   '05032_E_Set type expected'#000+
-  '05033_W_Function result does not seem to be set'#000+
+  '05033_W_Function result does n','ot seem to be set'#000+
   '05034_W_Type "$1" is not aligned correctly in current record for C'#000+
   '05035_E_Unknown record field identifier "$1"'#000+
-  '05036_W_Local variable "$1" does not seem to be init','ialized'#000+
-  '05037_W_Variable "$1" does not seem to be initialized'#000+
+  '05036_W_Local variable "$1" does not seem to be initialized'#000+
+  '05037_W_Variable "$1" does not seem to be initiali','zed'#000+
   '05038_E_identifier idents no member "$1"'#000+
   '05039_H_Found declaration: $1'#000+
   '05040_E_Data element too large'#000+
   '05042_E_No matching implementation for interface method "$1" found'#000+
-  '05043_W_S','ymbol "$1" is deprecated'#000+
-  '05044_W_Symbol "$1" is not portable'#000+
+  '05043_W_Symbol "$1" is deprecated'#000+
+  '05044_W_Symbol "$1" is not portab','le'#000+
   '05055_W_Symbol "$1" is not implemented'#000+
   '05056_E_Can'#039't create unique type from this type'#000+
   '05057_H_Local variable "$1" does not seem to be initialized'#000+
-  '05058_H_Variable "$1" does not s','eem to be initialized'#000+
-  '05059_W_Function result variable does not seem to initialized'#000+
+  '05058_H_Variable "$1" does not seem to be initialized'#000+
+  '05059_W_Function result variable doe','s not seem to initialized'#000+
   '05060_H_Function result variable does not seem to be initialized'#000+
   '05061_W_Variable "$1" read but nowhere assigned'#000+
   '05062_H_Found abstract method: $1'#000+
-  '06009_E_P','arameter list size exceeds 65535 bytes'#000+
-  '06012_E_File types must be var parameters'#000+
+  '06009_E_Parameter list size exceeds 65535 bytes'#000+
+  '06012_E_File types ','must be var parameters'#000+
   '06013_E_The use of a far pointer isn'#039't allowed there'#000+
   '06015_E_EXPORT declared functions can'#039't be called'#000+
-  '06016_W_Possible illegal call of constructor or destruct','or'#000+
+  '06016_W_Possible illegal call of constructor or destructor'#000+
   '06017_N_Inefficient code'#000+
   '06018_W_unreachable code'#000+
-  '06020_E_Abstract methods can'#039't be called directly'#000+
+  '06020','_E_Abstract methods can'#039't be called directly'#000+
   '06027_DL_Register $1 weight $2 $3'#000+
   '06029_DL_Stack frame is omitted'#000+
   '06031_E_Object or class methods can'#039't be inline.'#000+
-  '06032_E_Procvar calls ','cannot be inline.'#000+
-  '06033_E_No code for inline procedure stored'#000+
+  '06032_E_Procvar calls cannot be inline.'#000+
+  '06033_E_No code for inline procedure sto','red'#000+
   '06035_E_Element zero of an ansi/wide- or longstring can'#039't be acces'+
   'sed, use (set)length instead'#000+
   '06037_E_Constructors or destructors can not be called inside a '#039'wi'+
   'th'#039' clause'#000+
-  '06038_','E_Cannot call message handler methods directly'#000+
-  '06039_E_Jump in or outside of an exception block'#000+
+  '06038_E_Cannot call message handler methods directly'#000+
+  '06039_E_Jum','p in or outside of an exception block'#000+
   '06040_E_Control flow statements aren'#039't allowed in a finally block'#000+
   '06041_W_Parameters size exceeds limit for certain cpu'#039's'#000+
-  '06042_W_Local variable',' size exceed limit for certain cpu'#039's'#000+
-  '06043_E_Local variables size exceeds supported limit'#000+
+  '06042_W_Local variable size exceed limit for certain cpu'#039's'#000+
+  '06043_E_Local variabl','es size exceeds supported limit'#000+
   '06044_E_BREAK not allowed'#000+
   '06045_E_CONTINUE not allowed'#000+
   '06046_F_Unknown compilerproc "$1". Check if you use the correct run ti'+
   'me library.'#000+
-  '06047_F_Canno','t find system type "$1". Check if you use the correct r'+
-  'un time library.'#000+
+  '06047_F_Cannot find system type "$1". Check if you use the correct run'+
+  ' ','time library.'#000+
   '06048_H_Inherited call to abstract method ignored'#000+
   '06049_E_Goto label "$1" not defined or optimized away'#000+
   '07000_DL_Starting $1 styled assembler parsing'#000+
-  '07001_DL_Finished ','$1 styled assembler parsing'#000+
-  '07002_E_Non-label pattern contains @'#000+
+  '07001_DL_Finished $1 styled assembler parsing'#000+
+  '07002_E_Non-label pattern cont','ains @'#000+
   '07004_E_Error building record offset'#000+
   '07005_E_OFFSET used without identifier'#000+
   '07006_E_TYPE used without identifier'#000+
   '07007_E_Cannot use local variable or parameters here'#000+
-  '07008_E_n','eed to use OFFSET here'#000+
+  '07008_E_need to use OFFSET here'#000+
   '07009_E_need to use $ here'#000+
-  '07010_E_Cannot use multiple relocatable symbols'#000+
+  '07010_E_','Cannot use multiple relocatable symbols'#000+
   '07011_E_Relocatable symbol can only be added'#000+
   '07012_E_Invalid constant expression'#000+
   '07013_E_Relocatable symbol is not allowed'#000+
-  '07014_E_Invalid ref','erence syntax'#000+
-  '07015_E_You can not reach $1 from that code'#000+
+  '07014_E_Invalid reference syntax'#000+
+  '07015_E_You can not reach $1 from that code'#000,
   '07016_E_Local symbols/labels aren'#039't allowed as references'#000+
   '07017_E_Invalid base and index register usage'#000+
   '07018_W_Possible error in object field handling'#000+
-  '07019_E_Wrong scale factor spe','cified'#000+
+  '07019_E_Wrong scale factor specified'#000+
   '07020_E_Multiple index register usage'#000+
-  '07021_E_Invalid operand type'#000+
+  '07021_E_Inval','id operand type'#000+
   '07022_E_Invalid string as opcode operand: $1'#000+
   '07023_W_@CODE and @DATA not supported'#000+
   '07024_E_Null label references are not allowed'#000+
-  '07025_E_Divide by zero in asm evaluat','or'#000+
+  '07025_E_Divide by zero in asm evaluator'#000+
   '07026_E_Illegal expression'#000+
-  '07027_E_escape sequence ignored: $1'#000+
+  '07027_E_escape sequence igno','red: $1'#000+
   '07028_E_Invalid symbol reference'#000+
   '07029_W_Fwait can cause emulation problems with emu387'#000+
   '07030_W_$1 without operand translated into $1P'#000+
-  '07031_W_ENTER instruction is not suppor','ted by Linux kernel'#000+
-  '07032_W_Calling an overload function in assembler'#000+
+  '07031_W_ENTER instruction is not supported by Linux kernel'#000+
+  '07032_W_Calling an overload function i','n assembler'#000+
   '07033_E_Unsupported symbol type for operand'#000+
   '07034_E_Constant value out of bounds'#000+
   '07035_E_Error converting decimal $1'#000+
   '07036_E_Error converting octal $1'#000+
-  '07037_E_Error conve','rting binary $1'#000+
+  '07037_E_Error converting binary $1'#000+
   '07038_E_Error converting hexadecimal $1'#000+
-  '07039_H_$1 translated to $2'#000+
+  '07','039_H_$1 translated to $2'#000+
   '07040_W_$1 is associated to an overloaded function'#000+
   '07041_E_Cannot use SELF outside a method'#000+
   '07042_E_Cannot use OLDEBP outside a nested procedure'#000+
-  '07043_W_Pro','cedures can'#039't return any value in asm code'#000+
-  '07044_E_SEG not supported'#000+
+  '07043_W_Procedures can'#039't return any value in asm code'#000+
+  '07044_E_SEG not',' supported'#000+
   '07045_E_Size suffix and destination or source size do not match'#000+
   '07046_W_Size suffix and destination or source size do not match'#000+
   '07047_E_Assembler syntax error'#000+
-  '07048_E_Inva','lid combination of opcode and operands'#000+
-  '07049_E_Assembler syntax error in operand'#000+
+  '07048_E_Invalid combination of opcode and operands'#000+
+  '07049_E_Assembler s','yntax error in operand'#000+
   '07050_E_Assembler syntax error in constant'#000+
   '07051_E_Invalid String expression'#000+
   '07052_W_constant with symbol $1 for address which is not on a pointer'#000+
-  '07053_E_Unre','cognized opcode $1'#000+
+  '07053_E_Unrecognized opcode $1'#000+
   '07054_E_Invalid or missing opcode'#000+
-  '07055_E_Invalid combination of prefix and opcode: $1'#000+
+  '07055','_E_Invalid combination of prefix and opcode: $1'#000+
   '07056_E_Invalid combination of override and opcode: $1'#000+
   '07057_E_Too many operands on line'#000+
   '07058_W_NEAR ignored'#000+
   '07059_W_FAR ignored'#000+
-  '0706','0_E_Duplicate local symbol $1'#000+
-  '07061_E_Undefined local symbol $1'#000+
+  '07060_E_Duplicate local symbol $1'#000+
+  '07061_E_Undefined local symb','ol $1'#000+
   '07062_E_Unknown label identifier $1'#000+
   '07063_E_Invalid register name'#000+
   '07064_E_Invalid floating point register name'#000+
   '07066_W_Modulo not supported'#000+
-  '07067_E_Invalid floating point const','ant $1'#000+
+  '07067_E_Invalid floating point constant $1'#000+
   '07068_E_Invalid floating point expression'#000+
-  '07069_E_Wrong symbol type'#000+
+  '07069_E_W','rong symbol type'#000+
   '07070_E_Cannot index a local var or parameter with a register'#000+
   '07071_E_Invalid segment override expression'#000+
   '07072_W_Identifier $1 supposed external'#000+
-  '07073_E_Strings not',' allowed as constants'#000+
-  '07074_No type of variable specified'#000+
+  '07073_E_Strings not allowed as constants'#000+
+  '07074_No type of variable specified'#000,
   '07075_E_assembler code not returned to text section'#000+
   '07076_E_Not a directive or local symbol $1'#000+
   '07077_E_Using a defined name as a local label'#000+
-  '07078_E_Dollar token is used without an i','dentifier'#000+
+  '07078_E_Dollar token is used without an identifier'#000+
   '07079_W_32bit constant created for address'#000+
-  '07080_N_.align is target specific, use .balign or .p2align'#000+
+  '07080','_N_.align is target specific, use .balign or .p2align'#000+
   '07081_E_Can'#039't access fields directly for parameters'#000+
   '07082_E_Can'#039't access fields of objects/classes directly'#000+
-  '07083_E_No size spec','ified and unable to determine the size of the op'+
-  'erands'#000+
-  '07084_E_Cannot use RESULT in this function'#000+
+  '07083_E_No size specified and unable to determine the size of the oper'+
+  'ands'#000+
+  '070','84_E_Cannot use RESULT in this function'#000+
   '07086_W_"$1" without operand translated into "$1 %st,%st(1)"'#000+
   '07087_W_"$1 %st(n)" translated into "$1 %st,%st(n)"'#000+
-  '07088_W_"$1 %st(n)" translate','d into "$1 %st(n),%st"'#000+
+  '07088_W_"$1 %st(n)" translated into "$1 %st(n),%st"'#000+
   '07089_E_Char < not allowed here'#000+
-  '07090_E_Char > not allowed here'#000+
+  '070','90_E_Char > not allowed here'#000+
   '07093_W_ALIGN not supported'#000+
   '07094_E_Inc and Dec cannot be together'#000+
   '07095_E_Invalid reglist for movem'#000+
   '07096_E_Reglist invalid for opcode'#000+
-  '07097_E_Higher cp','u mode required ($1)'#000+
-  '07098_W_No size specified and unable to determine the size of the oper'+
-  'ands, using DWORD as default'#000+
+  '07097_E_Higher cpu mode required ($1)'#000+
+  '07098_W_No size specified and unable ','to determine the size of the op'+
+  'erands, using DWORD as default'#000+
   '07099_E_Syntax error while trying to parse a shifter operand'#000+
-  '07100_E_Address of packed component is not at a byte bounda','ry'#000+
-  '07101_W_No size specified and unable to determine the size of the oper'+
-  'ands, using BYTE as default'#000+
+  '07100_E_Address of packed component is not at a byte boundary'#000+
+  '07101_W_No size specified and unable to determine the s','ize of the op'+
+  'erands, using BYTE as default'#000+
   '07102_W_Use of +offset(%ebp) for parameters invalid here'#000+
   '07103_W_Use of +offset(%ebp) is not compatible with regcall convention'+
   #000+
-  '07104_W_Use',' of -offset(%ebp) is not recommended for local variable a'+
-  'ccess'#000+
+  '07104_W_Use of -offset(%ebp) is not recommended for local variable ac',
+  'cess'#000+
   '07105_W_Use of -offset(%esp), access may cause a crash or value may be'+
   ' lost'#000+
   '07106_E_VMTOffset must be used in combination with a virtual method, a'+
   'nd "$1" is not virtual'#000+
-  '07107_E_','Generating PIC, but reference is not PIC-safe'#000+
-  '08000_F_Too many assembler files'#000+
+  '07107_E_Generating PIC, but reference is not PIC-safe'#000+
+  '08000_F_Too ','many assembler files'#000+
   '08001_F_Selected assembler output not supported'#000+
   '08002_F_Comp not supported'#000+
   '08003_F_Direct not support for binary writers'#000+
-  '08004_E_Allocating of data is only allow','ed in bss section'#000+
+  '08004_E_Allocating of data is only allowed in bss section'#000+
   '08005_F_No binary writer selected'#000+
-  '08006_E_Asm: Opcode $1 not in table'#000+
+  '08006_','E_Asm: Opcode $1 not in table'#000+
   '08007_E_Asm: $1 invalid combination of opcode and operands'#000+
   '08008_E_Asm: 16 Bit references not supported'#000+
   '08009_E_Asm: Invalid effective address'#000+
-  '08010_E_A','sm: Immediate or reference expected'#000+
-  '08011_E_Asm: $1 value exceeds bounds $2'#000+
+  '08010_E_Asm: Immediate or reference expected'#000+
+  '08011_E_Asm: $1 value ','exceeds bounds $2'#000+
   '08012_E_Asm: Short jump is out of range $1'#000+
   '08013_E_Asm: Undefined label $1'#000+
   '08014_E_Asm: Comp type not supported for this target'#000+
-  '08015_E_Asm: Extended type not suppo','rted for this target'#000+
+  '08015_E_Asm: Extended type not supported for this target'#000+
   '08016_E_Asm: Duplicate label $1'#000+
-  '08017_E_Asm: Redefined label $1'#000+
+  '08017','_E_Asm: Redefined label $1'#000+
   '08018_E_Asm: First defined here'#000+
   '08019_E_Asm: Invalid register $1'#000+
   '08020_E_Asm: 16 or 32 Bit references not supported'#000+
-  '08021_E_Asm: 64 Bit operands not suppor','ted'#000+
+  '08021_E_Asm: 64 Bit operands not supported'#000+
   '09000_W_Source operating system redefined'#000+
-  '09001_I_Assembling (pipe) $1'#000+
+  '09001_I_Asse','mbling (pipe) $1'#000+
   '09002_E_Can'#039't create assembler file: $1'#000+
   '09003_E_Can'#039't create object file: $1'#000+
   '09004_E_Can'#039't create archive file: $1'#000+
-  '09005_E_Assembler $1 not found, switching to exter','nal assembling'#000+
+  '09005_E_Assembler $1 not found, switching to external assembling'#000+
   '09006_T_Using assembler: $1'#000+
-  '09007_E_Error while assembling exitcode $1'#000+
+  '09007_E_Error w','hile assembling exitcode $1'#000+
   '09008_E_Can'#039't call the assembler, error $1 switching to external a'+
   'ssembling'#000+
   '09009_I_Assembling $1'#000+
   '09010_I_Assembling with smartlinking $1'#000+
-  '09011_W_Object $','1 not found, Linking may fail !'#000+
-  '09012_W_Library $1 not found, Linking may fail !'#000+
+  '09011_W_Object $1 not found, Linking may fail !'#000+
+  '09012_W_Library $1 not fou','nd, Linking may fail !'#000+
   '09013_E_Error while linking'#000+
   '09014_E_Can'#039't call the linker, switching to external linking'#000+
   '09015_I_Linking $1'#000+
-  '09016_E_Util $1 not found, switching to external li','nking'#000+
+  '09016_E_Util $1 not found, switching to external linking'#000+
   '09017_T_Using util $1'#000+
-  '09018_E_Creation of Executables not supported'#000+
+  '09018_E_Creation of Executable','s not supported'#000+
   '09019_E_Creation of Dynamic/Shared Libraries not supported'#000+
   '09020_I_Closing script $1'#000+
   '09021_E_resource compiler not found, switching to external mode'#000+
-  '09022_I_Compiling',' resource $1'#000+
-  '09023_T_unit $1 can'#039't be statically linked, switching to smart lin'+
-  'king'#000+
+  '09022_I_Compiling resource $1'#000+
+  '09023_T_unit $1 can'#039't be statically linked, s','witching to smart l'+
+  'inking'#000+
   '09024_T_unit $1 can'#039't be smart linked, switching to static linking'+
   #000+
   '09025_T_unit $1 can'#039't be shared linked, switching to static linkin'+
   'g'#000+
-  '09026_E_unit $1 can'#039't',' be smart or static linked'#000+
-  '09027_E_unit $1 can'#039't be shared or static linked'#000+
+  '09026_E_unit $1 can'#039't be smart or static linked'#000+
+  '09027_E_unit $1 can'#039't be shared',' or static linked'#000+
   '09028_D_Calling resource compiler "$1" with "$2" as command line'#000+
   '09128_F_Can'#039't post process executable $1'#000+
   '09129_F_Can'#039't open executable $1'#000+
-  '09130_X_Size of Code: $1 ','bytes'#000+
+  '09130_X_Size of Code: $1 bytes'#000+
   '09131_X_Size of initialized data: $1 bytes'#000+
-  '09132_X_Size of uninitialized data: $1 bytes'#000+
+  '09132_X_S','ize of uninitialized data: $1 bytes'#000+
   '09133_X_Stack space reserved: $1 bytes'#000+
   '09134_X_Stack space committed: $1 bytes'#000+
   '10000_T_Unitsearch: $1'#000+
   '10001_T_PPU Loading $1'#000+
-  '10002_U_PPU Name: $1'#000,
+  '10002_U_PPU Name: $1'#000+
   '10003_U_PPU Flags: $1'#000+
   '10004_U_PPU Crc: $1'#000+
-  '10005_U_PPU Time: $1'#000+
+  '10005_U_PPU Time',': $1'#000+
   '10006_U_PPU File too short'#000+
   '10007_U_PPU Invalid Header (no PPU at the begin)'#000+
   '10008_U_PPU Invalid Version $1'#000+
   '10009_U_PPU is compiled for another processor'#000+
-  '10010_U_PPU is compiled ','for an other target'#000+
+  '10010_U_PPU is compiled for an other target'#000+
   '10011_U_PPU Source: $1'#000+
-  '10012_U_Writing $1'#000+
+  '10012_U_Writing',' $1'#000+
   '10013_F_Can'#039't Write PPU-File'#000+
   '10014_F_Error reading PPU-File'#000+
   '10015_F_unexpected end of PPU-File'#000+
   '10016_F_Invalid PPU-File entry: $1'#000+
   '10017_F_PPU Dbx count problem'#000+
-  '10018_E_Illegal un','it name: $1'#000+
+  '10018_E_Illegal unit name: $1'#000+
   '10019_F_Too much units'#000+
-  '10020_F_Circular unit reference between $1 and $2'#000+
+  '10020_F_Circular unit r','eference between $1 and $2'#000+
   '10021_F_Can'#039't compile unit $1, no sources available'#000+
   '10022_F_Can'#039't find unit $1 used by $2'#000+
   '10023_W_Unit $1 was not found but $2 exists'#000+
-  '10024_F_Unit $1 searc','hed but $2 found'#000+
-  '10025_W_Compiling the system unit requires the -Us switch'#000+
+  '10024_F_Unit $1 searched but $2 found'#000+
+  '10025_W_Compiling the system unit require','s the -Us switch'#000+
   '10026_F_There were $1 errors compiling module, stopping'#000+
   '10027_U_Load from $1 ($2) unit $3'#000+
   '10028_U_Recompiling $1, checksum changed for $2'#000+
-  '10029_U_Recompiling $1, sou','rce found only'#000+
-  '10030_U_Recompiling unit, static lib is older than ppufile'#000+
+  '10029_U_Recompiling $1, source found only'#000+
+  '10030_U_Recompiling unit, static lib is old','er than ppufile'#000+
   '10031_U_Recompiling unit, shared lib is older than ppufile'#000+
   '10032_U_Recompiling unit, obj and asm are older than ppufile'#000+
-  '10033_U_Recompiling unit, obj is older than as','m'#000+
+  '10033_U_Recompiling unit, obj is older than asm'#000+
   '10034_U_Parsing interface of $1'#000+
-  '10035_U_Parsing implementation of $1'#000+
+  '10035_U_Parsing implemen','tation of $1'#000+
   '10036_U_Second load for unit $1'#000+
   '10037_U_PPU Check file $1 time $2'#000+
   '10040_W_Can'#039't recompile unit $1, but found modifed include files'#000+
-  '10041_U_File $1 is newer than PPU file',' $2'#000+
-  '10042_U_Trying to use a unit which was compiled with a different FPU m'+
-  'ode'#000+
+  '10041_U_File $1 is newer than PPU file $2'#000+
+  '10042_U_Trying to use a unit which was compiled with a',' different FPU'+
+  ' mode'#000+
   '10043_U_Loading interface units from $1'#000+
   '10044_U_Loading implementation units from $1'#000+
   '10045_U_Interface CRC changed for unit $1'#000+
-  '10046_U_Implementation CRC changed ','for unit $1'#000+
+  '10046_U_Implementation CRC changed for unit $1'#000+
   '10047_U_Finished compiling unit $1'#000+
-  '10048_U_Add dependency of $1 to $2'#000+
+  '10048_U_Add',' dependency of $1 to $2'#000+
   '10049_U_No reload, is caller: $1'#000+
   '10050_U_No reload, already in second compile: $1'#000+
   '10051_U_Flag for reload: $1'#000+
   '10052_U_Forced reloading'#000+
-  '10053_U_Previous state ','of $1: $2'#000+
-  '10054_U_Already compiling $1, setting second compile'#000+
+  '10053_U_Previous state of $1: $2'#000+
+  '10054_U_Already compiling $1, setting second com','pile'#000+
   '10055_U_Loading unit $1'#000+
   '10056_U_Finished loading unit $1'#000+
   '10057_U_Registering new unit $1'#000+
   '10058_U_Re-resolving unit $1'#000+
-  '10059_U_Skipping re-resolving unit $1, still loading used u','nits'#000+
+  '10059_U_Skipping re-resolving unit $1, still loading used units'#000+
   '11000_O_$1 [options] <inputfile> [options]'#000+
-  '11001_W_Only one source file supported'#000+
+  '11001_W_On','ly one source file supported'#000+
   '11002_W_DEF file can be created only for OS/2'#000+
   '11003_E_nested response files are not supported'#000+
   '11004_F_No source file name in command line'#000+
-  '11005_N_No opti','on inside $1 config file'#000+
+  '11005_N_No option inside $1 config file'#000+
   '11006_E_Illegal parameter: $1'#000+
-  '11007_H_-? writes help pages'#000+
+  '110','07_H_-? writes help pages'#000+
   '11008_F_Too many config files nested'#000+
   '11009_F_Unable to open file $1'#000+
   '11010_D_Reading further options from $1'#000+
   '11011_W_Target is already set to: $1'#000+
-  '11012_W_Sha','red libs not supported on DOS platform, reverting to stat'+
-  'ic'#000+
+  '11012_W_Shared libs not supported on DOS platform, reverting to stati',
+  'c'#000+
   '11013_F_too many IF(N)DEFs'#000+
   '11014_F_too many ENDIFs'#000+
   '11015_F_open conditional at the end of the file'#000+
   '11016_W_Debug information generation is not supported by this executab'+
   'le'#000+
-  '11017_H_','Try recompiling with -dGDB'#000+
-  '11018_W_You are using the obsolete switch $1'#000+
+  '11017_H_Try recompiling with -dGDB'#000+
+  '11018_W_You are using the obsol','ete switch $1'#000+
   '11019_W_You are using the obsolete switch $1, please use $2'#000+
   '11020_N_Switching assembler to default source writing assembler'#000+
-  '11021_W_Assembler output selected "$1" is no','t compatible with "$2"'#000+
+  '11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+
   '11022_W_"$1" assembler use forced'#000+
-  '11026_T_Reading options from file $1'#000+
+  '1','1026_T_Reading options from file $1'#000+
   '11027_T_Reading options from environment $1'#000+
   '11028_D_Handling option "$1"'#000+
   '11029__*** press enter ***'#000+
   '11030_H_Start of reading config file $1'#000+
-  '11031_','H_End of reading config file $1'#000+
-  '11032_D_interpreting option "$1"'#000+
+  '11031_H_End of reading config file $1'#000+
+  '11032_D_interpreting optio','n "$1"'#000+
   '11036_D_interpreting firstpass option "$1"'#000+
   '11033_D_interpreting file option "$1"'#000+
   '11034_D_Reading config file "$1"'#000+
   '11035_D_found source file name "$1"'#000+
-  '11039_E_Unknown code page',#000+
+  '11039_E_Unknown code page'#000+
   '11040_F_Config file $1 is a directory'#000+
-  '11041_W_Assembler output selected "$1" cannot generate debug info, deb'+
-  'ugging disabled'#000+
+  '11041_W_Assembler o','utput selected "$1" cannot generate debug info, d'+
+  'ebugging disabled'#000+
   '11023_Free Pascal Compiler version $FPCFULLVERSION [$FPCDATE] for $FPC'+
   'CPU'#010+
-  'Copyright (c) 1993-2007 by Florian Klaemp','fl'#000+
+  'Copyright (c) 1993-2007 by Florian Klaempfl'#000+
   '11024_Free Pascal Compiler version $FPCVERSION'#010+
   #010+
-  'Compiler Date      : $FPCDATE'#010+
+  'Compile','r Date      : $FPCDATE'#010+
   'Compiler CPU Target: $FPCCPU'#010+
   #010+
   'Supported targets:'#010+
@@ -828,270 +829,270 @@ const msgtxt : array[0..000190,1..240] of char=(
   '  $INSTRUCTIONSETS'#010+
   #010+
   'Supported FPU instruction sets:'#010+
-  '  $FPUINSTRU','CTIONSETS'#010+
+  '  $FPUINSTRUCTIONSETS'#010+
   #010+
   'Supported Optimizations:'#010+
   '  $OPTIMIZATIONS'#010+
   #010+
-  'This program comes under the GNU General Public Licence'#010+
+  'This',' program comes under the GNU General Public Licence'#010+
   'For more information read COPYING.FPC'#010+
   #010+
   'Report bugs,suggestions etc to:'#010+
   '                 [email protected]'#000+
-  '11025_**0*_Put + after',' a boolean switch option to enable it, - to di'+
-  'sable it'#010+
-  '**1a_The compiler doesn'#039't delete the generated assembler file'#010+
+  '11025_**0*_Put + after a boolean switch option to enable it, - to disa'+
+  'ble it'#010+
+  '**1','a_The compiler doesn'#039't delete the generated assembler file'#010+
   '**2al_List sourcecode lines in assembler file'#010+
   '**2an_List node info in assembler file'#010+
-  '*L2ap_Use pipes instead of creating te','mporary assembler files'#010+
-  '**2ar_List register allocation/release info in assembler file'#010+
+  '*L2ap_Use pipes instead of creating temporary assembler files'#010+
+  '**2ar_List register allocation/rel','ease info in assembler file'#010+
   '**2at_List temp allocation/release info in assembler file'#010+
   '**1A<x>_Output format:'#010+
   '**2Adefault_Use default assembler'#010+
   '3*2Aas_Assemble using GNU AS'#010+
-  '3*2Anasmco','ff_COFF (Go32v2) file using Nasm'#010+
-  '3*2Anasmelf_ELF32 (Linux) file using Nasm'#010+
+  '3*2Anasmcoff_COFF (Go32v2) file using Nasm'#010+
+  '3*2Anasmelf_ELF32 (Linux)',' file using Nasm'#010+
   '3*2Anasmwin32_Win32 object file using Nasm'#010+
   '3*2Anasmwdosx_Win32/WDOSX object file using Nasm'#010+
   '3*2Awasm_Obj file using Wasm (Watcom)'#010+
   '3*2Anasmobj_Obj file using Nasm'#010+
-  '3*2','Amasm_Obj file using Masm (Microsoft)'#010+
-  '3*2Atasm_Obj file using Tasm (Borland)'#010+
+  '3*2Amasm_Obj file using Masm (Microsoft)'#010+
+  '3*2Atasm_Obj file us','ing Tasm (Borland)'#010+
   '3*2Aelf_ELF (Linux) using internal writer'#010+
   '3*2Acoff_COFF (Go32v2) using internal writer'#010+
   '3*2Apecoff_PE-COFF (Win32) using internal writer'#010+
-  '4*2Aas_Assemble using GNU A','S'#010+
+  '4*2Aas_Assemble using GNU AS'#010+
   '6*2Aas_Unix o-file using GNU AS'#010+
-  '6*2Agas_GNU Motorola assembler'#010+
+  '6*2Agas_GNU Motorola ass','embler'#010+
   '6*2Amit_MIT Syntax (old GAS)'#010+
   '6*2Amot_Standard Motorola assembler'#010+
   'A*2Aas_Assemble using GNU AS'#010+
   'P*2Aas_Assemble using GNU AS'#010+
   'S*2Aas_Assemble using GNU AS'#010+
-  '**1b_Generate browser i','nfo'#010+
+  '**1b_Generate browser info'#010+
   '**2bl_Generate local symbol info'#010+
-  '**1B_Build all modules'#010+
+  '**1B_Build all module','s'#010+
   '**1C<x>_Code generation options:'#010+
   '**2Cc<x>_Set default calling convention to <x>'#010+
   '**2CD_Create also dynamic library (not supported)'#010+
-  '**2Ce_Compilation with emulated floating point opc','odes'#010+
-  '**2Cf<x>_Select fpu instruction set to use, see fpc -i for possible va'+
-  'lues'#010+
+  '**2Ce_Compilation with emulated floating point opcodes'#010+
+  '**2Cf<x>_Select fpu instruction set to use, see fpc -','i for possible '+
+  'values'#010+
   '**2CF<x>_Minimal floating point constant precision (default, 32, 64)'#010+
   '**2Cg_Generate PIC code'#010+
   '**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
-  '**2Ci_IO-checki','ng'#010+
+  '**2Ci_IO-checking'#010+
   '**2Cn_Omit linking stage'#010+
-  '**2Co_Check overflow of integer operations'#010+
+  '**2Co_Check overflow of intege','r operations'#010+
   '**2CO_Check for possible overflow of integer operations'#010+
   '**2Cp<x>_Select instruction set, see fpc -i for possible values'#010+
   '**2CP<x>=<y>_ packing settings'#010+
-  '**3CPPACKSET=<y>_ ','<y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, '+
-  '4 and 8'#010+
+  '**3CPPACKSET=<y>_ <y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, 4 '+
+  'and 8'#010,
   '**2Cr_Range checking'#010+
   '**2CR_Verify object method call validity'#010+
   '**2Cs<n>_Set stack size to <n>'#010+
   '**2Ct_Stack checking'#010+
   '**2CX_Create also smartlinked library'#010+
-  '**1d<x>_Defines the symbol <x>',#010+
+  '**1d<x>_Defines the symbol <x>'#010+
   '**1D_Generate a DEF file'#010+
-  '**2Dd<x>_Set description to <x>'#010+
+  '**2Dd<x>_Set description to <x>'#010,
   '**2Dv<x>_Set DLL version to <x>'#010+
   '*O2Dw_PM application'#010+
   '**1e<x>_Set path to executable'#010+
   '**1E_Same as -Cn'#010+
   '**1fPIC_Same as -Cg'#010+
   '**1F<x>_Set file names and paths:'#010+
-  '**2Fa<x>[,y]_(for a program',') load units <x> and [y] before uses is p'+
-  'arsed'#010+
-  '**2Fc<x>_Set input codepage to <x>'#010+
+  '**2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is par'+
+  'sed'#010+
+  '**2Fc<x>_Se','t input codepage to <x>'#010+
   '**2FC<x>_Set RC compiler binary name to <x>'#010+
   '**2FD<x>_Set the directory where to search for compiler utilities'#010+
   '**2Fe<x>_Redirect error output to <x>'#010+
-  '**2Ff<x>_A','dd <x> to framework path (Darwin only)'#010+
-  '**2FE<x>_Set exe/unit output path to <x>'#010+
+  '**2Ff<x>_Add <x> to framework path (Darwin only)'#010+
+  '**2FE<x>_Set exe/un','it output path to <x>'#010+
   '**2Fi<x>_Add <x> to include path'#010+
   '**2Fl<x>_Add <x> to library path'#010+
   '**2FL<x>_Use <x> as dynamic linker'#010+
-  '**2Fm<x>_Load unicode conversion table from <x>.txt in the ','compiler '+
-  'dir'#010+
+  '**2Fm<x>_Load unicode conversion table from <x>.txt in the compiler di'+
+  'r'#010+
   '**2Fo<x>_Add <x> to object path'#010+
-  '**2Fr<x>_Load error message file <x>'#010+
+  '**2Fr<x>_Load',' error message file <x>'#010+
   '**2FR<x>_Set resource (.res) linker to <x>'#010+
   '**2Fu<x>_Add <x> to unit path'#010+
   '**2FU<x>_Set unit output path to <x>, overrides -FE'#010+
-  '*g1g_Generate debug information (','default format for target)'#010+
-  '*g2gc_Generate checks for pointers'#010+
+  '*g1g_Generate debug information (default format for target)'#010+
+  '*g2gc_Generate checks for point','ers'#010+
   '*g2gh_Use heaptrace unit (for memory leak/corruption debugging)'#010+
   '*g2gl_Use line info unit (show more info with backtraces)'#010+
   '*g2go<x>_Set debug information options'#010+
-  '*g3godwarfsets_ E','nable Dwarf set debug information (breaks gdb < 6.5'+
-  ')'#010+
-  '*g2gp_Preserve case in stabs symbol names'#010+
+  '*g3godwarfsets_ Enable Dwarf set debug information (breaks gdb < 6.5)'#010+
+  '*g2gp','_Preserve case in stabs symbol names'#010+
   '*g2gs_Generate stabs debug information'#010+
   '*g2gt_Trash local variables (to detect uninitialized uses)'#010+
-  '*g2gv_Generates programs traceable with valgrin','d'#010+
-  '*g2gw_Generate dwarf-2 debug information (same as -gw2)'#010+
+  '*g2gv_Generates programs traceable with valgrind'#010+
+  '*g2gw_Generate dwarf-2 debug information (same as -gw2)'#010,
   '*g2gw2_Generate dwarf-2 debug information'#010+
   '*g2gw3_Generate dwarf-3 debug information'#010+
   '**1i_Information'#010+
   '**2iD_Return compiler date'#010+
   '**2iV_Return short compiler version'#010+
-  '**2iW_Return full ','compiler version'#010+
+  '**2iW_Return full compiler version'#010+
   '**2iSO_Return compiler OS'#010+
-  '**2iSP_Return compiler host processor'#010+
+  '**2iSP_Return c','ompiler host processor'#010+
   '**2iTO_Return target OS'#010+
   '**2iTP_Return target processor'#010+
   '**1I<x>_Add <x> to include path'#010+
   '**1k<x>_Pass <x> to the linker'#010+
   '**1l_Write logo'#010+
-  '**1M<x>_Set language mode',' to <x>'#010+
+  '**1M<x>_Set language mode to <x>'#010+
   '**2Mfpc_Free Pascal dialect (default)'#010+
-  '**2Mobjfpc_FPC mode with Object Pascal support'#010+
+  '**2Mobjfpc_F','PC mode with Object Pascal support'#010+
   '**2Mdelphi_Delphi 7 compatibility mode'#010+
   '**2Mtp_TP/BP 7.0 compatibility mode'#010+
   '**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+
-  '**1n_Do not read',' the default config files'#010+
-  '**1N<x>_Node tree optimizations'#010+
+  '**1n_Do not read the default config files'#010+
+  '**1N<x>_Node tree optimizations'#010,
   '**2Nu_Unroll loops'#010+
   '**1o<x>_Change the name of the executable produced to <x>'#010+
   '**1O<x>_Optimizations:'#010+
   '**2O-_Disable optimizations'#010+
-  '**2O1_Level 1 optimizations (quick and debugger friend','ly)'#010+
-  '**2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
+  '**2O1_Level 1 optimizations (quick and debugger friendly)'#010+
+  '**2O2_Level 2 optimizations (-O1 + quick optimizations',')'#010+
   '**2O3_Level 3 optimizations (-O2 + slow optimizations)'#010+
   '**2Oa<x>=<y>_Set alignment'#010+
   '**2Oo[NO]<x>_Enable or disable optimizations, see fpc -i for possible '+
   'values'#010+
-  '**2Op<x>_Set target c','pu for optimizing, see fpc -i for possible valu'+
-  'es'#010+
-  '**2Os_Optimize for size rather than speed'#010+
+  '**2Op<x>_Set target cpu for optimizing, see fpc -i for possible values'+
+  #010+
+  '**2Os_Op','timize for size rather than speed'#010+
   '**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+
   '**1R<x>_Assembler reading style:'#010+
   '**2Rdefault_Use default assembler for target'#010+
-  '3*2Ratt_Re','ad AT&T style assembler'#010+
-  '3*2Rintel_Read Intel style assembler'#010+
+  '3*2Ratt_Read AT&T style assembler'#010+
+  '3*2Rintel_Read Intel style assembl','er'#010+
   '6*2RMOT_Read motorola style assembler'#010+
   '**1S<x>_Syntax options:'#010+
   '**2S2_Same as -Mobjfpc'#010+
   '**2Sc_Support operators like C (*=,+=,/= and -=)'#010+
   '**2Sa_Turn on assertions'#010+
-  '**2Sd_Same as -Mdelp','hi'#010+
-  '**2Se<x>_Error options. <x> is a combination of the following:'#010+
+  '**2Sd_Same as -Mdelphi'#010+
+  '**2Se<x>_Error options. <x> is a combination of the fol','lowing:'#010+
   '**3*_<n> : Compiler halts after the <n> errors (default is 1)'#010+
   '**3*_w : Compiler also halts after warnings'#010+
   '**3*_n : Compiler also halts after notes'#010+
-  '**3*_h : Compiler also halt','s after hints'#010+
-  '**2Sg_Enable LABEL and GOTO (default in -Mtp and -Mdelphi)'#010+
+  '**3*_h : Compiler also halts after hints'#010+
+  '**2Sg_Enable LABEL and GOTO (default in -Mtp',' and -Mdelphi)'#010+
   '**2Sh_Use ansistrings by default instead of shortstrings'#010+
   '**2Si_Turn on inlining of procedures/functions declared as "inline"'#010+
   '**2Sk_Load fpcylix unit'#010+
-  '**2SI<x>_Set inter','face style to <x>'#010+
-  '**3SIcom_COM compatible interface (default)'#010+
+  '**2SI<x>_Set interface style to <x>'#010+
+  '**3SIcom_COM compatible interface (defau','lt)'#010+
   '**3SIcorba_CORBA compatible interface'#010+
   '**2Sm_Support macros like C (global)'#010+
   '**2So_Same as -Mtp'#010+
   '**2Ss_Constructor name must be init (destructor must be done)'#010+
-  '**2St_Allow static key','word in objects'#010+
-  '**2Sx_Enable exception keywords (default in Delphi/ObjFPC modes)'#010+
+  '**2St_Allow static keyword in objects'#010+
+  '**2Sx_Enable exception keywords (default i','n Delphi/ObjFPC modes)'#010+
   '**1s_Do not call assembler and linker'#010+
   '**2sh_Generate script to link on host'#010+
   '**2st_Generate script to link on target'#010+
-  '**2sr_Skip register allocation phase (use w','ith -alr)'#010+
+  '**2sr_Skip register allocation phase (use with -alr)'#010+
   '**1T<x>_Target operating system:'#010+
-  '3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+
+  '3*2Temx_OS/2 vi','a EMX (including EMX/RSX extender)'#010+
   '3*2Tfreebsd_FreeBSD'#010+
   '3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
   '3*2Tlinux_Linux'#010+
   '3*2Tnetbsd_NetBSD'#010+
   '3*2Tnetware_Novell Netware Module (clib)'#010+
-  '3*2T','netwlibc_Novell Netware Module (libc)'#010+
-  '3*2Topenbsd_OpenBSD'#010+
+  '3*2Tnetwlibc_Novell Netware Module (libc)'#010+
+  '3*2Topenbsd_OpenBSD'#010,
   '3*2Tos2_OS/2 / eComStation'#010+
   '3*2Tsunos_SunOS/Solaris'#010+
   '3*2Tsymbian_Symbian OS'#010+
   '3*2Twatcom_Watcom compatible DOS extender'#010+
   '3*2Twdosx_WDOSX DOS extender'#010+
   '3*2Twin32_Windows 32 Bit'#010+
-  '3*2Twince_Wi','ndows CE'#010+
+  '3*2Twince_Windows CE'#010+
   '4*2Tlinux_Linux'#010+
   '6*2Tamiga_Commodore Amiga'#010+
-  '6*2Tatari_Atari ST/STe/TT'#010+
+  '6*2Tata','ri_Atari ST/STe/TT'#010+
   '6*2Tlinux_Linux/m68k'#010+
   '6*2Tmacos_Macintosh m68k (not supported)'#010+
   '6*2Tpalmos_PalmOS'#010+
   'A*2Tlinux_Linux'#010+
   'A*2Twince_Windows CE'#010+
   'P*2Tamiga_AmigaOS on PowerPC'#010+
-  'P*2Tdarwin_Darwin',' and Mac OS X on PowerPC'#010+
+  'P*2Tdarwin_Darwin and Mac OS X on PowerPC'#010+
   'P*2Tlinux_Linux on PowerPC'#010+
-  'P*2Tmacos_Mac OS (classic) on PowerPC'#010+
+  'P*2Tma','cos_Mac OS (classic) on PowerPC'#010+
   'P*2Tmorphos_MorphOS'#010+
   'S*2Tlinux_Linux'#010+
   '**1u<x>_Undefines the symbol <x>'#010+
   '**1U_Unit options:'#010+
   '**2Un_Do not check where the unit name matches the file name'#010+
-  '*','*2Ur_Generate release unit files (never automatically recompiled)'#010+
+  '**2Ur_Generate release unit files (never automatically reco','mpiled)'#010+
   '**2Us_Compile a system unit'#010+
   '**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
   '**2*_e : Show errors (default)       0 : Show nothing (except errors)'#010+
-  '**2*_w : ','Show warnings               u : Show unit info'#010+
-  '**2*_n : Show notes                  t : Show tried/used files'#010+
+  '**2*_w : Show warnings               u : Show unit info'#010+
+  '**2*_n : Sh','ow notes                  t : Show tried/used files'#010+
   '**2*_h : Show hints                  c : Show conditionals'#010+
   '**2*_i : Show general info           d : Show debug info'#010+
-  '**2*_l : Show ','linenumbers            r : Rhide/GCC compatibility mod'+
-  'e'#010+
-  '**2*_a : Show everything             x : Executable info (Win32 only)'#010+
+  '**2*_l : Show linenumbers            r : Rhide/GCC compatibility mode'#010+
+  '**','2*_a : Show everything             x : Executable info (Win32 only'+
+  ')'#010+
   '**2*_b : Write file names messages with full path'#010+
-  '**2*_v : Write fpcdebug.txt with     p : Write tree.log with par','se t'+
-  'ree'#010+
+  '**2*_v : Write fpcdebug.txt with     p : Write tree.log with parse tre'+
+  'e'#010+
   '**2*_    lots of debugging info'#010+
-  '3*1W<x>_Target-specific options (targets)'#010+
+  '3*1W<x>_Target-spe','cific options (targets)'#010+
   'A*1W<x>_Target-specific options (targets)'#010+
   'P*1W<x>_Target-specific options (targets)'#010+
   '3*2Wb_Create a bundle instead of a library (Darwin)'#010+
-  'P*2Wb_Create a bundle ','instead of a library (Darwin)'#010+
-  'p*2Wb_Create a bundle instead of a library (Darwin)'#010+
+  'P*2Wb_Create a bundle instead of a library (Darwin)'#010+
+  'p*2Wb_Create a bundle instea','d of a library (Darwin)'#010+
   '3*2WB_Create a relocatable image (Windows)'#010+
   'A*2WB_Create a relocatable image (Windows, Symbian)'#010+
   '3*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
-  'A*2','WC_Specify console type application (Windows)'#010+
-  'P*2WC_Specify console type application (Classic Mac OS)'#010+
+  'A*2WC_Specify console type application (Windows)'#010+
+  'P*2WC_Specif','y console type application (Classic Mac OS)'#010+
   '3*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
   'A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
-  '3*2WF_Specify ','full-screen type application (EMX, OS/2)'#010+
-  '3*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
+  '3*2WF_Specify full-screen type application (EMX, OS/2)'#010+
+  '3*2WG_Specify gra','phic type application (EMX, OS/2, Windows)'#010+
   'A*2WG_Specify graphic type application (Windows)'#010+
   'P*2WG_Specify graphic type application (Classic Mac OS)'#010+
-  '3*2WN_Do not generate relocation c','ode, needed for debugging (Windows'+
+  '3*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
+  'A*2WN_Do not generate ','relocation code, needed for debugging (Windows'+
   ')'#010+
-  'A*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
   '3*2WR_Generate relocation code (Windows)'#010+
   'A*2WR_Generate relocation code (Windows)'#010+
-  'P*2WT_Specify MPW tool type application (Classic Mac',' OS)'#010+
+  'P*2WT_Specify MPW tool type application (Classic Mac OS)'#010+
   '**1X_Executable options:'#010+
-  '**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Lin'+
-  'ux)'#010+
+  '**2Xc_Pass --shared/-dynamic',' to the linker (BeOS, Darwin, FreeBSD, L'+
+  'inux)'#010+
   '**2Xd_Do not use standard library search path (needed for cross compil'+
   'e)'#010+
   '**2Xe_Use external linker'#010+
-  '**2Xg_Create debuginfo in a separate ','file and add a debuglink sectio'+
-  'n to executable'#010+
-  '**2XD_Try to link units dynamically      (defines FPC_LINK_DYNAMIC)'#010+
+  '**2Xg_Create debuginfo in a separate file and add a debuglink section '+
+  'to executable'#010+
+  '**2XD_Try t','o link units dynamically      (defines FPC_LINK_DYNAMIC)'#010+
   '**2Xi_Use internal linker'#010+
   '**2Xm_Generate link map'#010+
   '**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
   's '#039'main'#039')'#010+
-  '**2','XP<x>_Prepend the binutils names with the prefix <x>'#010+
-  '**2Xr<x>_Set library search path to <x> (needed for cross compile) (Be'+
-  'OS, Linux)'#010+
+  '**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
+  '**2Xr','<x>_Set library search path to <x> (needed for cross compile) ('+
+  'BeOS, Linux)'#010+
   '**2XR<x>_Prepend <x> to all linker search paths (BeOS, Darwin, FreeBSD'+
   ', Linux, Mac OS, Solaris)'#010+
-  '**2Xs_Stri','p all symbols from executable'#010+
-  '**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+
+  '**2Xs_Strip all symbols from executable'#010+
+  '**2XS_Try to link units stat','ically (default, defines FPC_LINK_STATIC'+
+  ')'#010+
   '**2Xt_Link with static libraries (-static is passed to linker)'#010+
   '**2XX_Try to smartlink units             (defines FPC_LINK_SMART)'#010+
   '**1*_'#010+
-  '**1?_','Show this help'#010+
+  '**1?_Show this help'#010+
   '**1h_Shows this help without waiting'#000
 );

+ 5 - 15
compiler/ncgutil.pas

@@ -156,7 +156,7 @@ implementation
   uses
     version,
     cutils,cclasses,
-    globals,systems,verbose,
+    globals,systems,verbose,export,
     ppu,defutil,
     procinfo,paramgr,fmodule,
     regvars,dbgbase,
@@ -2013,20 +2013,10 @@ implementation
 
         current_procinfo.procdef.procendtai:=tai(list.last);
 
-        { finalisation marker for Mac OS X }
-        if (target_info.system in systems_darwin) and
-           (current_module.islibrary) and
-           (((current_module.flags and uf_finalize)<>0) or
-            (current_procinfo.procdef.proctypeoption = potype_proginit)) then
-          begin
-            if (current_procinfo.procdef.proctypeoption = potype_proginit) then
-              list.concat(tai_directive.create(asd_mod_init_func,''))
-            else
-              list.concat(tai_directive.create(asd_mod_term_func,''));
-            list.concat(tai_align.create(4));
-            list.concat(Tai_const.Createname(current_procinfo.procdef.mangledname,0));
-          end;
-
+        if (current_module.islibrary) then
+          if (current_procinfo.procdef.proctypeoption = potype_proginit) then
+            exportlib.setinitname(list,current_procinfo.procdef.mangledname);
+        
         if (current_procinfo.procdef.proctypeoption=potype_proginit) then
           begin
            if (target_info.system in (systems_darwin+[system_powerpc_macos])) and

+ 56 - 22
compiler/pexports.pas

@@ -34,7 +34,7 @@ implementation
        { common }
        cutils,
        { global }
-       globals,tokens,verbose,
+       globals,globtype,tokens,verbose,
        systems,
        ppu,fmodule,
        { symtable }
@@ -52,7 +52,6 @@ implementation
 
     procedure read_exports;
       var
-        hp        : texported_item;
         orgs,
         DefString,
         InternalProcName : string;
@@ -60,6 +59,9 @@ implementation
         pt         : tnode;
         srsym      : tsym;
         srsymtable : TSymtable;
+        hpname     : shortstring;
+        index      : longint;
+        options    : word;
 
         function IsGreater(hp1,hp2:texported_item):boolean;
         var
@@ -83,12 +85,13 @@ implementation
          InternalProcName:='';
          consume(_EXPORTS);
          repeat
-           hp:=texported_item.create;
+           hpname:='';
+           options:=0;
+           index:=0;
            if token=_ID then
              begin
                 consume_sym_orgid(srsym,srsymtable,orgs);
                 { orgpattern is still valid here }
-                hp.sym:=srsym;
                 InternalProcName:='';
                 case srsym.typ of
                   staticvarsym :
@@ -126,16 +129,16 @@ implementation
                  begin
                    pt:=comp_expr(true);
                    if pt.nodetype=ordconstn then
-                    hp.index:=tordconstnode(pt).value
+                     index:=tordconstnode(pt).value
                    else
                     begin
-                      hp.index:=0;
+                      index:=0;
                       consume(_INTCONST);
                     end;
-                   hp.options:=hp.options or eo_index;
+                   options:=options or eo_index;
                    pt.free;
                    if target_info.system in [system_i386_win32,system_i386_wdosx,system_arm_wince,system_i386_wince] then
-                    DefString:=srsym.realname+'='+InternalProcName+' @ '+tostr(hp.index)
+                    DefString:=srsym.realname+'='+InternalProcName+' @ '+tostr(index)
                    else
                     DefString:=srsym.realname+'='+InternalProcName; {Index ignored!}
                  end;
@@ -143,33 +146,64 @@ implementation
                  begin
                    pt:=comp_expr(true);
                    if pt.nodetype=stringconstn then
-                    hp.name:=stringdup(strpas(tstringconstnode(pt).value_str))
+                    hpname:=strpas(tstringconstnode(pt).value_str)
                    else
                     begin
-                      hp.name:=stringdup('');
                       consume(_CSTRING);
                     end;
-                   hp.options:=hp.options or eo_name;
+                   options:=options or eo_name;
                    pt.free;
-                   DefString:=hp.name^+'='+InternalProcName;
+                   DefString:=hpname+'='+InternalProcName;
                  end;
                 if try_to_consume(_RESIDENT) then
                  begin
-                   hp.options:=hp.options or eo_resident;
+                   options:=options or eo_resident;
                    DefString:=srsym.realname+'='+InternalProcName;{Resident ignored!}
                  end;
                 if (DefString<>'') and UseDeffileForExports then
                  DefFile.AddExport(DefString);
-                { Default to generate a name entry with the provided name }
-                if not assigned(hp.name) then
-                 begin
-                   hp.name:=stringdup(orgs);
-                   hp.options:=hp.options or eo_name;
-                 end;
-                if hp.sym.typ=procsym then
-                  exportlib.exportprocedure(hp)
+
+                if srsym.typ=procsym then
+                  begin
+                    { if no specific name or index was given, then if }
+                    { the procedure has aliases defined export those, }
+                    { otherwise export the name as it appears in the  }
+                    { export section (it doesn't make sense to export }
+                    { the generic mangled name, because the name of   }
+                    { the parent unit is used in that)                }
+                    if ((options and (eo_name or eo_index))=0) and
+                       (tprocdef(tprocsym(srsym).procdeflist[0]).aliasnames.count>1) then
+                      exportallprocsymnames(tprocsym(srsym),options)
+                    else
+                      begin
+                        { there's a name or an index -> export only one name   }
+                        { correct? Or can you export multiple names with the   }
+                        { same index? And/or should we also export the aliases }
+                        { if a name is specified? (JM)                         }
+
+                        if ((options and eo_name)=0) then
+                          { Use set mangled name in case of cdecl/cppdecl/mwpascal }
+                          { if no name specified                                   }
+                          if (tprocdef(tprocsym(srsym).procdeflist[0]).proccalloption in [pocall_cdecl,pocall_mwpascal]) then
+                            hpname:=target_info.cprefix+tprocsym(srsym).realname
+                          else if (tprocdef(tprocsym(srsym).procdeflist[0]).proccalloption in [pocall_cppdecl]) then
+                            hpname:=target_info.cprefix+tprocdef(tprocsym(srsym).procdeflist[0]).cplusplusmangledname
+                          else
+                            hpname:=orgs;
+
+                        exportprocsym(srsym,hpname,index,options);
+                      end
+                  end
                 else
-                  exportlib.exportvar(hp);
+                  begin
+                    if ((options and eo_name)=0) then
+                      { for "cvar" }
+                      if (vo_has_mangledname in tstaticvarsym(srsym).varoptions) then
+                        hpname:=srsym.mangledname
+                      else
+                        hpname:=orgs;
+                    exportvarsym(srsym,hpname,index,options);
+                  end;
              end
            else
              consume(_ID);

+ 5 - 0
compiler/pmodules.pas

@@ -1363,6 +1363,11 @@ implementation
            if force_init_final then
              finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
 
+          { the finalization routine of libraries is generic (and all libraries need to }
+          { be finalized, so they can finalize any units they use                       }
+          if (islibrary) then
+            exportlib.setfininame(current_asmdata.asmlists[al_procedures],'FPC_LIB_EXIT');
+
          { all labels must be defined before generating code }
          if Errorcount=0 then
            tstoredsymtable(current_module.localsymtable).checklabels;

+ 48 - 112
compiler/systems/t_bsd.pas

@@ -36,7 +36,7 @@ implementation
     verbose,systems,globtype,globals,
     symconst,script,
     fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,
-    import,export,link,i_bsd,
+    import,export,link,i_bsd,expunix,
     cgutils,cgbase,cgobj,cpuinfo,ogbase;
 
   type
@@ -48,11 +48,12 @@ implementation
       procedure generatelib;override;
     end;
 
-    texportlibbsd=class(texportlib)
-      procedure preparelib(const s : string);override;
-      procedure exportprocedure(hp : texported_item);override;
-      procedure exportvar(hp : texported_item);override;
-      procedure generatelib;override;
+    texportlibbsd=class(texportlibunix)
+    end;
+
+    texportlibdarwin=class(texportlibbsd)
+      procedure setinitname(list: TAsmList; const s: string); override;
+      procedure setfininame(list: TAsmList; const s: string); override;
     end;
 
     tlinkerbsd=class(texternallinker)
@@ -79,6 +80,26 @@ implementation
       end;
 
 
+{*****************************************************************************
+                             TEXPORTLIBDARWIN
+*****************************************************************************}
+
+    procedure texportlibdarwin.setinitname(list: TAsmList; const s: string);
+      begin
+        list.concat(tai_directive.create(asd_mod_init_func,''));
+        list.concat(tai_align.create(sizeof(aint)));
+        list.concat(Tai_const.Createname(s,0));
+      end;
+
+
+    procedure texportlibdarwin.setfininame(list: TAsmList; const s: string);
+      begin
+        list.concat(tai_directive.create(asd_mod_term_func,''));
+        list.concat(tai_align.create(sizeof(aint)));
+        list.concat(Tai_const.Createname(s,0));
+      end;
+
+
 {*****************************************************************************
                                TIMPORTLIBBSD
 *****************************************************************************}
@@ -96,109 +117,6 @@ implementation
       end;
 
 
-{*****************************************************************************
-                               TEXPORTLIBBSD
-*****************************************************************************}
-
-procedure texportlibbsd.preparelib(const s:string);
-begin
-end;
-
-
-procedure texportlibbsd.exportprocedure(hp : texported_item);
-var
-  hp2 : texported_item;
-begin
-  { first test the index value }
-  if (hp.options and eo_index)<>0 then
-   begin
-     Message1(parser_e_no_export_with_index_for_target,'*bsd/darwin');
-     exit;
-   end;
-  { now place in correct order }
-  hp2:=texported_item(current_module._exports.first);
-  while assigned(hp2) and
-     (hp.name^>hp2.name^) do
-    hp2:=texported_item(hp2.next);
-  { insert hp there !! }
-  if assigned(hp2) and (hp2.name^=hp.name^) then
-    begin
-      { this is not allowed !! }
-      Message1(parser_e_export_name_double,hp.name^);
-      exit;
-    end;
-  if hp2=texported_item(current_module._exports.first) then
-    current_module._exports.concat(hp)
-  else if assigned(hp2) then
-    begin
-       hp.next:=hp2;
-       hp.previous:=hp2.previous;
-       if assigned(hp2.previous) then
-         hp2.previous.next:=hp;
-       hp2.previous:=hp;
-    end
-  else
-    current_module._exports.concat(hp);
-end;
-
-
-procedure texportlibbsd.exportvar(hp : texported_item);
-begin
-  hp.is_var:=true;
-  exportprocedure(hp);
-end;
-
-
-procedure texportlibbsd.generatelib;  // straight t_linux copy for now.
-var
-  hp2 : texported_item;
-  pd  : tprocdef;
-{$ifdef x86}
-  sym : tasmsymbol;
-  r : treference;
-{$endif x86}
-begin
-  new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
-  hp2:=texported_item(current_module._exports.first);
-  while assigned(hp2) do
-   begin
-     if (not hp2.is_var) and
-        (hp2.sym.typ=procsym) then
-      begin
-        { the manglednames can already be the same when the procedure
-          is declared with cdecl }
-        pd:=tprocdef(tprocsym(hp2.sym).ProcdefList[0]);
-        if pd.mangledname<>hp2.name^ then
-         begin
-           { place jump in al_procedures }
-           current_asmdata.asmlists[al_procedures].concat(tai_align.create(target_info.alignment.procalign));
-           current_asmdata.asmlists[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
-           if (cs_create_pic in current_settings.moduleswitches) and
-             { other targets need to be checked how it works }
-             (target_info.system in [system_i386_freebsd]) then
-             begin
-{$ifdef x86}
-               sym:=current_asmdata.RefAsmSymbol(pd.mangledname);
-               reference_reset_symbol(r,sym,0);
-               if cs_create_pic in current_settings.moduleswitches then
-                 r.refaddr:=addr_pic
-               else
-                 r.refaddr:=addr_full;
-               current_asmdata.asmlists[al_procedures].concat(taicpu.op_ref(A_JMP,S_NO,r));
-{$endif x86}
-             end
-           else
-             cg.a_jmp_name(current_asmdata.asmlists[al_procedures],pd.mangledname);
-           current_asmdata.asmlists[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
-         end;
-      end
-     else
-      Message1(parser_e_no_export_of_variables_for_target,'*bsd/darwin');
-     hp2:=texported_item(hp2.next);
-   end;
-end;
-
-
 {*****************************************************************************
                                   TLINKERBSD
 *****************************************************************************}
@@ -679,6 +597,7 @@ var
   cmdstr,
   extdbgbinstr,
   extdbgcmdstr  : TCmdStr;
+  exportedsyms: text;
   success : boolean;
 begin
   MakeSharedLibrary:=false;
@@ -717,6 +636,21 @@ begin
       extdbgcmdstr:=maybequoted(current_module.sharedlibfilename^);
     end;
 
+  if (target_info.system in systems_darwin) then
+    begin
+      { exported symbols for darwin }
+      if not texportlibunix(exportlib).exportedsymnames.empty then
+        begin
+          assign(exportedsyms,outputexedir+'linksyms.fpc');
+          rewrite(exportedsyms);
+          repeat
+            writeln(exportedsyms,texportlibunix(exportlib).exportedsymnames.getfirst);
+          until texportlibunix(exportlib).exportedsymnames.empty;
+          close(exportedsyms);
+          cmdstr:=cmdstr+' -exported_symbols_list '+maybequoted(outputexedir)+'linksyms.fpc';
+        end;
+    end;
+
   if (LdSupportsNoResponseFile) and
      not(cs_link_nolink in current_settings.globalswitches) then
     begin
@@ -755,6 +689,8 @@ begin
           DeleteFile(linkscript.fn);
           linkscript.free
         end;
+      if (target_info.system in systems_darwin) then
+        DeleteFile(outputexedir+'linksyms.fpc');
     end;     
 
   MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
@@ -787,7 +723,7 @@ initialization
   RegisterTarget(system_i386_openbsd_info);
   RegisterExternalLinker(system_i386_darwin_info,TLinkerBSD);
   RegisterImport(system_i386_darwin,timportlibdarwin);
-  RegisterExport(system_i386_darwin,texportlibbsd);
+  RegisterExport(system_i386_darwin,texportlibdarwin);
   RegisterTarget(system_i386_darwin_info);
 {$endif i386}
 {$ifdef m68k}
@@ -801,7 +737,7 @@ initialization
 //  RegisterExternalLinker(system_m68k_FreeBSD_info,TLinkerBSD);
   RegisterExternalLinker(system_powerpc_darwin_info,TLinkerBSD);
   RegisterImport(system_powerpc_darwin,timportlibdarwin);
-  RegisterExport(system_powerpc_darwin,texportlibbsd);
+  RegisterExport(system_powerpc_darwin,texportlibdarwin);
   RegisterTarget(system_powerpc_darwin_info);
 
   RegisterExternalLinker(system_powerpc_netbsd_info,TLinkerBSD);
@@ -812,7 +748,7 @@ initialization
 {$ifdef powerpc64}
   RegisterExternalLinker(system_powerpc64_darwin_info,TLinkerBSD);
   RegisterImport(system_powerpc64_darwin,timportlibdarwin);
-  RegisterExport(system_powerpc64_darwin,texportlibbsd);
+  RegisterExport(system_powerpc64_darwin,texportlibdarwin);
   RegisterTarget(system_powerpc64_darwin_info);
 {$endif powerpc64}
 end.

+ 38 - 105
compiler/systems/t_linux.pas

@@ -27,19 +27,17 @@ unit t_linux;
 interface
 
   uses
+    aasmdata,
     symsym,symdef,ppu,
-    import,export,link;
+    import,export,expunix,link;
 
   type
     timportliblinux=class(timportlib)
       procedure generatelib;override;
     end;
 
-    texportliblinux=class(texportlib)
-      procedure preparelib(const s : string);override;
-      procedure exportprocedure(hp : texported_item);override;
-      procedure exportvar(hp : texported_item);override;
-      procedure generatelib;override;
+    texportliblinux=class(texportlibunix)
+      procedure setfininame(list: TAsmList; const s: string); override;
     end;
 
     tlinkerlinux=class(texternallinker)
@@ -70,7 +68,7 @@ implementation
     verbose,systems,globtype,globals,
     symconst,script,
     fmodule,
-    aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,
+    aasmbase,aasmtai,aasmcpu,cpubase,
     cgbase,cgobj,cgutils,ogbase,ncgutil,
     comprsrc,
     i_linux
@@ -97,104 +95,15 @@ implementation
                                TEXPORTLIBLINUX
 *****************************************************************************}
 
-procedure texportliblinux.preparelib(const s:string);
-begin
-end;
-
-
-procedure texportliblinux.exportprocedure(hp : texported_item);
-var
-  hp2 : texported_item;
-begin
-  { first test the index value }
-  if (hp.options and eo_index)<>0 then
-   begin
-     Message1(parser_e_no_export_with_index_for_target,'linux');
-     exit;
-   end;
-  { now place in correct order }
-  hp2:=texported_item(current_module._exports.first);
-  while assigned(hp2) and
-     (hp.name^>hp2.name^) do
-    hp2:=texported_item(hp2.next);
-  { insert hp there !! }
-  if assigned(hp2) and (hp2.name^=hp.name^) then
-    begin
-      { this is not allowed !! }
-      Message1(parser_e_export_name_double,hp.name^);
-      exit;
-    end;
-  if hp2=texported_item(current_module._exports.first) then
-    current_module._exports.concat(hp)
-  else if assigned(hp2) then
-    begin
-       hp.next:=hp2;
-       hp.previous:=hp2.previous;
-       if assigned(hp2.previous) then
-         hp2.previous.next:=hp;
-       hp2.previous:=hp;
-    end
-  else
-    current_module._exports.concat(hp);
-end;
-
-
-procedure texportliblinux.exportvar(hp : texported_item);
-begin
-  hp.is_var:=true;
-  exportprocedure(hp);
-end;
-
-
-procedure texportliblinux.generatelib;
-var
-  hp2 : texported_item;
-  pd  : tprocdef;
-{$ifdef x86}
-  sym : tasmsymbol;
-  r : treference;
-{$endif x86}
-begin
-  new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
-  hp2:=texported_item(current_module._exports.first);
-  while assigned(hp2) do
-   begin
-     if (not hp2.is_var) and
-        (hp2.sym.typ=procsym) then
+    procedure texportliblinux.setfininame(list: TAsmList; const s: string);
       begin
-        { the manglednames can already be the same when the procedure
-          is declared with cdecl }
-        pd:=tprocdef(tprocsym(hp2.sym).ProcdefList[0]);
-        if not has_alias_name(pd,hp2.name^) then
-         begin
-           { place jump in al_procedures }
-           current_asmdata.asmlists[al_procedures].concat(tai_align.create(target_info.alignment.procalign));
-           current_asmdata.asmlists[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
-           if (cs_create_pic in current_settings.moduleswitches) and
-             { other targets need to be checked how it works }
-             (target_info.system in [system_x86_64_linux,system_i386_linux]) then
-             begin
-{$ifdef x86}
-               sym:=current_asmdata.RefAsmSymbol(pd.mangledname);
-               reference_reset_symbol(r,sym,0);
-               if cs_create_pic in current_settings.moduleswitches then
-                 r.refaddr:=addr_pic
-               else
-                 r.refaddr:=addr_full;
-               current_asmdata.asmlists[al_procedures].concat(taicpu.op_ref(A_JMP,S_NO,r));
-{$endif x86}
-             end
-           else
-             cg.a_jmp_name(current_asmdata.asmlists[al_procedures],pd.mangledname);
-           current_asmdata.asmlists[al_procedures].concat(Tai_symbol_end.Createname(hp2.name^));
-         end;
-      end
-     else
-      message1(parser_e_no_export_of_variables_for_target,'linux');
-     hp2:=texported_item(hp2.next);
-   end;
-end;
-
+        { the problem with not having a .fini section is that a finalization
+          routine in regular code can get "smart" linked away -> reference it
+          just like the debug info }
+        list.concat(Tai_section.create(sec_fpc,'links',0));
+        list.concat(Tai_const.Createname(s,0));
+        inherited setfininame(list,s);
+      end;
 
 {*****************************************************************************
                                   TLINKERLINUX
@@ -240,7 +149,7 @@ begin
      if length(sysrootpath) > 0 then
        ExeCmd[1]:=ExeCmd[1]+' -T';
      ExeCmd[1]:=ExeCmd[1]+' $RES';
-     DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES -E';
+     DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
      DllCmd[2]:='strip --strip-unneeded $EXE';
      ExtDbgCmd[1]:='objcopy --only-keep-debug $EXE $DBG';
      ExtDbgCmd[2]:='objcopy --add-gnu-debuglink=$DBG $EXE';
@@ -426,6 +335,29 @@ begin
          HPath:=TCmdStrListItem(HPath.Next);
        end;
 
+      { force local symbol resolution (i.e., inside the shared }
+      { library itself) for all non-exorted symbols, otherwise }
+      { several RTL symbols of FPC-compiled shared libraries   }
+      { will be bound to those of a single shared library or   }
+      { to the main program                                    }
+      if (isdll) then
+        begin
+          add('VERSION');
+          add('{');
+          add('  {');
+          if not texportlibunix(exportlib).exportedsymnames.empty then
+            begin
+              add('    global:');
+              repeat
+                add('      '+texportlibunix(exportlib).exportedsymnames.getfirst+';');
+              until texportlibunix(exportlib).exportedsymnames.empty;
+            end;
+          add('    local:');
+          add('      *;');
+          add('  };');
+          add('}');
+        end;
+
       StartSection('INPUT(');
       { add objectfiles, start with prt0 always }
       if not (target_info.system in system_internal_sysinit) and (prtobj<>'') then
@@ -881,6 +813,7 @@ begin
   WriteResponseFile(true);
 
  { Create some replacements }
+ { note: linux does not use exportlib.initname/fininame due to the custom startup code }
   InitStr:='-init FPC_LIB_START';
   FiniStr:='-fini FPC_LIB_EXIT';
   SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename^);

+ 8 - 3
rtl/linux/i386/si_dll.inc

@@ -40,7 +40,7 @@ procedure PASCALMAIN; external name 'PASCALMAIN';
  ******************************************************************************}
 {$asmmode ATT}
 
-procedure _FPC_shared_lib_start(argc : dword;argv,envp : pointer); cdecl; public name '_start';
+procedure _FPC_shared_lib_start(argc : dword;argv,envp : pointer); cdecl; public name '_FPC_SHARED_LIB_START_LOCAL'; public name '_start';
 begin
   { we've to discuss about the use of this ;) }
   asm
@@ -58,6 +58,11 @@ begin
 end;
 
 {$ifndef VER2_0}
+
+{ this hack is needed so we can make the reference below to _FPC_shared_lib_start }
+{ local in compiler/systems/t_linux.pas                                           }
+procedure _FPC_SHARED_LIB_START_LOCAL(argc : dword;argv,envp : pointer); cdecl; external;
+
 procedure initdummy; assembler; nostackframe;
 label
   FPC_LIB_START;
@@ -68,9 +73,9 @@ asm
 //    .type FPC_LIB_START,@function
 FPC_LIB_START:
 {$ifdef FPC_PIC}
-  jmp	_FPC_shared_lib_start@PLT
+  jmp	_FPC_SHARED_LIB_START_LOCAL@PLT
 {$else FPC_PIC}
-  jmp	_FPC_shared_lib_start
+  jmp	_FPC_SHARED_LIB_START_LOCAL
 {$endif FPC_PIC}
 .text
 end;

+ 10 - 0
rtl/linux/i386/si_prc.inc

@@ -40,6 +40,9 @@ procedure PASCALMAIN; external name 'PASCALMAIN';
  ******************************************************************************}
 {$asmmode ATT}
 
+var
+  dlexitproc: pointer;
+
 procedure _FPC_proc_start; assembler; nostackframe; public name '_start';
 asm
   { First locate the start of the environment variables }
@@ -52,6 +55,8 @@ asm
   movl    %ecx,operatingsystem_parameter_argc
   movl    %ebx,operatingsystem_parameter_argv
 
+  movl    %edx, dlexitproc
+
   fninit                           { initialize fpu }
   fwait
   fldcw   Default8087CW
@@ -70,6 +75,11 @@ end;
 procedure _FPC_proc_haltproc; assembler; nostackframe; public name '_haltproc';
 asm
 .Lhaltproc:
+  movl    dlexitproc,%eax
+  testl   %eax,%eax
+  je      .Lnodlexitproc
+  call    *%eax
+.Lnodlexitproc:
   movl    syscall_nr_exit_group,%eax
 {$if sizeof(ExitCode)=2}  
   movzwl  ExitCode,%ebx

+ 19 - 0
tests/webtbs/tw6586a.pp

@@ -0,0 +1,19 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos }
+{ %norun }
+
+library tw6586a;
+{$H+}{$MODE OBJFPC}
+
+uses cmem;
+
+procedure ExportTest1(input: longint); stdcall;
+begin
+ input:= 5;
+end;
+
+exports
+  ExportTest1;
+
+begin
+end.
+

+ 22 - 0
tests/webtbs/tw6586b.pp

@@ -0,0 +1,22 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos }
+{ %needlibrary }
+
+program project1;
+
+{$mode objfpc}{$H+}
+
+uses cmem;
+
+const
+{$ifdef windows}
+  libname='tw6586a.dll';
+{$else}
+  libname='tw6586a';
+  {$linklib tw6586a}
+{$endif}
+
+procedure ExportTest1(input: longint); stdcall; external libname;
+
+begin
+  writeln('Watch for Seg fault on closing');
+end.

+ 10 - 0
tests/webtbs/tw6822a.pp

@@ -0,0 +1,10 @@
+{ %norun }
+library tw6822a;
+{$mode objfpc}{$H+}
+
+uses
+  uw6822a;
+
+begin
+  writeln('hello from library');
+end.

+ 32 - 0
tests/webtbs/tw6822b.pp

@@ -0,0 +1,32 @@
+{ %needlibrary }
+
+program loader;
+{$mode objfpc}{$H+}
+
+uses
+  dynlibs;
+var
+  h: TLibHandle;
+const
+{$ifdef unix}
+{$ifdef darwin}
+libname = './libtw6822a.dylib';
+{$else darwin}
+libname = './libtw6822a.so';
+{$endif darwin}
+{$endif unix}
+
+{$ifdef mswindows}
+libname = 'tw6822a.dll';
+{$endif mswindows}
+
+begin
+  writeln('hello from loader program');
+  h:= loadlibrary(libname);
+  if h = nilhandle then
+  begin
+    write('could not load library');
+    exit;
+  end;
+  freelibrary(h);
+end.

+ 17 - 0
tests/webtbs/tw6822c.pp

@@ -0,0 +1,17 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+uses
+  SysUtils;
+
+var
+  t: text;
+begin
+  { see uw6822a.pp }
+  assign(t,'uw6822a.txt');
+{$i-}
+  reset(t);
+{$i+}
+  if ioresult<>0 then
+    halt(1);
+  close(t);
+  erase(t);
+end.

+ 29 - 0
tests/webtbs/tw7838a.pp

@@ -0,0 +1,29 @@
+{ %norun }
+{ %target=win32,win64,wince,linux}
+
+library tw7838a;
+
+{$mode objfpc} {$h+}
+
+uses uw7838a;
+
+{$ifdef win32}
+const
+ progname = '.\prog.exe';
+{$endif}
+
+
+
+
+function dllf: longint; 
+begin
+  result:=exetest;
+  if (result<>aa) then
+    halt(1);
+end;
+
+exports dllf;
+
+begin
+
+end.

+ 52 - 0
tests/webtbs/tw7838b.pp

@@ -0,0 +1,52 @@
+{ %target=win32,win64,wince,linux}
+
+program prog;
+{$mode objfpc}
+
+uses
+ dynlibs;
+
+// this function is exported from the EXE
+function exetest: longint; {public name 'exetest';}
+begin
+  writeln('exe test');
+  result:=5;
+end;
+
+exports
+  exetest name 'exetest';
+
+const
+{$ifdef unix}
+{$ifdef darwin}
+  libname = './libtw7838a.dylib';
+{$else}
+  libname = './libtw7838a.so';
+{$endif}
+{$endif}
+{$ifdef mswindows}
+  libname = '.\tw7838a.dll';
+{$endif}
+
+var
+  dllf: function: longint;
+  lh: tlibhandle;
+
+begin
+
+  lh:= loadlibrary(libname); // load dyn.so (unix) or dyn.dll (ms windows)
+  if lh = nilhandle then
+    begin
+      writeln('dyn library returned nil handle');
+      halt(1);
+    end;
+  pointer(dllf):= getprocaddress(lh, 'dllf'); // get function from dll
+
+  // call function in dll, which calls function in exe, and then prints 
+  // a result number 5
+  if (dllf()<>5) then
+    halt(1);
+  writeln(dllf());
+  writeln('end of program');
+  freelibrary(lh);
+end.

+ 25 - 0
tests/webtbs/tw8730a.pp

@@ -0,0 +1,25 @@
+{ %norun }
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+
+{$mode delphi}
+
+{$ifdef darwin}
+{$PIC+}
+{$endif darwin}
+
+{$ifdef CPUX86_64}
+{$ifndef WINDOWS}
+{$PIC+}
+{$endif WINDOWS}
+{$endif CPUX86_64}
+
+library tw8730a;
+
+uses uw8730a;
+
+exports
+_Lib1Func;
+
+end.
+
+//= END OF FILE ===============================================================

+ 35 - 0
tests/webtbs/tw8730b.pp

@@ -0,0 +1,35 @@
+{ %norun }
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+{ %NEEDLIBRARY }
+
+{$mode delphi}
+
+{$ifdef darwin}
+{$PIC+}
+{$endif darwin}
+
+{$ifdef CPUX86_64}
+{$ifndef WINDOWS}
+{$PIC+}
+{$endif WINDOWS}
+{$endif CPUX86_64}
+
+library tw8730b;
+
+{$ifndef windows}
+  {$linklib tw8730a}
+{$endif}
+
+
+uses uw8730b;
+
+exports
+{$if defined(darwin) or defined(win32) or defined(wince)}
+Lib2Func name '_Lib2Func';
+{$else}
+Lib2Func;
+{$endif}
+
+end.
+
+//= END OF FILE ===============================================================

+ 33 - 0
tests/webtbs/tw8730c.pp

@@ -0,0 +1,33 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+{ %NEEDLIBRARY }
+
+{$mode delphi}
+program MainApp;
+
+uses
+  sysutils;
+
+const
+{$ifdef windows}
+  libname='tw8730b.dll';
+{$else}
+  libname='tw8730b';
+  {$linklib tw8730b}
+{$endif}
+
+function Lib2Func: pchar; CDecl; external libname name 'Lib2Func';
+
+var
+  error: byte;
+begin
+  error:=0;
+  WriteLn( Lib2Func );
+  if not(fileexists('tw8730a.txt')) or
+     not(fileexists('tw8730b.txt')) then
+   error:=1;
+  if (fileexists('tw8730a.txt')) then
+    deletefile('tw8730a.txt');
+  if (fileexists('tw8730b.txt')) then
+    deletefile('tw8730b.txt');
+  halt(error);
+end.

+ 36 - 0
tests/webtbs/tw8730d.pp

@@ -0,0 +1,36 @@
+{ %target=darwin,linux,freebsd,solaris,beos}
+{ %NEEDLIBRARY }
+
+{ same as tw8730c, but linking to libc so it uses different }
+{ startup code                                              }
+
+{$mode delphi}
+program MainApp;
+
+uses
+  initc, sysutils;
+
+const
+{$ifdef windows}
+  libname='tw8730b.dll';
+{$else}
+  libname='tw8730b';
+  {$linklib tw8730b}
+{$endif}
+
+function Lib2Func: pchar; CDecl; external libname name 'Lib2Func';
+
+var
+  error: byte;
+begin
+  error:=0;
+  WriteLn( Lib2Func );
+  if not(fileexists('tw8730a.txt')) or
+     not(fileexists('tw8730b.txt')) then
+   error:=1;
+  if (fileexists('tw8730a.txt')) then
+    deletefile('tw8730a.txt');
+  if (fileexists('tw8730b.txt')) then
+    deletefile('tw8730b.txt');
+  halt(error);
+end.

+ 22 - 0
tests/webtbs/tw9089a.pp

@@ -0,0 +1,22 @@
+{ %norun }
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+
+library tw9089a;
+
+{$mode objfpc}{$H+}
+
+var
+  myvar: longint; cvar;
+
+exports
+  myvar;
+
+initialization
+  Writeln('INIT');
+  myvar:=-1;
+
+finalization
+  Writeln('FINI');
+  if (myvar<>1) then
+    halt(1);
+end.

+ 45 - 0
tests/webtbs/tw9089b.pp

@@ -0,0 +1,45 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+{ %norun }
+{ %needlibrary }
+
+library tw9089b;
+
+{$mode objfpc}{$H+}
+
+const
+{$ifdef windows}
+  libname='tw9089a.dll';
+{$else}
+  libname='tw9089a';
+  {$linklib tw9089a}
+{$endif}
+
+var
+  myvar: longint; cvar; external;
+
+function Test: Integer; cdecl; export;
+begin
+  Result := 0;
+  
+  Writeln('Test');
+end;
+
+exports
+  Test;
+
+var
+  t: text;
+
+initialization
+  Writeln('INIT2');
+  if (myvar<>-1) then
+    halt(3);
+
+finalization
+  Writeln('FINI2');
+  myvar:=1;
+  { so tw9089d can check whether the finalization has run at all }
+  assign(t,'tw9089b.txt');
+  rewrite(t);
+  close(t);
+end.

+ 20 - 0
tests/webtbs/tw9089c.pp

@@ -0,0 +1,20 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+{ %needlibrary }
+
+program ptest;
+
+{$mode objfpc}{$H+}
+
+const
+{$ifdef windows}
+  libname='tw9089b.dll';
+{$else}
+  libname='tw9089a';
+  {$linklib tw9089b}
+{$endif}
+  
+function Test: Integer; cdecl; external libname;
+
+begin
+  Writeln(Test);
+end.

+ 17 - 0
tests/webtbs/tw9089d.pp

@@ -0,0 +1,17 @@
+{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos}
+uses
+  SysUtils;
+
+var
+  t: text;
+begin
+  { see tw9089b.pp }
+  assign(t,'tw9089b.txt');
+{$i-}
+  reset(t);
+{$i+}
+  if ioresult<>0 then
+    halt(1);
+  close(t);
+  erase(t);
+end.

+ 20 - 0
tests/webtbs/uw6822a.pp

@@ -0,0 +1,20 @@
+unit uw6822a;
+{$mode objfpc}{$H+}
+
+interface
+
+implementation
+
+var
+  t: text;
+
+initialization
+  writeln('Unit 1');
+  writeln('initialization');
+finalization
+  writeln('Unit 1'); // problem
+  writeln('finalization'); 
+  assign(t,'uw6822a.txt');
+  rewrite(t);
+  close(t);
+end.

+ 28 - 0
tests/webtbs/uw7838a.pp

@@ -0,0 +1,28 @@
+unit uw7838a;
+{$mode objfpc} {$h+}
+
+interface
+
+var
+  aa: longint;
+
+{$ifdef mswindows}
+function exetest: longint; external 'tw7838b.exe'; 
+{$endif}
+
+{$ifdef unix}
+function exetest: longint; external name 'exetest'; 
+{$endif}
+
+
+implementation
+
+initialization
+  writeln('libunit1 initialization');
+  aa:=5;
+
+finalization
+  
+  writeln('libunit1 finalization');
+  aa:=-5;
+end.

+ 36 - 0
tests/webtbs/uw8730a.pp

@@ -0,0 +1,36 @@
+{$mode delphi}
+
+{$ifdef darwin}
+{$PIC+}
+{$endif darwin}
+
+{$ifdef CPUX86_64}
+{$ifndef WINDOWS}
+{$PIC+}
+{$endif WINDOWS}
+{$endif CPUX86_64}
+unit uw8730a;
+
+interface
+
+function _Lib1Func: pchar;
+
+implementation
+
+function _Lib1Func: pchar;
+begin
+  result := 'result of function Lib1Func';
+end;
+
+var
+  t: text;
+
+initialization
+assign(t,'tw8730a.txt');
+rewrite(t);
+close(t);
+WriteLn( 'Init of Unit1' );
+
+end.
+
+//= END OF FILE ===============================================================

+ 46 - 0
tests/webtbs/uw8730b.pp

@@ -0,0 +1,46 @@
+{$mode delphi}
+
+{$ifdef darwin}
+{$PIC+}
+{$endif darwin}
+
+{$ifdef CPUX86_64}
+{$ifndef WINDOWS}
+{$PIC+}
+{$endif WINDOWS}
+{$endif CPUX86_64}
+unit uw8730b;
+
+interface
+
+function Lib2Func: pchar; CDecl;
+
+implementation
+
+const
+{$ifdef windows}
+  alibname='tw8730a.dll';
+{$else}
+  alibname='tw8730a';
+  {$linklib tw8730a}
+{$endif}
+
+function Lib1Func: pchar; external alibname name '_Lib1Func';
+
+function Lib2Func: pchar;
+begin
+  Writeln( Lib1Func );
+  result := 'result of function Lib2Func';
+end;
+
+var
+  t: text;
+initialization
+assign(t,'tw8730b.txt');
+rewrite(t);
+close(t);
+WriteLn( 'Init of Unit 2' );
+
+end.
+
+//= END OF FILE ===============================================================