os2_targ.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Daniel Mantione
  4. Portions Copyright (c) 1992-96 Eberhard Mattes
  5. Unit to write out import libraries and def files for OS/2
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. {
  20. A lot of code in this unit has been ported from C to Pascal from the
  21. emximp utility, part of the EMX development system. Emximp is copyrighted
  22. by Eberhard Mattes. Note: Eberhard doesn't know much about the Pascal
  23. port, please send questions to Daniel Mantione
  24. <[email protected]>.
  25. }
  26. unit os2_targ;
  27. interface
  28. uses import;
  29. type
  30. pimportlibos2=^timportlibos2;
  31. timportlibos2=object(timportlib)
  32. procedure preparelib(const s:string);virtual;
  33. procedure importprocedure(const func,module:string;index:longint;const name:string);virtual;
  34. procedure generatelib;virtual;
  35. end;
  36. {***************************************************************************}
  37. {***************************************************************************}
  38. implementation
  39. uses
  40. {$ifdef Delphi}
  41. dmisc,
  42. {$else Delphi}
  43. dos,
  44. {$endif Delphi}
  45. globtype,strings,comphook,
  46. globals,link,files;
  47. const profile_flag:boolean=false;
  48. const n_ext = 1;
  49. n_abs = 2;
  50. n_text = 4;
  51. n_data = 6;
  52. n_bss = 8;
  53. n_imp1 = $68;
  54. n_imp2 = $6a;
  55. type reloc=packed record {This is the layout of a relocation table
  56. entry.}
  57. address:longint; {Fixup location}
  58. remaining:longint;
  59. {Meaning of bits for remaining:
  60. 0..23: Symbol number or segment
  61. 24: Self-relative fixup if non-zero
  62. 25..26: Fixup size (0: 1 byte, 1: 2, 2: 4 bytes)
  63. 27: Reference to symbol or segment
  64. 28..31 Not used}
  65. end;
  66. nlist=packed record {This is the layout of a symbol table entry.}
  67. strofs:longint; {Offset in string table}
  68. typ:byte; {Type of the symbol}
  69. other:byte; {Other information}
  70. desc:word; {More information}
  71. value:longint; {Value (address)}
  72. end;
  73. a_out_header=packed record
  74. magic:word; {Magic word, must be $0107}
  75. machtype:byte; {Machine type}
  76. flags:byte; {Flags}
  77. text_size:longint; {Length of text, in bytes}
  78. data_size:longint; {Length of initialized data, in bytes}
  79. bss_size:longint; {Length of uninitialized data, in bytes}
  80. sym_size:longint; {Length of symbol table, in bytes}
  81. entry:longint; {Start address (entry point)}
  82. trsize:longint; {Length of relocation info for text, bytes}
  83. drsize:longint; {Length of relocation info for data, bytes}
  84. end;
  85. ar_hdr=packed record
  86. ar_name:array[0..15] of char;
  87. ar_date:array[0..11] of char;
  88. ar_uid:array[0..5] of char;
  89. ar_gid:array[0..5] of char;
  90. ar_mode:array[0..7] of char;
  91. ar_size:array[0..9] of char;
  92. ar_fmag:array[0..1] of char;
  93. end;
  94. var aout_str_size:longint;
  95. aout_str_tab:array[0..2047] of byte;
  96. aout_sym_count:longint;
  97. aout_sym_tab:array[0..5] of nlist;
  98. aout_text:array[0..63] of byte;
  99. aout_text_size:longint;
  100. aout_treloc_tab:array[0..1] of reloc;
  101. aout_treloc_count:longint;
  102. aout_size:longint;
  103. seq_no:longint;
  104. ar_member_size:longint;
  105. out_file:file;
  106. procedure write_ar(const name:string;size:longint);
  107. var ar:ar_hdr;
  108. time:datetime;
  109. dummy:word;
  110. numtime:longint;
  111. tmp:string[19];
  112. begin
  113. ar_member_size:=size;
  114. fillchar(ar.ar_name,sizeof(ar.ar_name),' ');
  115. move(name[1],ar.ar_name,length(name));
  116. getdate(time.year,time.month,time.day,dummy);
  117. gettime(time.hour,time.min,time.sec,dummy);
  118. packtime(time,numtime);
  119. str(numtime,tmp);
  120. fillchar(ar.ar_date,sizeof(ar.ar_date),' ');
  121. move(tmp[1],ar.ar_date,length(tmp));
  122. ar.ar_uid:='0 ';
  123. ar.ar_gid:='0 ';
  124. ar.ar_mode:='100666'#0#0;
  125. str(size,tmp);
  126. fillchar(ar.ar_size,sizeof(ar.ar_size),' ');
  127. move(tmp[1],ar.ar_size,length(tmp));
  128. ar.ar_fmag:='`'#10;
  129. blockwrite(out_file,ar,sizeof(ar));
  130. end;
  131. procedure finish_ar;
  132. var a:byte;
  133. begin
  134. a:=0;
  135. if odd(ar_member_size) then
  136. blockwrite(out_file,a,1);
  137. end;
  138. procedure aout_init;
  139. begin
  140. aout_str_size:=sizeof(longint);
  141. aout_sym_count:=0;
  142. aout_text_size:=0;
  143. aout_treloc_count:=0;
  144. end;
  145. function aout_sym(const name:string;typ,other:byte;desc:word;
  146. value:longint):longint;
  147. begin
  148. if aout_str_size+length(name)+1>sizeof(aout_str_tab) then
  149. Do_halt($da);
  150. if aout_sym_count>=sizeof(aout_sym_tab) div sizeof(aout_sym_tab[0]) then
  151. Do_halt($da);
  152. aout_sym_tab[aout_sym_count].strofs:=aout_str_size;
  153. aout_sym_tab[aout_sym_count].typ:=typ;
  154. aout_sym_tab[aout_sym_count].other:=other;
  155. aout_sym_tab[aout_sym_count].desc:=desc;
  156. aout_sym_tab[aout_sym_count].value:=value;
  157. strPcopy(@aout_str_tab[aout_str_size],name);
  158. aout_str_size:=aout_str_size+length(name)+1;
  159. aout_sym:=aout_sym_count;
  160. inc(aout_sym_count);
  161. end;
  162. procedure aout_text_byte(b:byte);
  163. begin
  164. if aout_text_size>=sizeof(aout_text) then
  165. Do_halt($da);
  166. aout_text[aout_text_size]:=b;
  167. inc(aout_text_size);
  168. end;
  169. procedure aout_text_dword(d:longint);
  170. type li_ar=array[0..3] of byte;
  171. begin
  172. aout_text_byte(li_ar(d)[0]);
  173. aout_text_byte(li_ar(d)[1]);
  174. aout_text_byte(li_ar(d)[2]);
  175. aout_text_byte(li_ar(d)[3]);
  176. end;
  177. procedure aout_treloc(address,symbolnum,pcrel,len,ext:longint);
  178. begin
  179. if aout_treloc_count>=sizeof(aout_treloc_tab) div sizeof(reloc) then
  180. Do_halt($da);
  181. aout_treloc_tab[aout_treloc_count].address:=address;
  182. aout_treloc_tab[aout_treloc_count].remaining:=symbolnum+pcrel shl 24+
  183. len shl 25+ext shl 27;
  184. inc(aout_treloc_count);
  185. end;
  186. procedure aout_finish;
  187. begin
  188. while (aout_text_size and 3)<>0 do
  189. aout_text_byte ($90);
  190. aout_size:=sizeof(a_out_header)+aout_text_size+aout_treloc_count*
  191. sizeof(reloc)+aout_sym_count*sizeof(aout_sym_tab[0])+aout_str_size;
  192. end;
  193. procedure aout_write;
  194. var ao:a_out_header;
  195. begin
  196. ao.magic:=$0107;
  197. ao.machtype:=0;
  198. ao.flags:=0;
  199. ao.text_size:=aout_text_size;
  200. ao.data_size:=0;
  201. ao.bss_size:=0;
  202. ao.sym_size:=aout_sym_count*sizeof(aout_sym_tab[0]);
  203. ao.entry:=0;
  204. ao.trsize:=aout_treloc_count*sizeof(reloc);
  205. ao.drsize:=0;
  206. blockwrite(out_file,ao,sizeof(ao));
  207. blockwrite(out_file,aout_text,aout_text_size);
  208. blockwrite(out_file,aout_treloc_tab,sizeof(reloc)*aout_treloc_count);
  209. blockwrite(out_file,aout_sym_tab,sizeof(aout_sym_tab[0])*aout_sym_count);
  210. longint((@aout_str_tab)^):=aout_str_size;
  211. blockwrite(out_file,aout_str_tab,aout_str_size);
  212. end;
  213. procedure timportlibos2.preparelib(const s:string);
  214. {This code triggers a lot of bugs in the compiler.
  215. const armag='!<arch>'#10;
  216. ar_magic:array[1..length(armag)] of char=armag;}
  217. const ar_magic:array[1..8] of char='!<arch>'#10;
  218. begin
  219. seq_no:=1;
  220. if not (cs_smartlink in aktmoduleswitches) then
  221. current_module^.linkotherstaticlibs.insert(s,link_allways);
  222. assign(out_file,current_module^.path^+s+'.ao2');
  223. rewrite(out_file,1);
  224. blockwrite(out_file,ar_magic,sizeof(ar_magic));
  225. end;
  226. procedure timportlibos2.importprocedure(const func,module:string;index:longint;const name:string);
  227. {func = Name of function to import.
  228. module = Name of DLL to import from.
  229. index = Index of function in DLL. Use 0 to import by name.
  230. name = Name of function in DLL. Ignored when index=0;}
  231. var tmp1,tmp2,tmp3:string;
  232. sym_mcount,sym_entry,sym_import:longint;
  233. fixup_mcount,fixup_import:longint;
  234. begin
  235. aout_init;
  236. tmp2:=func;
  237. if profile_flag and not (copy(func,1,4)='_16_') then
  238. begin
  239. sym_entry:=aout_sym(func,n_text+n_ext,0,0,aout_text_size);
  240. sym_mcount:=aout_sym('__mcount',n_ext,0,0,0);
  241. {Use, say, "_$U_DosRead" for "DosRead" to import the
  242. non-profiled function.}
  243. tmp2:='__$U_'+func;
  244. sym_import:=aout_sym(tmp2,n_ext,0,0,0);
  245. aout_text_byte($55); {push ebp}
  246. aout_text_byte($89); {mov ebp, esp}
  247. aout_text_byte($e5);
  248. aout_text_byte($e8); {call _mcount}
  249. fixup_mcount:=aout_text_size;
  250. aout_text_dword(0-(aout_text_size+4));
  251. aout_text_byte($5d); {pop ebp}
  252. aout_text_byte($e9); {jmp _$U_DosRead}
  253. fixup_import:=aout_text_size;
  254. aout_text_dword(0-(aout_text_size+4));
  255. aout_treloc(fixup_mcount,sym_mcount,1,2,1);
  256. aout_treloc (fixup_import, sym_import,1,2,1);
  257. end;
  258. str(seq_no,tmp1);
  259. tmp1:='IMPORT#'+tmp1;
  260. if name='' then
  261. begin
  262. str(index,tmp3);
  263. tmp3:=func+'='+module+'.'+tmp3;
  264. end
  265. else
  266. tmp3:=func+'='+module+'.'+name;
  267. aout_sym(tmp2,n_imp1+n_ext,0,0,0);
  268. aout_sym(tmp3,n_imp2+n_ext,0,0,0);
  269. aout_finish;
  270. write_ar(tmp1,aout_size);
  271. aout_write;
  272. finish_ar;
  273. inc(seq_no);
  274. end;
  275. procedure timportlibos2.generatelib;
  276. begin
  277. close(out_file);
  278. end;
  279. end.
  280. {
  281. $Log$
  282. Revision 1.10 1999-09-07 15:05:19 pierre
  283. * use do_halt instead of runerror
  284. Revision 1.9 1999/07/18 10:19:58 florian
  285. * made it compilable with Dlephi 4 again
  286. + fixed problem with large stack allocations on win32
  287. Revision 1.8 1999/07/03 00:29:55 peter
  288. * new link writing to the ppu, one .ppu is needed for all link types,
  289. static (.o) is now always created also when smartlinking is used
  290. Revision 1.7 1999/05/04 21:44:52 florian
  291. * changes to compile it with Delphi 4.0
  292. Revision 1.6 1998/12/11 00:03:25 peter
  293. + globtype,tokens,version unit splitted from globals
  294. Revision 1.5 1998/10/16 14:20:53 daniel
  295. * Faster keyword scanning.
  296. * Import library and smartlink library in one file.
  297. Revision 1.4 1998/06/17 14:10:14 peter
  298. * small os2 fixes
  299. * fixed interdependent units with newppu (remake3 under linux works now)
  300. Revision 1.3 1998/06/04 23:51:48 peter
  301. * m68k compiles
  302. + .def file creation moved to gendef.pas so it could also be used
  303. for win32
  304. Revision 1.2 1998/05/04 17:54:27 peter
  305. + smartlinking works (only case jumptable left todo)
  306. * redesign of systems.pas to support assemblers and linkers
  307. + Unitname is now also in the PPU-file, increased version to 14
  308. }