initc.pp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Pierre Muller
  4. Code to generate execution of all c functions
  5. with constructors attributes
  6. Based on .ctor and .dtor sections of DJGPP gcc compiler
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$IFNDEF FPC_DOTTEDUNITS}
  14. unit InitC;
  15. {$ENDIF FPC_DOTTEDUNITS}
  16. interface
  17. implementation
  18. { we need to include dpmiexcp unit
  19. to avoid getting troubles with _exit found both
  20. in libc and in v2prt0.as PM }
  21. {$IFDEF FPC_DOTTEDUNITS}
  22. uses
  23. DOSApi.dpmiexcp;
  24. {$ELSE FPC_DOTTEDUNITS}
  25. uses
  26. dpmiexcp;
  27. {$ENDIF FPC_DOTTEDUNITS}
  28. type
  29. simple_proc = procedure;
  30. var
  31. first_ctor : longint;external name 'djgpp_first_ctor';
  32. ctor : array [0..maxlongint div sizeof(simple_proc)-1] of simple_proc;external name 'djgpp_first_ctor';
  33. last_ctor : longint;external name 'djgpp_last_ctor';
  34. first_dtor : longint;external name 'djgpp_first_dtor';
  35. dtor : array [0..maxlongint div sizeof(simple_proc)-1] of simple_proc;external name 'djgpp_first_dtor';
  36. last_dtor : longint;external name 'djgpp_last_dtor';
  37. bss_count : longint;external name '___bss_count';
  38. const
  39. save_exit : pointer = nil;
  40. procedure run_c_constructors;
  41. const
  42. already_done : longint = -1;
  43. var
  44. f : simple_proc;
  45. i,nb : longint;
  46. begin
  47. if already_done=bss_count then
  48. exit;
  49. already_done:=bss_count;
  50. f:=ctor[0];
  51. nb:=((cardinal(@last_ctor)-cardinal(@first_ctor)) div sizeof(pointer));
  52. for i:=1 to nb do
  53. begin
  54. f();
  55. f:=ctor[i];
  56. end;
  57. end;
  58. procedure run_c_destructors;
  59. const
  60. already_done : longint = -1;
  61. var
  62. f : simple_proc;
  63. i,nb : longint;
  64. begin
  65. exitproc:=save_exit;
  66. if already_done=bss_count then
  67. exit;
  68. already_done:=bss_count;
  69. f:=dtor[0];
  70. nb:=((cardinal(@last_dtor)-cardinal(@first_dtor)) div sizeof(pointer));
  71. for i:=1 to nb do
  72. begin
  73. f();
  74. f:=dtor[i];
  75. end;
  76. end;
  77. begin
  78. run_c_constructors;
  79. If cardinal(@first_dtor)<>cardinal(@last_dtor) then
  80. begin
  81. { can exitproc be allready non nil here ?
  82. you have to make really weird things to achieve
  83. that be lets suppose it is possible !! (PM) }
  84. save_exit:=exitproc;
  85. exitproc:=@run_c_destructors;
  86. end;
  87. end.