aggas.pas 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392
  1. {
  2. Copyright (c) 1998-2006 by the Free Pascal team
  3. This unit implements the generic part of the GNU assembler
  4. (v2.8 or later) writer
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  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. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. { Base unit for writing GNU assembler output.
  19. }
  20. unit aggas;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. cclasses,
  25. globtype,globals,
  26. aasmbase,aasmtai,aasmdata,aasmcpu,
  27. assemble;
  28. type
  29. TCPUInstrWriter = class;
  30. {# This is a derived class which is used to write
  31. GAS styled assembler.
  32. }
  33. { TGNUAssembler }
  34. TGNUAssembler=class(texternalassembler)
  35. protected
  36. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual;
  37. procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  38. procedure WriteExtraHeader;virtual;
  39. procedure WriteInstruction(hp: tai);
  40. procedure WriteWeakSymbolDef(s: tasmsymbol); virtual;
  41. public
  42. function MakeCmdLine: TCmdStr; override;
  43. procedure WriteTree(p:TAsmList);override;
  44. procedure WriteAsmList;override;
  45. destructor destroy; override;
  46. private
  47. setcount: longint;
  48. procedure WriteDecodedSleb128(a: int64);
  49. procedure WriteDecodedUleb128(a: qword);
  50. function NextSetLabel: string;
  51. protected
  52. InstrWriter: TCPUInstrWriter;
  53. end;
  54. {# This is the base class for writing instructions.
  55. The WriteInstruction() method must be overriden
  56. to write a single instruction to the assembler
  57. file.
  58. }
  59. TCPUInstrWriter = class
  60. constructor create(_owner: TGNUAssembler);
  61. procedure WriteInstruction(hp : tai); virtual; abstract;
  62. protected
  63. owner: TGNUAssembler;
  64. end;
  65. { TAppleGNUAssembler }
  66. TAppleGNUAssembler=class(TGNUAssembler)
  67. protected
  68. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  69. procedure WriteWeakSymbolDef(s: tasmsymbol); override;
  70. end;
  71. TAoutGNUAssembler=class(TGNUAssembler)
  72. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  73. end;
  74. implementation
  75. uses
  76. SysUtils,
  77. cutils,cfileutl,systems,
  78. fmodule,finput,verbose,
  79. itcpugas,cpubase
  80. ;
  81. const
  82. line_length = 70;
  83. var
  84. symendcount : longint;
  85. type
  86. {$ifdef cpuextended}
  87. t80bitarray = array[0..9] of byte;
  88. {$endif cpuextended}
  89. t64bitarray = array[0..7] of byte;
  90. t32bitarray = array[0..3] of byte;
  91. {****************************************************************************}
  92. { Support routines }
  93. {****************************************************************************}
  94. function fixline(s:string):string;
  95. {
  96. return s with all leading and ending spaces and tabs removed
  97. }
  98. var
  99. i,j,k : integer;
  100. begin
  101. i:=length(s);
  102. while (i>0) and (s[i] in [#9,' ']) do
  103. dec(i);
  104. j:=1;
  105. while (j<i) and (s[j] in [#9,' ']) do
  106. inc(j);
  107. for k:=j to i do
  108. if s[k] in [#0..#31,#127..#255] then
  109. s[k]:='.';
  110. fixline:=Copy(s,j,i-j+1);
  111. end;
  112. function single2str(d : single) : string;
  113. var
  114. hs : string;
  115. begin
  116. str(d,hs);
  117. { replace space with + }
  118. if hs[1]=' ' then
  119. hs[1]:='+';
  120. single2str:='0d'+hs
  121. end;
  122. function double2str(d : double) : string;
  123. var
  124. hs : string;
  125. begin
  126. str(d,hs);
  127. { replace space with + }
  128. if hs[1]=' ' then
  129. hs[1]:='+';
  130. double2str:='0d'+hs
  131. end;
  132. function extended2str(e : extended) : string;
  133. var
  134. hs : string;
  135. begin
  136. str(e,hs);
  137. { replace space with + }
  138. if hs[1]=' ' then
  139. hs[1]:='+';
  140. extended2str:='0d'+hs
  141. end;
  142. { convert floating point values }
  143. { to correct endian }
  144. procedure swap64bitarray(var t: t64bitarray);
  145. var
  146. b: byte;
  147. begin
  148. b:= t[7];
  149. t[7] := t[0];
  150. t[0] := b;
  151. b := t[6];
  152. t[6] := t[1];
  153. t[1] := b;
  154. b:= t[5];
  155. t[5] := t[2];
  156. t[2] := b;
  157. b:= t[4];
  158. t[4] := t[3];
  159. t[3] := b;
  160. end;
  161. procedure swap32bitarray(var t: t32bitarray);
  162. var
  163. b: byte;
  164. begin
  165. b:= t[1];
  166. t[1]:= t[2];
  167. t[2]:= b;
  168. b:= t[0];
  169. t[0]:= t[3];
  170. t[3]:= b;
  171. end;
  172. const
  173. ait_const2str : array[aitconst_128bit..aitconst_darwin_dwarf_delta32] of string[20]=(
  174. #9'.fixme128'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,#9'.byte'#9,
  175. #9'.sleb128'#9,#9'.uleb128'#9,
  176. #9'.rva'#9,#9'.secrel32'#9,#9'.indirect_symbol'#9,#9'.quad'#9,#9'.long'#9
  177. );
  178. {****************************************************************************}
  179. { GNU Assembler writer }
  180. {****************************************************************************}
  181. destructor TGNUAssembler.Destroy;
  182. begin
  183. InstrWriter.free;
  184. inherited destroy;
  185. end;
  186. function TGNUAssembler.MakeCmdLine: TCmdStr;
  187. begin
  188. result := inherited MakeCmdLine;
  189. // MWE: disabled again. It generates dwarf info for the generated .s
  190. // files as well. This conflicts with the info we generate
  191. // if target_dbg.id = dbg_dwarf then
  192. // result := result + ' --gdwarf-2';
  193. end;
  194. function TGNUAssembler.NextSetLabel: string;
  195. begin
  196. inc(setcount);
  197. result := target_asm.labelprefix+'$set$'+tostr(setcount);
  198. end;
  199. function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  200. const
  201. secnames : array[TAsmSectiontype] of string[length('.objc_meth_var_types')] = ('',
  202. '.text',
  203. '.data',
  204. { why doesn't .rodata work? (FK) }
  205. { sometimes we have to create a data.rel.ro instead of .rodata, e.g. for }
  206. { vtables (and anything else containing relocations), otherwise those are }
  207. { not relocated properly on e.g. linux/ppc64. g++ generates there for a }
  208. { vtable for a class called Window: }
  209. { .section .data.rel.ro._ZTV6Window,"awG",@progbits,_ZTV6Window,comdat }
  210. { TODO: .data.ro not yet working}
  211. {$if defined(arm) or defined(powerpc)}
  212. '.rodata',
  213. {$else arm}
  214. '.data',
  215. {$endif arm}
  216. {$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
  217. '.data',
  218. {$else}
  219. '.rodata',
  220. {$endif}
  221. '.bss',
  222. '.threadvar',
  223. '.pdata',
  224. '', { stubs }
  225. '.stab',
  226. '.stabstr',
  227. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  228. '.eh_frame',
  229. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  230. '.fpc',
  231. '.toc',
  232. '.init',
  233. '.fini',
  234. '.objc_class',
  235. '.objc_meta_class',
  236. '.objc_cat_cls_meth',
  237. '.objc_cat_inst_meth',
  238. '.objc_protocol',
  239. '.objc_string_object',
  240. '.objc_cls_meth',
  241. '.objc_inst_meth',
  242. '.objc_cls_refs',
  243. '.objc_message_refs',
  244. '.objc_symbols',
  245. '.objc_category',
  246. '.objc_class_vars',
  247. '.objc_instance_vars',
  248. '.objc_module_info',
  249. '.objc_class_names',
  250. '.objc_meth_var_types',
  251. '.objc_meth_var_names',
  252. '.objc_selector_strs',
  253. '.objc_protocol_ext',
  254. '.objc_class_ext',
  255. '.objc_property',
  256. '.objc_image_info',
  257. '.objc_cstring_object',
  258. '.objc_sel_fixup'
  259. );
  260. secnames_pic : array[TAsmSectiontype] of string[length('.objc_meth_var_types')] = ('',
  261. '.text',
  262. '.data.rel',
  263. '.data.rel',
  264. '.data.rel',
  265. '.bss',
  266. '.threadvar',
  267. '.pdata',
  268. '', { stubs }
  269. '.stab',
  270. '.stabstr',
  271. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  272. '.eh_frame',
  273. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  274. '.fpc',
  275. '.toc',
  276. '.init',
  277. '.fini',
  278. '.objc_class',
  279. '.objc_meta_class',
  280. '.objc_cat_cls_meth',
  281. '.objc_cat_inst_meth',
  282. '.objc_protocol',
  283. '.objc_string_object',
  284. '.objc_cls_meth',
  285. '.objc_inst_meth',
  286. '.objc_cls_refs',
  287. '.objc_message_refs',
  288. '.objc_symbols',
  289. '.objc_category',
  290. '.objc_class_vars',
  291. '.objc_instance_vars',
  292. '.objc_module_info',
  293. '.objc_class_names',
  294. '.objc_meth_var_types',
  295. '.objc_meth_var_names',
  296. '.objc_selector_strs',
  297. '.objc_protocol_ext',
  298. '.objc_class_ext',
  299. '.objc_property',
  300. '.objc_image_info',
  301. '.objc_cstring_object',
  302. '.objc_sel_fixup'
  303. );
  304. var
  305. sep : string[3];
  306. secname : string;
  307. begin
  308. if (cs_create_pic in current_settings.moduleswitches) and
  309. not(target_info.system in systems_darwin) then
  310. secname:=secnames_pic[atype]
  311. else
  312. secname:=secnames[atype];
  313. {$ifdef m68k}
  314. { old Amiga GNU AS doesn't support .section .fpc }
  315. if (atype=sec_fpc) and (target_info.system = system_m68k_amiga) then
  316. secname:=secnames[sec_data];
  317. {$endif}
  318. if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
  319. begin
  320. result:=secname+'.'+aname;
  321. exit;
  322. end;
  323. if (atype=sec_threadvar) and
  324. (target_info.system=system_i386_win32) then
  325. secname:='.tls';
  326. { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
  327. Thus, data which normally goes into .rodata and .rodata_norel sections must
  328. end up in .data section }
  329. if (atype in [sec_rodata,sec_rodata_norel]) and
  330. (target_info.system=system_i386_go32v2) then
  331. secname:='.data';
  332. { For bss we need to set some flags that are target dependent,
  333. it is easier to disable it for smartlinking. It doesn't take up
  334. filespace }
  335. if not(target_info.system in systems_darwin) and
  336. create_smartlink_sections and
  337. (aname<>'') and
  338. (atype<>sec_toc) and
  339. { on embedded systems every byte counts, so smartlink bss too }
  340. ((atype<>sec_bss) or (target_info.system in system_embedded)) then
  341. begin
  342. case aorder of
  343. secorder_begin :
  344. sep:='.b_';
  345. secorder_end :
  346. sep:='.z_';
  347. else
  348. sep:='.n_';
  349. end;
  350. result:=secname+sep+aname
  351. end
  352. else
  353. result:=secname;
  354. end;
  355. procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  356. var
  357. s : string;
  358. begin
  359. AsmLn;
  360. case target_info.system of
  361. system_i386_OS2,
  362. system_i386_EMX,
  363. system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  364. system_m68k_linux: ;
  365. system_powerpc_darwin,
  366. system_i386_darwin,
  367. system_powerpc64_darwin,
  368. system_x86_64_darwin,
  369. system_arm_darwin:
  370. begin
  371. if (atype = sec_stub) then
  372. AsmWrite('.section ');
  373. end
  374. else
  375. AsmWrite('.section ');
  376. end;
  377. s:=sectionname(atype,aname,aorder);
  378. AsmWrite(s);
  379. case atype of
  380. sec_fpc :
  381. if aname = 'resptrs' then
  382. AsmWrite(', "a", @progbits');
  383. sec_stub :
  384. begin
  385. case target_info.system of
  386. { there are processor-independent shortcuts available }
  387. { for this, namely .symbol_stub and .picsymbol_stub, but }
  388. { they don't work and gcc doesn't use them either... }
  389. system_powerpc_darwin,
  390. system_powerpc64_darwin:
  391. if (cs_create_pic in current_settings.moduleswitches) then
  392. AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  393. else
  394. AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  395. system_i386_darwin:
  396. AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  397. system_arm_darwin:
  398. if (cs_create_pic in current_settings.moduleswitches) then
  399. AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16')
  400. else
  401. AsmWriteln('.section __TEXT,__symbol_stub4,symbol_stubs,none,12')
  402. { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
  403. else
  404. internalerror(2006031101);
  405. end;
  406. end;
  407. end;
  408. AsmLn;
  409. LastSecType:=atype;
  410. end;
  411. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  412. var
  413. i,len : longint;
  414. buf : array[0..63] of byte;
  415. begin
  416. len:=EncodeUleb128(a,buf);
  417. for i:=0 to len-1 do
  418. begin
  419. if (i > 0) then
  420. AsmWrite(',');
  421. AsmWrite(tostr(buf[i]));
  422. end;
  423. end;
  424. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  425. var
  426. i,len : longint;
  427. buf : array[0..255] of byte;
  428. begin
  429. len:=EncodeSleb128(a,buf);
  430. for i:=0 to len-1 do
  431. begin
  432. if (i > 0) then
  433. AsmWrite(',');
  434. AsmWrite(tostr(buf[i]));
  435. end;
  436. end;
  437. procedure TGNUAssembler.WriteTree(p:TAsmList);
  438. function needsObject(hp : tai_symbol) : boolean;
  439. begin
  440. needsObject :=
  441. (
  442. assigned(hp.next) and
  443. (tai(hp.next).typ in [ait_const,ait_datablock,
  444. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit])
  445. ) or
  446. (hp.sym.typ=AT_DATA);
  447. end;
  448. var
  449. ch : char;
  450. hp : tai;
  451. hp1 : tailineinfo;
  452. constdef : taiconst_type;
  453. s,t : string;
  454. i,pos,l : longint;
  455. InlineLevel : longint;
  456. last_align : longint;
  457. co : comp;
  458. sin : single;
  459. d : double;
  460. {$ifdef cpuextended}
  461. e : extended;
  462. {$endif cpuextended}
  463. do_line : boolean;
  464. sepChar : char;
  465. begin
  466. if not assigned(p) then
  467. exit;
  468. last_align := 2;
  469. InlineLevel:=0;
  470. { lineinfo is only needed for al_procedures (PFV) }
  471. do_line:=(cs_asm_source in current_settings.globalswitches) or
  472. ((cs_lineinfo in current_settings.moduleswitches)
  473. and (p=current_asmdata.asmlists[al_procedures]));
  474. hp:=tai(p.first);
  475. while assigned(hp) do
  476. begin
  477. if not(hp.typ in SkipLineInfo) then
  478. begin
  479. hp1 := hp as tailineinfo;
  480. current_filepos:=hp1.fileinfo;
  481. { no line info for inlined code }
  482. if do_line and (inlinelevel=0) then
  483. begin
  484. { load infile }
  485. if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
  486. begin
  487. infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
  488. if assigned(infile) then
  489. begin
  490. { open only if needed !! }
  491. if (cs_asm_source in current_settings.globalswitches) then
  492. infile.open;
  493. end;
  494. { avoid unnecessary reopens of the same file !! }
  495. lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
  496. { be sure to change line !! }
  497. lastfileinfo.line:=-1;
  498. end;
  499. { write source }
  500. if (cs_asm_source in current_settings.globalswitches) and
  501. assigned(infile) then
  502. begin
  503. if (infile<>lastinfile) then
  504. begin
  505. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  506. if assigned(lastinfile) then
  507. lastinfile.close;
  508. end;
  509. if (hp1.fileinfo.line<>lastfileinfo.line) and
  510. ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  511. begin
  512. if (hp1.fileinfo.line<>0) and
  513. ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
  514. AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
  515. fixline(infile.GetLineStr(hp1.fileinfo.line)));
  516. { set it to a negative value !
  517. to make that is has been read already !! PM }
  518. if (infile.linebuf^[hp1.fileinfo.line]>=0) then
  519. infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
  520. end;
  521. end;
  522. lastfileinfo:=hp1.fileinfo;
  523. lastinfile:=infile;
  524. end;
  525. end;
  526. case hp.typ of
  527. ait_comment :
  528. Begin
  529. AsmWrite(target_asm.comment);
  530. AsmWritePChar(tai_comment(hp).str);
  531. AsmLn;
  532. End;
  533. ait_regalloc :
  534. begin
  535. if (cs_asm_regalloc in current_settings.globalswitches) then
  536. begin
  537. AsmWrite(#9+target_asm.comment+'Register ');
  538. repeat
  539. AsmWrite(std_regname(Tai_regalloc(hp).reg));
  540. if (hp.next=nil) or
  541. (tai(hp.next).typ<>ait_regalloc) or
  542. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  543. break;
  544. hp:=tai(hp.next);
  545. AsmWrite(',');
  546. until false;
  547. AsmWrite(' ');
  548. AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  549. end;
  550. end;
  551. ait_tempalloc :
  552. begin
  553. if (cs_asm_tempalloc in current_settings.globalswitches) then
  554. begin
  555. {$ifdef EXTDEBUG}
  556. if assigned(tai_tempalloc(hp).problem) then
  557. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  558. tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
  559. else
  560. {$endif EXTDEBUG}
  561. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  562. tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
  563. end;
  564. end;
  565. ait_align :
  566. begin
  567. last_align := tai_align_abstract(hp).aligntype;
  568. if tai_align_abstract(hp).aligntype>1 then
  569. begin
  570. if not(target_info.system in systems_darwin) then
  571. begin
  572. AsmWrite(#9'.balign '+tostr(tai_align_abstract(hp).aligntype));
  573. if tai_align_abstract(hp).use_op then
  574. AsmWrite(','+tostr(tai_align_abstract(hp).fillop))
  575. {$ifdef x86}
  576. { force NOP as alignment op code }
  577. else if LastSecType=sec_code then
  578. AsmWrite(',0x90');
  579. {$endif x86}
  580. end
  581. else
  582. begin
  583. { darwin as only supports .align }
  584. if not ispowerof2(tai_align_abstract(hp).aligntype,i) then
  585. internalerror(2003010305);
  586. AsmWrite(#9'.align '+tostr(i));
  587. last_align := i;
  588. end;
  589. AsmLn;
  590. end;
  591. end;
  592. ait_section :
  593. begin
  594. if tai_section(hp).sectype<>sec_none then
  595. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder)
  596. else
  597. begin
  598. {$ifdef EXTDEBUG}
  599. AsmWrite(target_asm.comment);
  600. AsmWriteln(' sec_none');
  601. {$endif EXTDEBUG}
  602. end;
  603. end;
  604. ait_datablock :
  605. begin
  606. if (target_info.system in systems_darwin) then
  607. begin
  608. { On Mac OS X you can't have common symbols in a shared library
  609. since those are in the TEXT section and the text section is
  610. read-only in shared libraries (so it can be shared among different
  611. processes). The alternate code creates some kind of common symbols
  612. in the data segment.
  613. }
  614. if tai_datablock(hp).is_global then
  615. begin
  616. asmwrite('.globl ');
  617. asmwriteln(tai_datablock(hp).sym.name);
  618. asmwriteln('.data');
  619. asmwrite('.zerofill __DATA, __common, ');
  620. asmwrite(tai_datablock(hp).sym.name);
  621. asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  622. if not(LastSecType in [sec_data,sec_none]) then
  623. writesection(LastSecType,'',secorder_default);
  624. end
  625. else
  626. begin
  627. asmwrite(#9'.lcomm'#9);
  628. asmwrite(tai_datablock(hp).sym.name);
  629. asmwrite(','+tostr(tai_datablock(hp).size));
  630. asmwrite(','+tostr(last_align));
  631. asmln;
  632. end;
  633. end
  634. else
  635. begin
  636. {$ifdef USE_COMM_IN_BSS}
  637. if writingpackages then
  638. begin
  639. { The .comm is required for COMMON symbols. These are used
  640. in the shared library loading. All the symbols declared in
  641. the .so file need to resolve to the data allocated in the main
  642. program (PFV) }
  643. if tai_datablock(hp).is_global then
  644. begin
  645. asmwrite(#9'.comm'#9);
  646. asmwrite(tai_datablock(hp).sym.name);
  647. asmwrite(','+tostr(tai_datablock(hp).size));
  648. asmwrite(','+tostr(last_align));
  649. asmln;
  650. end
  651. else
  652. begin
  653. asmwrite(#9'.lcomm'#9);
  654. asmwrite(tai_datablock(hp).sym.name);
  655. asmwrite(','+tostr(tai_datablock(hp).size));
  656. asmwrite(','+tostr(last_align));
  657. asmln;
  658. end
  659. end
  660. else
  661. {$endif USE_COMM_IN_BSS}
  662. begin
  663. if Tai_datablock(hp).is_global then
  664. begin
  665. asmwrite(#9'.globl ');
  666. asmwriteln(Tai_datablock(hp).sym.name);
  667. end;
  668. if (target_info.system <> system_arm_linux) then
  669. sepChar := '@'
  670. else
  671. sepChar := '%';
  672. if (tf_needs_symbol_type in target_info.flags) then
  673. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  674. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  675. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  676. asmwrite(Tai_datablock(hp).sym.name);
  677. asmwriteln(':');
  678. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  679. end;
  680. end;
  681. end;
  682. ait_const:
  683. begin
  684. constdef:=tai_const(hp).consttype;
  685. case constdef of
  686. {$ifndef cpu64bitaddr}
  687. aitconst_128bit :
  688. begin
  689. internalerror(200404291);
  690. end;
  691. aitconst_64bit :
  692. begin
  693. if assigned(tai_const(hp).sym) then
  694. internalerror(200404292);
  695. AsmWrite(ait_const2str[aitconst_32bit]);
  696. if target_info.endian = endian_little then
  697. begin
  698. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  699. AsmWrite(',');
  700. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  701. end
  702. else
  703. begin
  704. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  705. AsmWrite(',');
  706. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  707. end;
  708. AsmLn;
  709. end;
  710. {$endif cpu64bitaddr}
  711. aitconst_uleb128bit,
  712. aitconst_sleb128bit,
  713. {$ifdef cpu64bitaddr}
  714. aitconst_128bit,
  715. aitconst_64bit,
  716. {$endif cpu64bitaddr}
  717. aitconst_32bit,
  718. aitconst_16bit,
  719. aitconst_8bit,
  720. aitconst_rva_symbol,
  721. aitconst_secrel32_symbol,
  722. aitconst_indirect_symbol,
  723. aitconst_darwin_dwarf_delta32,
  724. aitconst_darwin_dwarf_delta64:
  725. begin
  726. if (target_info.system in systems_darwin) and
  727. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  728. begin
  729. AsmWrite(ait_const2str[aitconst_8bit]);
  730. case tai_const(hp).consttype of
  731. aitconst_uleb128bit:
  732. WriteDecodedUleb128(qword(tai_const(hp).value));
  733. aitconst_sleb128bit:
  734. WriteDecodedSleb128(int64(tai_const(hp).value));
  735. end
  736. end
  737. else
  738. begin
  739. AsmWrite(ait_const2str[constdef]);
  740. l:=0;
  741. t := '';
  742. repeat
  743. if assigned(tai_const(hp).sym) then
  744. begin
  745. if assigned(tai_const(hp).endsym) then
  746. begin
  747. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  748. begin
  749. s := NextSetLabel;
  750. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  751. end
  752. else
  753. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  754. end
  755. else
  756. s:=tai_const(hp).sym.name;
  757. if tai_const(hp).value<>0 then
  758. s:=s+tostr_with_plus(tai_const(hp).value);
  759. end
  760. else
  761. s:=tostr(tai_const(hp).value);
  762. AsmWrite(s);
  763. inc(l,length(s));
  764. { Values with symbols are written on a single line to improve
  765. reading of the .s file (PFV) }
  766. if assigned(tai_const(hp).sym) or
  767. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  768. (l>line_length) or
  769. (hp.next=nil) or
  770. (tai(hp.next).typ<>ait_const) or
  771. (tai_const(hp.next).consttype<>constdef) or
  772. assigned(tai_const(hp.next).sym) then
  773. break;
  774. hp:=tai(hp.next);
  775. AsmWrite(',');
  776. until false;
  777. if (t <> '') then
  778. begin
  779. AsmLn;
  780. AsmWrite(t);
  781. end;
  782. end;
  783. AsmLn;
  784. end;
  785. else
  786. internalerror(200704251);
  787. end;
  788. end;
  789. { the "and defined(FPC_HAS_TYPE_EXTENDED)" isn't optimal but currently the only solution
  790. it prevents proper cross compilation to i386 though
  791. }
  792. {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
  793. ait_real_80bit :
  794. begin
  795. if do_line then
  796. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_real_80bit(hp).value));
  797. { Make sure e is a extended type, bestreal could be
  798. a different type (bestreal) !! (PFV) }
  799. e:=tai_real_80bit(hp).value;
  800. AsmWrite(#9'.byte'#9);
  801. for i:=0 to 9 do
  802. begin
  803. if i<>0 then
  804. AsmWrite(',');
  805. AsmWrite(tostr(t80bitarray(e)[i]));
  806. end;
  807. AsmLn;
  808. end;
  809. {$endif cpuextended}
  810. ait_real_64bit :
  811. begin
  812. if do_line then
  813. AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
  814. d:=tai_real_64bit(hp).value;
  815. { swap the values to correct endian if required }
  816. if source_info.endian <> target_info.endian then
  817. swap64bitarray(t64bitarray(d));
  818. AsmWrite(#9'.byte'#9);
  819. {$ifdef arm}
  820. if tai_real_64bit(hp).formatoptions=fo_hiloswapped then
  821. begin
  822. for i:=4 to 7 do
  823. begin
  824. if i<>4 then
  825. AsmWrite(',');
  826. AsmWrite(tostr(t64bitarray(d)[i]));
  827. end;
  828. for i:=0 to 3 do
  829. begin
  830. AsmWrite(',');
  831. AsmWrite(tostr(t64bitarray(d)[i]));
  832. end;
  833. end
  834. else
  835. {$endif arm}
  836. begin
  837. for i:=0 to 7 do
  838. begin
  839. if i<>0 then
  840. AsmWrite(',');
  841. AsmWrite(tostr(t64bitarray(d)[i]));
  842. end;
  843. end;
  844. AsmLn;
  845. end;
  846. ait_real_32bit :
  847. begin
  848. if do_line then
  849. AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
  850. sin:=tai_real_32bit(hp).value;
  851. { swap the values to correct endian if required }
  852. if source_info.endian <> target_info.endian then
  853. swap32bitarray(t32bitarray(sin));
  854. AsmWrite(#9'.byte'#9);
  855. for i:=0 to 3 do
  856. begin
  857. if i<>0 then
  858. AsmWrite(',');
  859. AsmWrite(tostr(t32bitarray(sin)[i]));
  860. end;
  861. AsmLn;
  862. end;
  863. ait_comp_64bit :
  864. begin
  865. if do_line then
  866. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_comp_64bit(hp).value));
  867. AsmWrite(#9'.byte'#9);
  868. co:=comp(tai_comp_64bit(hp).value);
  869. { swap the values to correct endian if required }
  870. if source_info.endian <> target_info.endian then
  871. swap64bitarray(t64bitarray(co));
  872. for i:=0 to 7 do
  873. begin
  874. if i<>0 then
  875. AsmWrite(',');
  876. AsmWrite(tostr(t64bitarray(co)[i]));
  877. end;
  878. AsmLn;
  879. end;
  880. ait_string :
  881. begin
  882. pos:=0;
  883. for i:=1 to tai_string(hp).len do
  884. begin
  885. if pos=0 then
  886. begin
  887. AsmWrite(#9'.ascii'#9'"');
  888. pos:=20;
  889. end;
  890. ch:=tai_string(hp).str[i-1];
  891. case ch of
  892. #0, {This can't be done by range, because a bug in FPC}
  893. #1..#31,
  894. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  895. '"' : s:='\"';
  896. '\' : s:='\\';
  897. else
  898. s:=ch;
  899. end;
  900. AsmWrite(s);
  901. inc(pos,length(s));
  902. if (pos>line_length) or (i=tai_string(hp).len) then
  903. begin
  904. AsmWriteLn('"');
  905. pos:=0;
  906. end;
  907. end;
  908. end;
  909. ait_label :
  910. begin
  911. if (tai_label(hp).labsym.is_used) then
  912. begin
  913. if tai_label(hp).labsym.bind=AB_GLOBAL then
  914. begin
  915. AsmWrite('.globl'#9);
  916. AsmWriteLn(tai_label(hp).labsym.name);
  917. end;
  918. AsmWrite(tai_label(hp).labsym.name);
  919. AsmWriteLn(':');
  920. end;
  921. end;
  922. ait_symbol :
  923. begin
  924. if (target_info.system = system_powerpc64_linux) and
  925. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  926. begin
  927. AsmWriteLn('.globl _mcount');
  928. end;
  929. if tai_symbol(hp).is_global then
  930. begin
  931. AsmWrite('.globl'#9);
  932. AsmWriteLn(tai_symbol(hp).sym.name);
  933. end;
  934. if (target_info.system = system_powerpc64_linux) and
  935. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  936. begin
  937. AsmWriteLn('.section ".opd", "aw"');
  938. AsmWriteLn('.align 3');
  939. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  940. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  941. AsmWriteLn('.previous');
  942. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  943. if (tai_symbol(hp).is_global) then
  944. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  945. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  946. { the dotted name is the name of the actual function entry }
  947. AsmWrite('.');
  948. end
  949. else
  950. begin
  951. if (target_info.system <> system_arm_linux) then
  952. sepChar := '@'
  953. else
  954. sepChar := '#';
  955. if (tf_needs_symbol_type in target_info.flags) then
  956. begin
  957. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  958. if (needsObject(tai_symbol(hp))) then
  959. AsmWriteLn(',' + sepChar + 'object')
  960. else
  961. AsmWriteLn(',' + sepChar + 'function');
  962. end;
  963. end;
  964. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  965. end;
  966. {$ifdef arm}
  967. ait_thumb_func:
  968. begin
  969. AsmWriteLn(#9'.thumb_func');
  970. end;
  971. {$endif arm}
  972. ait_symbol_end :
  973. begin
  974. if tf_needs_symbol_size in target_info.flags then
  975. begin
  976. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  977. inc(symendcount);
  978. AsmWriteLn(s+':');
  979. AsmWrite(#9'.size'#9);
  980. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  981. AsmWrite('.');
  982. AsmWrite(tai_symbol_end(hp).sym.name);
  983. AsmWrite(', '+s+' - ');
  984. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  985. AsmWrite('.');
  986. AsmWriteLn(tai_symbol_end(hp).sym.name);
  987. end;
  988. end;
  989. ait_instruction :
  990. begin
  991. WriteInstruction(hp);
  992. end;
  993. ait_stab :
  994. begin
  995. if assigned(tai_stab(hp).str) then
  996. begin
  997. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  998. AsmWritePChar(tai_stab(hp).str);
  999. AsmLn;
  1000. end;
  1001. end;
  1002. ait_force_line,
  1003. ait_function_name : ;
  1004. ait_cutobject :
  1005. begin
  1006. if SmartAsm then
  1007. begin
  1008. { only reset buffer if nothing has changed }
  1009. if AsmSize=AsmStartSize then
  1010. AsmClear
  1011. else
  1012. begin
  1013. AsmClose;
  1014. DoAssemble;
  1015. AsmCreate(tai_cutobject(hp).place);
  1016. end;
  1017. { avoid empty files }
  1018. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1019. begin
  1020. if tai(hp.next).typ=ait_section then
  1021. LastSecType:=tai_section(hp.next).sectype;
  1022. hp:=tai(hp.next);
  1023. end;
  1024. if LastSecType<>sec_none then
  1025. WriteSection(LastSecType,'',secorder_default);
  1026. AsmStartSize:=AsmSize;
  1027. end;
  1028. end;
  1029. ait_marker :
  1030. if tai_marker(hp).kind=mark_InlineStart then
  1031. inc(InlineLevel)
  1032. else if tai_marker(hp).kind=mark_InlineEnd then
  1033. dec(InlineLevel);
  1034. ait_directive :
  1035. begin
  1036. AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
  1037. if assigned(tai_directive(hp).name) then
  1038. AsmWrite(tai_directive(hp).name^);
  1039. AsmLn;
  1040. end;
  1041. else
  1042. internalerror(2006012201);
  1043. end;
  1044. hp:=tai(hp.next);
  1045. end;
  1046. end;
  1047. procedure TGNUAssembler.WriteExtraHeader;
  1048. begin
  1049. end;
  1050. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1051. begin
  1052. InstrWriter.WriteInstruction(hp);
  1053. end;
  1054. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1055. begin
  1056. AsmWriteLn(#9'.weak '+s.name);
  1057. end;
  1058. procedure TGNUAssembler.WriteAsmList;
  1059. var
  1060. n : string;
  1061. hal : tasmlisttype;
  1062. i: longint;
  1063. begin
  1064. {$ifdef EXTDEBUG}
  1065. if assigned(current_module.mainsource) then
  1066. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource^);
  1067. {$endif}
  1068. if assigned(current_module.mainsource) then
  1069. n:=ExtractFileName(current_module.mainsource^)
  1070. else
  1071. n:=InputFileName;
  1072. { gcc does not add it either for Darwin (and AIX). Grep for
  1073. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1074. }
  1075. if not(target_info.system in systems_darwin) then
  1076. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1077. WriteExtraHeader;
  1078. AsmStartSize:=AsmSize;
  1079. symendcount:=0;
  1080. for hal:=low(TasmlistType) to high(TasmlistType) do
  1081. begin
  1082. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1083. writetree(current_asmdata.asmlists[hal]);
  1084. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1085. end;
  1086. { add weak symbol markers }
  1087. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1088. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1089. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1090. if create_smartlink_sections and
  1091. (target_info.system in systems_darwin) then
  1092. AsmWriteLn(#9'.subsections_via_symbols');
  1093. { "no executable stack" marker for Linux }
  1094. if (target_info.system in system_linux) and
  1095. not(cs_executable_stack in current_settings.moduleswitches) then
  1096. begin
  1097. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1098. end;
  1099. AsmLn;
  1100. {$ifdef EXTDEBUG}
  1101. if assigned(current_module.mainsource) then
  1102. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource^);
  1103. {$endif EXTDEBUG}
  1104. end;
  1105. {****************************************************************************}
  1106. { Apple/GNU Assembler writer }
  1107. {****************************************************************************}
  1108. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1109. begin
  1110. if (target_info.system in systems_darwin) then
  1111. case atype of
  1112. sec_bss:
  1113. { all bss (lcomm) symbols are automatically put in the right }
  1114. { place by using the lcomm assembler directive }
  1115. atype := sec_none;
  1116. sec_debug_frame,
  1117. sec_eh_frame:
  1118. begin
  1119. result := '.section __DWARF,__debug_info,regular,debug';
  1120. exit;
  1121. end;
  1122. sec_debug_line:
  1123. begin
  1124. result := '.section __DWARF,__debug_line,regular,debug';
  1125. exit;
  1126. end;
  1127. sec_debug_info:
  1128. begin
  1129. result := '.section __DWARF,__debug_info,regular,debug';
  1130. exit;
  1131. end;
  1132. sec_debug_abbrev:
  1133. begin
  1134. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1135. exit;
  1136. end;
  1137. sec_rodata:
  1138. begin
  1139. result := '.const_data';
  1140. exit;
  1141. end;
  1142. sec_rodata_norel:
  1143. begin
  1144. result := '.const';
  1145. exit;
  1146. end;
  1147. sec_fpc:
  1148. begin
  1149. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1150. exit;
  1151. end;
  1152. sec_code:
  1153. begin
  1154. if (aname='fpc_geteipasebx') or
  1155. (aname='fpc_geteipasecx') then
  1156. begin
  1157. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1158. #10'.private_extern '+aname;
  1159. exit;
  1160. end;
  1161. end;
  1162. sec_objc_protocol_ext:
  1163. begin
  1164. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1165. exit;
  1166. end;
  1167. sec_objc_class_ext:
  1168. begin
  1169. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1170. exit;
  1171. end;
  1172. sec_objc_property:
  1173. begin
  1174. result:='.section __OBJC, __property, regular, no_dead_strip';
  1175. exit;
  1176. end;
  1177. sec_objc_image_info:
  1178. begin
  1179. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1180. exit;
  1181. end;
  1182. sec_objc_cstring_object:
  1183. begin
  1184. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1185. exit;
  1186. end;
  1187. sec_objc_sel_fixup:
  1188. begin
  1189. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1190. exit;
  1191. end;
  1192. end;
  1193. result := inherited sectionname(atype,aname,aorder);
  1194. end;
  1195. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1196. begin
  1197. AsmWriteLn(#9'.weak_reference '+s.name);
  1198. end;
  1199. {****************************************************************************}
  1200. { a.out/GNU Assembler writer }
  1201. {****************************************************************************}
  1202. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1203. const
  1204. (* Translation table - replace unsupported section types with basic ones. *)
  1205. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1206. sec_none,
  1207. sec_code,
  1208. sec_data,
  1209. sec_data (* sec_rodata *),
  1210. sec_data (* sec_rodata_norel *),
  1211. sec_bss,
  1212. sec_data (* sec_threadvar *),
  1213. { used for wince exception handling }
  1214. sec_code (* sec_pdata *),
  1215. { used for darwin import stubs }
  1216. sec_code (* sec_stub *),
  1217. { stabs }
  1218. sec_stab,sec_stabstr,
  1219. { win32 }
  1220. sec_data (* sec_idata2 *),
  1221. sec_data (* sec_idata4 *),
  1222. sec_data (* sec_idata5 *),
  1223. sec_data (* sec_idata6 *),
  1224. sec_data (* sec_idata7 *),
  1225. sec_data (* sec_edata *),
  1226. { C++ exception handling unwinding (uses dwarf) }
  1227. sec_eh_frame,
  1228. { dwarf }
  1229. sec_debug_frame,
  1230. sec_debug_info,
  1231. sec_debug_line,
  1232. sec_debug_abbrev,
  1233. { ELF resources (+ references to stabs debug information sections) }
  1234. sec_code (* sec_fpc *),
  1235. { Table of contents section }
  1236. sec_code (* sec_toc *),
  1237. sec_code (* sec_init *),
  1238. sec_code (* sec_fini *),
  1239. sec_none (* sec_objc_class *),
  1240. sec_none (* sec_objc_meta_class *),
  1241. sec_none (* sec_objc_cat_cls_meth *),
  1242. sec_none (* sec_objc_cat_inst_meth *),
  1243. sec_none (* sec_objc_protocol *),
  1244. sec_none (* sec_objc_string_object *),
  1245. sec_none (* sec_objc_cls_meth *),
  1246. sec_none (* sec_objc_inst_meth *),
  1247. sec_none (* sec_objc_cls_refs *),
  1248. sec_none (* sec_objc_message_refs *),
  1249. sec_none (* sec_objc_symbols *),
  1250. sec_none (* sec_objc_category *),
  1251. sec_none (* sec_objc_class_vars *),
  1252. sec_none (* sec_objc_instance_vars *),
  1253. sec_none (* sec_objc_module_info *),
  1254. sec_none (* sec_objc_class_names *),
  1255. sec_none (* sec_objc_meth_var_types *),
  1256. sec_none (* sec_objc_meth_var_names *),
  1257. sec_none (* sec_objc_selector_strs *),
  1258. sec_none (* sec_objc_protocol_ext *),
  1259. sec_none (* sec_objc_class_ext *),
  1260. sec_none (* sec_objc_property *),
  1261. sec_none (* sec_objc_image_info *),
  1262. sec_none (* sec_objc_cstring_object *),
  1263. sec_none (* sec_objc_sel_fixup *)
  1264. );
  1265. begin
  1266. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1267. end;
  1268. {****************************************************************************}
  1269. { Abstract Instruction Writer }
  1270. {****************************************************************************}
  1271. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1272. begin
  1273. inherited create;
  1274. owner := _owner;
  1275. end;
  1276. end.