aggas.pas 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554
  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'.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('__DATA, __datacoal_nt,coalesced')] = ('',
  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. '__DATA,__nl_symbol_ptr',
  226. '__DATA,__la_symbol_ptr',
  227. '__DATA,__mod_init_func',
  228. '__DATA,__mod_term_func',
  229. '.stab',
  230. '.stabstr',
  231. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  232. '.eh_frame',
  233. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  234. '.fpc',
  235. '.toc',
  236. '.init',
  237. '.fini',
  238. '.objc_class',
  239. '.objc_meta_class',
  240. '.objc_cat_cls_meth',
  241. '.objc_cat_inst_meth',
  242. '.objc_protocol',
  243. '.objc_string_object',
  244. '.objc_cls_meth',
  245. '.objc_inst_meth',
  246. '.objc_cls_refs',
  247. '.objc_message_refs',
  248. '.objc_symbols',
  249. '.objc_category',
  250. '.objc_class_vars',
  251. '.objc_instance_vars',
  252. '.objc_module_info',
  253. '.objc_class_names',
  254. '.objc_meth_var_types',
  255. '.objc_meth_var_names',
  256. '.objc_selector_strs',
  257. '.objc_protocol_ext',
  258. '.objc_class_ext',
  259. '.objc_property',
  260. '.objc_image_info',
  261. '.objc_cstring_object',
  262. '.objc_sel_fixup',
  263. '__DATA,__objc_data',
  264. '__DATA,__objc_const',
  265. '.objc_superrefs',
  266. '__DATA, __datacoal_nt,coalesced',
  267. '.objc_classlist',
  268. '.objc_nlclasslist',
  269. '.objc_catlist',
  270. '.obcj_nlcatlist',
  271. '.objc_protolist'
  272. );
  273. secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
  274. '.text',
  275. '.data.rel',
  276. '.data.rel',
  277. '.data.rel',
  278. '.bss',
  279. '.threadvar',
  280. '.pdata',
  281. '', { stubs }
  282. '__DATA,__nl_symbol_ptr',
  283. '__DATA,__la_symbol_ptr',
  284. '__DATA,__mod_init_func',
  285. '__DATA,__mod_term_func',
  286. '.stab',
  287. '.stabstr',
  288. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  289. '.eh_frame',
  290. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  291. '.fpc',
  292. '.toc',
  293. '.init',
  294. '.fini',
  295. '.objc_class',
  296. '.objc_meta_class',
  297. '.objc_cat_cls_meth',
  298. '.objc_cat_inst_meth',
  299. '.objc_protocol',
  300. '.objc_string_object',
  301. '.objc_cls_meth',
  302. '.objc_inst_meth',
  303. '.objc_cls_refs',
  304. '.objc_message_refs',
  305. '.objc_symbols',
  306. '.objc_category',
  307. '.objc_class_vars',
  308. '.objc_instance_vars',
  309. '.objc_module_info',
  310. '.objc_class_names',
  311. '.objc_meth_var_types',
  312. '.objc_meth_var_names',
  313. '.objc_selector_strs',
  314. '.objc_protocol_ext',
  315. '.objc_class_ext',
  316. '.objc_property',
  317. '.objc_image_info',
  318. '.objc_cstring_object',
  319. '.objc_sel_fixup',
  320. '__DATA, __objc_data',
  321. '__DATA, __objc_const',
  322. '.objc_superrefs',
  323. '__DATA, __datacoal_nt,coalesced',
  324. '.objc_classlist',
  325. '.objc_nlclasslist',
  326. '.objc_catlist',
  327. '.obcj_nlcatlist',
  328. '.objc_protolist'
  329. );
  330. var
  331. sep : string[3];
  332. secname : string;
  333. begin
  334. if (cs_create_pic in current_settings.moduleswitches) and
  335. not(target_info.system in systems_darwin) then
  336. secname:=secnames_pic[atype]
  337. else
  338. secname:=secnames[atype];
  339. {$ifdef m68k}
  340. { old Amiga GNU AS doesn't support .section .fpc }
  341. if (atype=sec_fpc) and (target_info.system = system_m68k_amiga) then
  342. secname:=secnames[sec_data];
  343. {$endif}
  344. if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
  345. begin
  346. result:=secname+'.'+aname;
  347. exit;
  348. end;
  349. if (atype=sec_threadvar) and
  350. (target_info.system=system_i386_win32) then
  351. secname:='.tls';
  352. { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
  353. Thus, data which normally goes into .rodata and .rodata_norel sections must
  354. end up in .data section }
  355. if (atype in [sec_rodata,sec_rodata_norel]) and
  356. (target_info.system=system_i386_go32v2) then
  357. secname:='.data';
  358. { For bss we need to set some flags that are target dependent,
  359. it is easier to disable it for smartlinking. It doesn't take up
  360. filespace }
  361. if not(target_info.system in systems_darwin) and
  362. create_smartlink_sections and
  363. (aname<>'') and
  364. (atype<>sec_toc) and
  365. { on embedded systems every byte counts, so smartlink bss too }
  366. ((atype<>sec_bss) or (target_info.system in systems_embedded)) then
  367. begin
  368. case aorder of
  369. secorder_begin :
  370. sep:='.b_';
  371. secorder_end :
  372. sep:='.z_';
  373. else
  374. sep:='.n_';
  375. end;
  376. result:=secname+sep+aname
  377. end
  378. else
  379. result:=secname;
  380. end;
  381. procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  382. var
  383. s : string;
  384. begin
  385. AsmLn;
  386. case target_info.system of
  387. system_i386_OS2,
  388. system_i386_EMX,
  389. system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  390. system_m68k_linux: ;
  391. system_powerpc_darwin,
  392. system_i386_darwin,
  393. system_powerpc64_darwin,
  394. system_x86_64_darwin,
  395. system_arm_darwin:
  396. begin
  397. if (atype in [sec_stub,sec_objc_data,sec_objc_const,sec_data_coalesced]) then
  398. AsmWrite('.section ');
  399. end
  400. else
  401. AsmWrite('.section ');
  402. end;
  403. s:=sectionname(atype,aname,aorder);
  404. AsmWrite(s);
  405. case atype of
  406. sec_fpc :
  407. if aname = 'resptrs' then
  408. AsmWrite(', "a", @progbits');
  409. sec_stub :
  410. begin
  411. case target_info.system of
  412. { there are processor-independent shortcuts available }
  413. { for this, namely .symbol_stub and .picsymbol_stub, but }
  414. { they don't work and gcc doesn't use them either... }
  415. system_powerpc_darwin,
  416. system_powerpc64_darwin:
  417. if (cs_create_pic in current_settings.moduleswitches) then
  418. AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  419. else
  420. AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  421. system_i386_darwin:
  422. AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  423. system_arm_darwin:
  424. if (cs_create_pic in current_settings.moduleswitches) then
  425. AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16')
  426. else
  427. AsmWriteln('.section __TEXT,__symbol_stub4,symbol_stubs,none,12')
  428. { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
  429. else
  430. internalerror(2006031101);
  431. end;
  432. end;
  433. end;
  434. AsmLn;
  435. LastSecType:=atype;
  436. end;
  437. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  438. var
  439. i,len : longint;
  440. buf : array[0..63] of byte;
  441. begin
  442. len:=EncodeUleb128(a,buf);
  443. for i:=0 to len-1 do
  444. begin
  445. if (i > 0) then
  446. AsmWrite(',');
  447. AsmWrite(tostr(buf[i]));
  448. end;
  449. end;
  450. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  451. var
  452. i,len : longint;
  453. buf : array[0..255] of byte;
  454. begin
  455. len:=EncodeSleb128(a,buf);
  456. for i:=0 to len-1 do
  457. begin
  458. if (i > 0) then
  459. AsmWrite(',');
  460. AsmWrite(tostr(buf[i]));
  461. end;
  462. end;
  463. procedure TGNUAssembler.WriteTree(p:TAsmList);
  464. function needsObject(hp : tai_symbol) : boolean;
  465. begin
  466. needsObject :=
  467. (
  468. assigned(hp.next) and
  469. (tai(hp.next).typ in [ait_const,ait_datablock,
  470. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit])
  471. ) or
  472. (hp.sym.typ=AT_DATA);
  473. end;
  474. procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint);
  475. var
  476. i: longint;
  477. begin
  478. last_align:=alignment;
  479. if alignment>1 then
  480. begin
  481. if not(target_info.system in systems_darwin) then
  482. begin
  483. AsmWrite(#9'.balign '+tostr(alignment));
  484. if use_op then
  485. AsmWrite(','+tostr(fillop))
  486. {$ifdef x86}
  487. { force NOP as alignment op code }
  488. else if LastSecType=sec_code then
  489. AsmWrite(',0x90');
  490. {$endif x86}
  491. end
  492. else
  493. begin
  494. { darwin as only supports .align }
  495. if not ispowerof2(alignment,i) then
  496. internalerror(2003010305);
  497. AsmWrite(#9'.align '+tostr(i));
  498. last_align:=i;
  499. end;
  500. AsmLn;
  501. end;
  502. end;
  503. var
  504. ch : char;
  505. hp : tai;
  506. hp1 : tailineinfo;
  507. constdef : taiconst_type;
  508. s,t : string;
  509. i,pos,l : longint;
  510. InlineLevel : longint;
  511. last_align : longint;
  512. co : comp;
  513. sin : single;
  514. d : double;
  515. {$ifdef cpuextended}
  516. e : extended;
  517. {$endif cpuextended}
  518. do_line : boolean;
  519. sepChar : char;
  520. begin
  521. if not assigned(p) then
  522. exit;
  523. last_align := 2;
  524. InlineLevel:=0;
  525. { lineinfo is only needed for al_procedures (PFV) }
  526. do_line:=(cs_asm_source in current_settings.globalswitches) or
  527. ((cs_lineinfo in current_settings.moduleswitches)
  528. and (p=current_asmdata.asmlists[al_procedures]));
  529. hp:=tai(p.first);
  530. while assigned(hp) do
  531. begin
  532. prefetch(pointer(hp.next)^);
  533. if not(hp.typ in SkipLineInfo) then
  534. begin
  535. hp1 := hp as tailineinfo;
  536. current_filepos:=hp1.fileinfo;
  537. { no line info for inlined code }
  538. if do_line and (inlinelevel=0) then
  539. begin
  540. { load infile }
  541. if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
  542. begin
  543. infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
  544. if assigned(infile) then
  545. begin
  546. { open only if needed !! }
  547. if (cs_asm_source in current_settings.globalswitches) then
  548. infile.open;
  549. end;
  550. { avoid unnecessary reopens of the same file !! }
  551. lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
  552. { be sure to change line !! }
  553. lastfileinfo.line:=-1;
  554. end;
  555. { write source }
  556. if (cs_asm_source in current_settings.globalswitches) and
  557. assigned(infile) then
  558. begin
  559. if (infile<>lastinfile) then
  560. begin
  561. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  562. if assigned(lastinfile) then
  563. lastinfile.close;
  564. end;
  565. if (hp1.fileinfo.line<>lastfileinfo.line) and
  566. ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  567. begin
  568. if (hp1.fileinfo.line<>0) and
  569. ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
  570. AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
  571. fixline(infile.GetLineStr(hp1.fileinfo.line)));
  572. { set it to a negative value !
  573. to make that is has been read already !! PM }
  574. if (infile.linebuf^[hp1.fileinfo.line]>=0) then
  575. infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
  576. end;
  577. end;
  578. lastfileinfo:=hp1.fileinfo;
  579. lastinfile:=infile;
  580. end;
  581. end;
  582. case hp.typ of
  583. ait_comment :
  584. Begin
  585. AsmWrite(target_asm.comment);
  586. AsmWritePChar(tai_comment(hp).str);
  587. AsmLn;
  588. End;
  589. ait_regalloc :
  590. begin
  591. if (cs_asm_regalloc in current_settings.globalswitches) then
  592. begin
  593. AsmWrite(#9+target_asm.comment+'Register ');
  594. repeat
  595. AsmWrite(std_regname(Tai_regalloc(hp).reg));
  596. if (hp.next=nil) or
  597. (tai(hp.next).typ<>ait_regalloc) or
  598. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  599. break;
  600. hp:=tai(hp.next);
  601. AsmWrite(',');
  602. until false;
  603. AsmWrite(' ');
  604. AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  605. end;
  606. end;
  607. ait_tempalloc :
  608. begin
  609. if (cs_asm_tempalloc in current_settings.globalswitches) then
  610. begin
  611. {$ifdef EXTDEBUG}
  612. if assigned(tai_tempalloc(hp).problem) then
  613. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  614. tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
  615. else
  616. {$endif EXTDEBUG}
  617. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  618. tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
  619. end;
  620. end;
  621. ait_align :
  622. begin
  623. doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align);
  624. end;
  625. ait_section :
  626. begin
  627. if tai_section(hp).sectype<>sec_none then
  628. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder)
  629. else
  630. begin
  631. {$ifdef EXTDEBUG}
  632. AsmWrite(target_asm.comment);
  633. AsmWriteln(' sec_none');
  634. {$endif EXTDEBUG}
  635. end;
  636. end;
  637. ait_datablock :
  638. begin
  639. if (target_info.system in systems_darwin) then
  640. begin
  641. { On Mac OS X you can't have common symbols in a shared library
  642. since those are in the TEXT section and the text section is
  643. read-only in shared libraries (so it can be shared among different
  644. processes). The alternate code creates some kind of common symbols
  645. in the data segment.
  646. }
  647. if tai_datablock(hp).is_global then
  648. begin
  649. asmwrite('.globl ');
  650. asmwriteln(tai_datablock(hp).sym.name);
  651. asmwriteln('.data');
  652. asmwrite('.zerofill __DATA, __common, ');
  653. asmwrite(tai_datablock(hp).sym.name);
  654. asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  655. if not(LastSecType in [sec_data,sec_none]) then
  656. writesection(LastSecType,'',secorder_default);
  657. end
  658. else
  659. begin
  660. asmwrite(#9'.lcomm'#9);
  661. asmwrite(tai_datablock(hp).sym.name);
  662. asmwrite(','+tostr(tai_datablock(hp).size));
  663. asmwrite(','+tostr(last_align));
  664. asmln;
  665. end;
  666. end
  667. else
  668. begin
  669. {$ifdef USE_COMM_IN_BSS}
  670. if writingpackages then
  671. begin
  672. { The .comm is required for COMMON symbols. These are used
  673. in the shared library loading. All the symbols declared in
  674. the .so file need to resolve to the data allocated in the main
  675. program (PFV) }
  676. if tai_datablock(hp).is_global then
  677. begin
  678. asmwrite(#9'.comm'#9);
  679. asmwrite(tai_datablock(hp).sym.name);
  680. asmwrite(','+tostr(tai_datablock(hp).size));
  681. asmwrite(','+tostr(last_align));
  682. asmln;
  683. end
  684. else
  685. begin
  686. asmwrite(#9'.lcomm'#9);
  687. asmwrite(tai_datablock(hp).sym.name);
  688. asmwrite(','+tostr(tai_datablock(hp).size));
  689. asmwrite(','+tostr(last_align));
  690. asmln;
  691. end
  692. end
  693. else
  694. {$endif USE_COMM_IN_BSS}
  695. begin
  696. if Tai_datablock(hp).is_global then
  697. begin
  698. asmwrite(#9'.globl ');
  699. asmwriteln(Tai_datablock(hp).sym.name);
  700. end;
  701. if (target_info.system <> system_arm_linux) then
  702. sepChar := '@'
  703. else
  704. sepChar := '%';
  705. if (tf_needs_symbol_type in target_info.flags) then
  706. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  707. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  708. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  709. asmwrite(Tai_datablock(hp).sym.name);
  710. asmwriteln(':');
  711. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  712. end;
  713. end;
  714. end;
  715. ait_const:
  716. begin
  717. constdef:=tai_const(hp).consttype;
  718. case constdef of
  719. {$ifndef cpu64bitaddr}
  720. aitconst_128bit :
  721. begin
  722. internalerror(200404291);
  723. end;
  724. aitconst_64bit :
  725. begin
  726. if assigned(tai_const(hp).sym) then
  727. internalerror(200404292);
  728. AsmWrite(ait_const2str[aitconst_32bit]);
  729. if target_info.endian = endian_little then
  730. begin
  731. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  732. AsmWrite(',');
  733. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  734. end
  735. else
  736. begin
  737. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  738. AsmWrite(',');
  739. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  740. end;
  741. AsmLn;
  742. end;
  743. {$endif cpu64bitaddr}
  744. aitconst_uleb128bit,
  745. aitconst_sleb128bit,
  746. {$ifdef cpu64bitaddr}
  747. aitconst_128bit,
  748. aitconst_64bit,
  749. {$endif cpu64bitaddr}
  750. aitconst_32bit,
  751. aitconst_16bit,
  752. aitconst_8bit,
  753. aitconst_rva_symbol,
  754. aitconst_secrel32_symbol,
  755. aitconst_darwin_dwarf_delta32,
  756. aitconst_darwin_dwarf_delta64:
  757. begin
  758. if (target_info.system in systems_darwin) and
  759. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  760. begin
  761. AsmWrite(ait_const2str[aitconst_8bit]);
  762. case tai_const(hp).consttype of
  763. aitconst_uleb128bit:
  764. WriteDecodedUleb128(qword(tai_const(hp).value));
  765. aitconst_sleb128bit:
  766. WriteDecodedSleb128(int64(tai_const(hp).value));
  767. end
  768. end
  769. else
  770. begin
  771. AsmWrite(ait_const2str[constdef]);
  772. l:=0;
  773. t := '';
  774. repeat
  775. if assigned(tai_const(hp).sym) then
  776. begin
  777. if assigned(tai_const(hp).endsym) then
  778. begin
  779. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  780. begin
  781. s := NextSetLabel;
  782. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  783. end
  784. else
  785. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  786. end
  787. else
  788. s:=tai_const(hp).sym.name;
  789. if tai_const(hp).value<>0 then
  790. s:=s+tostr_with_plus(tai_const(hp).value);
  791. end
  792. else
  793. {$ifdef cpu64bitaddr}
  794. s:=tostr(tai_const(hp).value);
  795. {$else cpu64bitaddr}
  796. { 64 bit constants are already handled above in this case }
  797. s:=tostr(longint(tai_const(hp).value));
  798. {$endif cpu64bitaddr}
  799. AsmWrite(s);
  800. inc(l,length(s));
  801. { Values with symbols are written on a single line to improve
  802. reading of the .s file (PFV) }
  803. if assigned(tai_const(hp).sym) or
  804. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  805. (l>line_length) or
  806. (hp.next=nil) or
  807. (tai(hp.next).typ<>ait_const) or
  808. (tai_const(hp.next).consttype<>constdef) or
  809. assigned(tai_const(hp.next).sym) then
  810. break;
  811. hp:=tai(hp.next);
  812. AsmWrite(',');
  813. until false;
  814. if (t <> '') then
  815. begin
  816. AsmLn;
  817. AsmWrite(t);
  818. end;
  819. end;
  820. AsmLn;
  821. end;
  822. else
  823. internalerror(200704251);
  824. end;
  825. end;
  826. { the "and defined(FPC_HAS_TYPE_EXTENDED)" isn't optimal but currently the only solution
  827. it prevents proper cross compilation to i386 though
  828. }
  829. {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
  830. ait_real_80bit :
  831. begin
  832. if do_line then
  833. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_real_80bit(hp).value));
  834. { Make sure e is a extended type, bestreal could be
  835. a different type (bestreal) !! (PFV) }
  836. e:=tai_real_80bit(hp).value;
  837. AsmWrite(#9'.byte'#9);
  838. for i:=0 to 9 do
  839. begin
  840. if i<>0 then
  841. AsmWrite(',');
  842. AsmWrite(tostr(t80bitarray(e)[i]));
  843. end;
  844. for i:=11 to tai_real_80bit(hp).savesize do
  845. AsmWrite(',0');
  846. AsmLn;
  847. end;
  848. {$endif cpuextended}
  849. ait_real_64bit :
  850. begin
  851. if do_line then
  852. AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
  853. d:=tai_real_64bit(hp).value;
  854. { swap the values to correct endian if required }
  855. if source_info.endian <> target_info.endian then
  856. swap64bitarray(t64bitarray(d));
  857. AsmWrite(#9'.byte'#9);
  858. {$ifdef arm}
  859. if tai_real_64bit(hp).formatoptions=fo_hiloswapped then
  860. begin
  861. for i:=4 to 7 do
  862. begin
  863. if i<>4 then
  864. AsmWrite(',');
  865. AsmWrite(tostr(t64bitarray(d)[i]));
  866. end;
  867. for i:=0 to 3 do
  868. begin
  869. AsmWrite(',');
  870. AsmWrite(tostr(t64bitarray(d)[i]));
  871. end;
  872. end
  873. else
  874. {$endif arm}
  875. begin
  876. for i:=0 to 7 do
  877. begin
  878. if i<>0 then
  879. AsmWrite(',');
  880. AsmWrite(tostr(t64bitarray(d)[i]));
  881. end;
  882. end;
  883. AsmLn;
  884. end;
  885. ait_real_32bit :
  886. begin
  887. if do_line then
  888. AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
  889. sin:=tai_real_32bit(hp).value;
  890. { swap the values to correct endian if required }
  891. if source_info.endian <> target_info.endian then
  892. swap32bitarray(t32bitarray(sin));
  893. AsmWrite(#9'.byte'#9);
  894. for i:=0 to 3 do
  895. begin
  896. if i<>0 then
  897. AsmWrite(',');
  898. AsmWrite(tostr(t32bitarray(sin)[i]));
  899. end;
  900. AsmLn;
  901. end;
  902. ait_comp_64bit :
  903. begin
  904. if do_line then
  905. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_comp_64bit(hp).value));
  906. AsmWrite(#9'.byte'#9);
  907. co:=comp(tai_comp_64bit(hp).value);
  908. { swap the values to correct endian if required }
  909. if source_info.endian <> target_info.endian then
  910. swap64bitarray(t64bitarray(co));
  911. for i:=0 to 7 do
  912. begin
  913. if i<>0 then
  914. AsmWrite(',');
  915. AsmWrite(tostr(t64bitarray(co)[i]));
  916. end;
  917. AsmLn;
  918. end;
  919. ait_string :
  920. begin
  921. pos:=0;
  922. for i:=1 to tai_string(hp).len do
  923. begin
  924. if pos=0 then
  925. begin
  926. AsmWrite(#9'.ascii'#9'"');
  927. pos:=20;
  928. end;
  929. ch:=tai_string(hp).str[i-1];
  930. case ch of
  931. #0, {This can't be done by range, because a bug in FPC}
  932. #1..#31,
  933. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  934. '"' : s:='\"';
  935. '\' : s:='\\';
  936. else
  937. s:=ch;
  938. end;
  939. AsmWrite(s);
  940. inc(pos,length(s));
  941. if (pos>line_length) or (i=tai_string(hp).len) then
  942. begin
  943. AsmWriteLn('"');
  944. pos:=0;
  945. end;
  946. end;
  947. end;
  948. ait_label :
  949. begin
  950. if (tai_label(hp).labsym.is_used) then
  951. begin
  952. if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
  953. begin
  954. AsmWrite(#9'.private_extern ');
  955. AsmWriteln(tai_label(hp).labsym.name);
  956. end;
  957. if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
  958. begin
  959. AsmWrite('.globl'#9);
  960. AsmWriteLn(tai_label(hp).labsym.name);
  961. end;
  962. AsmWrite(tai_label(hp).labsym.name);
  963. AsmWriteLn(':');
  964. end;
  965. end;
  966. ait_symbol :
  967. begin
  968. if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
  969. begin
  970. AsmWrite(#9'.private_extern ');
  971. AsmWriteln(tai_symbol(hp).sym.name);
  972. end;
  973. if (target_info.system = system_powerpc64_linux) and
  974. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  975. begin
  976. AsmWriteLn('.globl _mcount');
  977. end;
  978. if tai_symbol(hp).is_global then
  979. begin
  980. AsmWrite('.globl'#9);
  981. AsmWriteLn(tai_symbol(hp).sym.name);
  982. end;
  983. if (target_info.system = system_powerpc64_linux) and
  984. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  985. begin
  986. AsmWriteLn('.section ".opd", "aw"');
  987. AsmWriteLn('.align 3');
  988. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  989. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  990. AsmWriteLn('.previous');
  991. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  992. if (tai_symbol(hp).is_global) then
  993. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  994. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  995. { the dotted name is the name of the actual function entry }
  996. AsmWrite('.');
  997. end
  998. else
  999. begin
  1000. if (target_info.system <> system_arm_linux) then
  1001. sepChar := '@'
  1002. else
  1003. sepChar := '#';
  1004. if (tf_needs_symbol_type in target_info.flags) then
  1005. begin
  1006. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  1007. if (needsObject(tai_symbol(hp))) then
  1008. AsmWriteLn(',' + sepChar + 'object')
  1009. else
  1010. AsmWriteLn(',' + sepChar + 'function');
  1011. end;
  1012. end;
  1013. if not(tai_symbol(hp).has_value) then
  1014. AsmWriteLn(tai_symbol(hp).sym.name + ':')
  1015. else
  1016. AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
  1017. end;
  1018. {$ifdef arm}
  1019. ait_thumb_func:
  1020. begin
  1021. AsmWriteLn(#9'.thumb_func');
  1022. end;
  1023. {$endif arm}
  1024. ait_symbol_end :
  1025. begin
  1026. if tf_needs_symbol_size in target_info.flags then
  1027. begin
  1028. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  1029. inc(symendcount);
  1030. AsmWriteLn(s+':');
  1031. AsmWrite(#9'.size'#9);
  1032. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1033. AsmWrite('.');
  1034. AsmWrite(tai_symbol_end(hp).sym.name);
  1035. AsmWrite(', '+s+' - ');
  1036. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1037. AsmWrite('.');
  1038. AsmWriteLn(tai_symbol_end(hp).sym.name);
  1039. end;
  1040. end;
  1041. ait_instruction :
  1042. begin
  1043. WriteInstruction(hp);
  1044. end;
  1045. ait_stab :
  1046. begin
  1047. if assigned(tai_stab(hp).str) then
  1048. begin
  1049. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1050. AsmWritePChar(tai_stab(hp).str);
  1051. AsmLn;
  1052. end;
  1053. end;
  1054. ait_force_line,
  1055. ait_function_name : ;
  1056. ait_cutobject :
  1057. begin
  1058. if SmartAsm then
  1059. begin
  1060. { only reset buffer if nothing has changed }
  1061. if AsmSize=AsmStartSize then
  1062. AsmClear
  1063. else
  1064. begin
  1065. AsmClose;
  1066. DoAssemble;
  1067. AsmCreate(tai_cutobject(hp).place);
  1068. end;
  1069. { avoid empty files }
  1070. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1071. begin
  1072. if tai(hp.next).typ=ait_section then
  1073. LastSecType:=tai_section(hp.next).sectype;
  1074. hp:=tai(hp.next);
  1075. end;
  1076. if LastSecType<>sec_none then
  1077. WriteSection(LastSecType,'',secorder_default);
  1078. AsmStartSize:=AsmSize;
  1079. end;
  1080. end;
  1081. ait_marker :
  1082. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1083. inc(InlineLevel)
  1084. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1085. dec(InlineLevel);
  1086. ait_directive :
  1087. begin
  1088. AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
  1089. if assigned(tai_directive(hp).name) then
  1090. AsmWrite(tai_directive(hp).name^);
  1091. AsmLn;
  1092. end;
  1093. else
  1094. internalerror(2006012201);
  1095. end;
  1096. hp:=tai(hp.next);
  1097. end;
  1098. end;
  1099. procedure TGNUAssembler.WriteExtraHeader;
  1100. begin
  1101. end;
  1102. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1103. begin
  1104. InstrWriter.WriteInstruction(hp);
  1105. end;
  1106. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1107. begin
  1108. AsmWriteLn(#9'.weak '+s.name);
  1109. end;
  1110. procedure TGNUAssembler.WriteAsmList;
  1111. var
  1112. n : string;
  1113. hal : tasmlisttype;
  1114. i: longint;
  1115. begin
  1116. {$ifdef EXTDEBUG}
  1117. if assigned(current_module.mainsource) then
  1118. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource^);
  1119. {$endif}
  1120. if assigned(current_module.mainsource) then
  1121. n:=ExtractFileName(current_module.mainsource^)
  1122. else
  1123. n:=InputFileName;
  1124. { gcc does not add it either for Darwin (and AIX). Grep for
  1125. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1126. }
  1127. if not(target_info.system in systems_darwin) then
  1128. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1129. WriteExtraHeader;
  1130. AsmStartSize:=AsmSize;
  1131. symendcount:=0;
  1132. for hal:=low(TasmlistType) to high(TasmlistType) do
  1133. begin
  1134. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1135. writetree(current_asmdata.asmlists[hal]);
  1136. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1137. end;
  1138. { add weak symbol markers }
  1139. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1140. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1141. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1142. if create_smartlink_sections and
  1143. (target_info.system in systems_darwin) then
  1144. AsmWriteLn(#9'.subsections_via_symbols');
  1145. { "no executable stack" marker for Linux }
  1146. if (target_info.system in systems_linux) and
  1147. not(cs_executable_stack in current_settings.moduleswitches) then
  1148. begin
  1149. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1150. end;
  1151. AsmLn;
  1152. {$ifdef EXTDEBUG}
  1153. if assigned(current_module.mainsource) then
  1154. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource^);
  1155. {$endif EXTDEBUG}
  1156. end;
  1157. {****************************************************************************}
  1158. { Apple/GNU Assembler writer }
  1159. {****************************************************************************}
  1160. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1161. begin
  1162. if (target_info.system in systems_darwin) then
  1163. case atype of
  1164. sec_bss:
  1165. { all bss (lcomm) symbols are automatically put in the right }
  1166. { place by using the lcomm assembler directive }
  1167. atype := sec_none;
  1168. sec_debug_frame,
  1169. sec_eh_frame:
  1170. begin
  1171. result := '.section __DWARF,__debug_info,regular,debug';
  1172. exit;
  1173. end;
  1174. sec_debug_line:
  1175. begin
  1176. result := '.section __DWARF,__debug_line,regular,debug';
  1177. exit;
  1178. end;
  1179. sec_debug_info:
  1180. begin
  1181. result := '.section __DWARF,__debug_info,regular,debug';
  1182. exit;
  1183. end;
  1184. sec_debug_abbrev:
  1185. begin
  1186. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1187. exit;
  1188. end;
  1189. sec_rodata:
  1190. begin
  1191. result := '.const_data';
  1192. exit;
  1193. end;
  1194. sec_rodata_norel:
  1195. begin
  1196. result := '.const';
  1197. exit;
  1198. end;
  1199. sec_fpc:
  1200. begin
  1201. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1202. exit;
  1203. end;
  1204. sec_code:
  1205. begin
  1206. if (aname='fpc_geteipasebx') or
  1207. (aname='fpc_geteipasecx') then
  1208. begin
  1209. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1210. #10'.private_extern '+aname;
  1211. exit;
  1212. end;
  1213. end;
  1214. sec_data_nonlazy:
  1215. begin
  1216. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1217. exit;
  1218. end;
  1219. sec_data_lazy:
  1220. begin
  1221. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1222. exit;
  1223. end;
  1224. sec_init_func:
  1225. begin
  1226. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1227. exit;
  1228. end;
  1229. sec_term_func:
  1230. begin
  1231. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1232. exit;
  1233. end;
  1234. sec_objc_protocol_ext:
  1235. begin
  1236. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1237. exit;
  1238. end;
  1239. sec_objc_class_ext:
  1240. begin
  1241. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1242. exit;
  1243. end;
  1244. sec_objc_property:
  1245. begin
  1246. result:='.section __OBJC, __property, regular, no_dead_strip';
  1247. exit;
  1248. end;
  1249. sec_objc_image_info:
  1250. begin
  1251. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1252. exit;
  1253. end;
  1254. sec_objc_cstring_object:
  1255. begin
  1256. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1257. exit;
  1258. end;
  1259. sec_objc_sel_fixup:
  1260. begin
  1261. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1262. exit;
  1263. end;
  1264. sec_objc_message_refs:
  1265. begin
  1266. if (target_info.system in systems_objc_nfabi) then
  1267. begin
  1268. result:='.section __DATA, __objc_selrefs, literal_pointers, no_dead_strip';
  1269. exit;
  1270. end;
  1271. end;
  1272. sec_objc_cls_refs:
  1273. begin
  1274. if (target_info.system in systems_objc_nfabi) then
  1275. begin
  1276. result:='.section __DATA, __objc_clsrefs, regular, no_dead_strip';
  1277. exit;
  1278. end;
  1279. end;
  1280. sec_objc_meth_var_names,
  1281. sec_objc_class_names:
  1282. begin
  1283. if (target_info.system in systems_objc_nfabi) then
  1284. begin
  1285. result:='.cstring';
  1286. exit
  1287. end;
  1288. end;
  1289. sec_objc_inst_meth,
  1290. sec_objc_cls_meth,
  1291. sec_objc_cat_inst_meth,
  1292. sec_objc_cat_cls_meth:
  1293. begin
  1294. if (target_info.system in systems_objc_nfabi) then
  1295. begin
  1296. result:='.section __DATA, __objc_const';
  1297. exit;
  1298. end;
  1299. end;
  1300. sec_objc_meta_class,
  1301. sec_objc_class:
  1302. begin
  1303. if (target_info.system in systems_objc_nfabi) then
  1304. begin
  1305. result:='.section __DATA, __objc_data';
  1306. exit;
  1307. end;
  1308. end;
  1309. sec_objc_sup_refs:
  1310. begin
  1311. result:='.section __DATA, __objc_superrefs, regular, no_dead_strip';
  1312. exit
  1313. end;
  1314. sec_objc_classlist:
  1315. begin
  1316. result:='.section __DATA, __objc_classlist, regular, no_dead_strip';
  1317. exit
  1318. end;
  1319. sec_objc_nlclasslist:
  1320. begin
  1321. result:='.section __DATA, __objc_nlclasslist, regular, no_dead_strip';
  1322. exit
  1323. end;
  1324. sec_objc_catlist:
  1325. begin
  1326. result:='.section __DATA, __objc_catlist, regular, no_dead_strip';
  1327. exit
  1328. end;
  1329. sec_objc_nlcatlist:
  1330. begin
  1331. result:='.section __DATA, __objc_nlcatlist, regular, no_dead_strip';
  1332. exit
  1333. end;
  1334. sec_objc_protolist:
  1335. begin
  1336. result:='.section __DATA, __objc_protolist, coalesced, no_dead_strip';
  1337. exit;
  1338. end;
  1339. end;
  1340. result := inherited sectionname(atype,aname,aorder);
  1341. end;
  1342. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1343. begin
  1344. AsmWriteLn(#9'.weak_reference '+s.name);
  1345. end;
  1346. {****************************************************************************}
  1347. { a.out/GNU Assembler writer }
  1348. {****************************************************************************}
  1349. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1350. const
  1351. (* Translation table - replace unsupported section types with basic ones. *)
  1352. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1353. sec_none,
  1354. sec_code,
  1355. sec_data,
  1356. sec_data (* sec_rodata *),
  1357. sec_data (* sec_rodata_norel *),
  1358. sec_bss,
  1359. sec_data (* sec_threadvar *),
  1360. { used for wince exception handling }
  1361. sec_code (* sec_pdata *),
  1362. { used for darwin import stubs }
  1363. sec_code (* sec_stub *),
  1364. sec_data,(* sec_data_nonlazy *)
  1365. sec_data,(* sec_data_lazy *)
  1366. sec_data,(* sec_init_func *)
  1367. sec_data,(* sec_term_func *)
  1368. { stabs }
  1369. sec_stab,sec_stabstr,
  1370. { win32 }
  1371. sec_data (* sec_idata2 *),
  1372. sec_data (* sec_idata4 *),
  1373. sec_data (* sec_idata5 *),
  1374. sec_data (* sec_idata6 *),
  1375. sec_data (* sec_idata7 *),
  1376. sec_data (* sec_edata *),
  1377. { C++ exception handling unwinding (uses dwarf) }
  1378. sec_eh_frame,
  1379. { dwarf }
  1380. sec_debug_frame,
  1381. sec_debug_info,
  1382. sec_debug_line,
  1383. sec_debug_abbrev,
  1384. { ELF resources (+ references to stabs debug information sections) }
  1385. sec_code (* sec_fpc *),
  1386. { Table of contents section }
  1387. sec_code (* sec_toc *),
  1388. sec_code (* sec_init *),
  1389. sec_code (* sec_fini *),
  1390. sec_none (* sec_objc_class *),
  1391. sec_none (* sec_objc_meta_class *),
  1392. sec_none (* sec_objc_cat_cls_meth *),
  1393. sec_none (* sec_objc_cat_inst_meth *),
  1394. sec_none (* sec_objc_protocol *),
  1395. sec_none (* sec_objc_string_object *),
  1396. sec_none (* sec_objc_cls_meth *),
  1397. sec_none (* sec_objc_inst_meth *),
  1398. sec_none (* sec_objc_cls_refs *),
  1399. sec_none (* sec_objc_message_refs *),
  1400. sec_none (* sec_objc_symbols *),
  1401. sec_none (* sec_objc_category *),
  1402. sec_none (* sec_objc_class_vars *),
  1403. sec_none (* sec_objc_instance_vars *),
  1404. sec_none (* sec_objc_module_info *),
  1405. sec_none (* sec_objc_class_names *),
  1406. sec_none (* sec_objc_meth_var_types *),
  1407. sec_none (* sec_objc_meth_var_names *),
  1408. sec_none (* sec_objc_selector_strs *),
  1409. sec_none (* sec_objc_protocol_ext *),
  1410. sec_none (* sec_objc_class_ext *),
  1411. sec_none (* sec_objc_property *),
  1412. sec_none (* sec_objc_image_info *),
  1413. sec_none (* sec_objc_cstring_object *),
  1414. sec_none (* sec_objc_sel_fixup *),
  1415. sec_none (* sec_objc_data *),
  1416. sec_none (* sec_objc_const *),
  1417. sec_none (* sec_objc_sup_refs *),
  1418. sec_none (* sec_data_coalesced *),
  1419. sec_none (* sec_objc_classlist *),
  1420. sec_none (* sec_objc_nlclasslist *),
  1421. sec_none (* sec_objc_catlist *),
  1422. sec_none (* sec_objc_nlcatlist *),
  1423. sec_none (* sec_objc_protlist *)
  1424. );
  1425. begin
  1426. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1427. end;
  1428. {****************************************************************************}
  1429. { Abstract Instruction Writer }
  1430. {****************************************************************************}
  1431. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1432. begin
  1433. inherited create;
  1434. owner := _owner;
  1435. end;
  1436. end.